From 18ade8812aecb52eb10b8d9d3d849ea0e6e7e674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Tue, 20 Feb 2018 16:23:26 +0100 Subject: [PATCH 01/99] Add positioning support for DL --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 84 ++++++++----- openair2/LAYER2/MAC/mac_proto.h | 2 +- openair2/LAYER2/MAC/pre_processor.c | 146 +++++++++++++--------- 3 files changed, 143 insertions(+), 89 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index da52a8fedc..f283140403 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -80,6 +80,10 @@ float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float total_slice_percentage = 0; float total_slice_percentage_current = 0; +// Frequency ranges for slice positioning +int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; +int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; + // MAX MCS for each slice for past and current time int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; @@ -445,9 +449,7 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, //------------------------------------------------------------------------------ void -schedule_dlsch(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) -//------------------------------------------------------------------------------{ +schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) { int i = 0; @@ -462,7 +464,7 @@ schedule_dlsch(module_id_t module_idP, for (i = 0; i < n_active_slices; i++) { if (slice_percentage[i] < 0 ){ LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, slice_percentage[i]); + module_idP, frameP, subframeP, i, slice_percentage[i]); slice_percentage[i]=0; } total_slice_percentage+=slice_percentage[i]; @@ -482,37 +484,38 @@ schedule_dlsch(module_id_t module_idP, // check if the number of slices has changed, and log if (n_active_slices_current != n_active_slices ){ - if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { - LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); - - n_active_slices_current = n_active_slices; - - } else { - LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; - } + if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + LOG_I(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", + module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); + n_active_slices_current = n_active_slices; + } else { + LOG_W(MAC, "invalid number of DL slices %d, revert to the previous value %d\n", + n_active_slices, n_active_slices_current); + n_active_slices = n_active_slices_current; + } } // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); - total_slice_percentage_current= total_slice_percentage; - slice_percentage_current[i] = slice_percentage[i]; - + if (slice_percentage_current[i] != slice_percentage[i]) { // new slice percentage + LOG_I(MAC, + "[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, + slice_percentage_current[i], slice_percentage[i]); + total_slice_percentage_current = total_slice_percentage; + slice_percentage_current[i] = slice_percentage[i]; } // check if the slice max MCS, and log the console - if (slice_maxmcs_current[i] != slice_maxmcs[i]){ - if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); - slice_maxmcs_current[i] = slice_maxmcs[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",module_idP, i, slice_maxmcs[i],slice_maxmcs_current[i]); - slice_maxmcs[i]= slice_maxmcs_current[i]; - } + if (slice_maxmcs_current[i] != slice_maxmcs[i]) { + if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)) { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); + slice_maxmcs_current[i] = slice_maxmcs[i]; + } else { + LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n", + module_idP, i, slice_maxmcs[i], slice_maxmcs_current[i]); + slice_maxmcs[i] = slice_maxmcs_current[i]; + } } // check if a new scheduler, and log the console @@ -541,6 +544,29 @@ schedule_dlsch(module_id_t module_idP, } } + // Check for new slice positions + if (slice_position[i*2] > slice_position[i*2 + 1] || + slice_position[i*2] < 0 || + slice_position[i*2 + 1] > N_RBG_MAX) { + LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n", + module_idP, i, + slice_position[i*2], slice_position[i*2 + 1], + slice_position_current[i*2], slice_position_current[i*2 + 1]); + slice_position[i*2] = slice_position_current[i*2]; + slice_position[i*2 + 1] = slice_position_current[i*2 + 1]; + } else { + if (slice_position_current[i*2] != slice_position[i*2]) { + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", + module_idP, i, frameP, subframeP, slice_position_current[i*2], slice_position[i*2]); + slice_position_current[i*2] = slice_position[i*2]; + } + if (slice_position_current[i*2 + 1] != slice_position[i*2 + 1]) { + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", + module_idP, i, frameP, subframeP, slice_position_current[i*2 + 1], slice_position[i*2 + 1]); + slice_position_current[i*2 + 1] = slice_position[i*2 + 1]; + } + } + // Check for new sorting policy if (sorting_policy_current[i] != sorting_policy[i]) { LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index aba8c26d92..ab3b535f22 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -242,10 +242,10 @@ void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int N_RBG, int transmission_mode, int min_rb_unit, - uint8_t N_RB_DL, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 16cbd3fc19..c212418431 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -56,6 +56,7 @@ extern RAN_CONTEXT_t RC; extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES]; +extern int slice_position[MAX_NUM_SLICES*2]; extern uint32_t sorting_policy[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES]; @@ -451,6 +452,28 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { } } +void decode_slice_positioning(module_id_t Mod_idP, + slice_id_t slice_id, + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) { + uint8_t CC_id; + int RBG, start_frequency, end_frequency; + + // Init slice_alloc_mask + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (RBG = 0; RBG < N_RBG_MAX; ++RBG) { + slice_allocation_mask[CC_id][RBG] = 0; + } + } + + start_frequency = slice_position[slice_id*2]; + end_frequency = slice_position[slice_id*2 + 1]; + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { + slice_allocation_mask[CC_id][RBG] = 1; + } + } +} + // This fuction sorts the UE in order their dlsch buffer and CQI void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP) @@ -497,6 +520,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int N_RBG[NFAPI_CC_MAX], int min_rb_unit[NFAPI_CC_MAX], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { @@ -624,11 +648,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // control channel or retransmission /* TODO: do we have to check for retransmission? */ if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) { - nb_rbs_required_remaining_1[CC_id][UE_id] = - nb_rbs_required[CC_id][UE_id]; + nb_rbs_required_remaining_1[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; } else { - nb_rbs_required_remaining_1[CC_id][UE_id] = - cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + nb_rbs_required_remaining_1[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); } } } @@ -694,18 +716,17 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // retransmission in data channels // control channel in the 1st transmission // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, + LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, + UE_id, CC_id, N_RBG[CC_id], transmission_mode, - min_rb_unit - [CC_id], - to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth), + min_rb_unit[CC_id], nb_rbs_required, nb_rbs_required_remaining, rballoc_sub, + slice_allocation_mask, MIMO_mode_indicator); #ifdef TM5 @@ -890,6 +911,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, uint16_t i, j; uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting int min_rb_unit[NFAPI_CC_MAX]; @@ -947,7 +969,11 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // Sorts the user on the basis of dlsch logical channel buffer and CQI sort_UEs(Mod_id, slice_id, frameP, subframeP); - // This function does the main allocation of the number of RBs + // TODO: When accounting() is revised, this will be moved inside positioning() + decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); + + // ACCOUNTING + // This function does the main allocation of the *number* of RBs dlsch_scheduler_pre_processor_accounting(Mod_id, slice_id, frameP, @@ -955,6 +981,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, N_RBG, min_rb_unit, rballoc_sub, + slice_allocation_mask, MIMO_mode_indicator, nb_rbs_required); @@ -1220,65 +1247,66 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int N_RBG, int transmission_mode, int min_rb_unit, - uint8_t N_RB_DL, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { - int i; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + int i; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - for (i = 0; i < N_RBG; i++) { + for (i = 0; i < N_RBG; i++) { - if ((rballoc_sub[CC_id][i] == 0) && - (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && - (nb_rbs_required_remaining[CC_id][UE_id] > 0) && - (ue_sched_ctl->pre_nb_available_rbs[CC_id] < - nb_rbs_required[CC_id][UE_id])) { + if (rballoc_sub[CC_id][i] != 0) + continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0) + continue; + if (nb_rbs_required_remaining[CC_id][UE_id] <= 0) + continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) + continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) + continue; + if (slice_allocation_mask[CC_id][i] == 0) + continue; - // if this UE is not scheduled for TM5 - if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { +// if ((rballoc_sub[CC_id][i] == 0) && +// (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && +// (nb_rbs_required_remaining[CC_id][UE_id] > 0) && +// (ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) { +// // if this UE is not scheduled for TM5 +// if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { - if ((i == N_RBG - 1) - && ((N_RB_DL == 25) || (N_RB_DL == 50))) { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit - 1) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit + 1; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit - 1; - } - } else { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit; - } - } - } // dl_pow_off[CC_id][UE_id] ! = 0 - } + if ((i == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { + if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit - 1) { + rballoc_sub[CC_id][i] = 1; + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; + MIMO_mode_indicator[CC_id][i] = 1; + if (transmission_mode == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit + 1; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; + } + } else { + if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit) { + rballoc_sub[CC_id][i] = 1; + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; + MIMO_mode_indicator[CC_id][i] = 1; + if (transmission_mode == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; + } } +// } // dl_pow_off[CC_id][UE_id] ! = 0 +// } + } } From 490e24560af77bd143d18d894f8ea9e228fa5687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Wed, 21 Feb 2018 16:14:17 +0100 Subject: [PATCH 02/99] Split accounting and positioning in pre_processor --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 1 - openair2/LAYER2/MAC/mac_proto.h | 50 +- openair2/LAYER2/MAC/pre_processor.c | 531 ++++++++++++---------- 3 files changed, 316 insertions(+), 266 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index f283140403..d090d9a05b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -700,7 +700,6 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, slice_idP, frameP, subframeP, - N_RBG, mbsfn_flag); stop_meas(&eNB->schedule_dlsch_preprocessor); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index ab3b535f22..1086d8eef7 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -204,20 +204,6 @@ void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, void clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, frame_t frameP, sub_frame_t subframeP); -void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t - nb_rbs_required[NFAPI_CC_MAX] - [MAX_MOBILES_PER_ENB], - unsigned char - rballoc_sub[NFAPI_CC_MAX] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[NFAPI_CC_MAX] - [N_RBG_MAX]); // eNB functions /* \brief This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done @@ -229,12 +215,38 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, void dlsch_scheduler_pre_processor(module_id_t module_idP, - slice_id_t slice_idP, - frame_t frameP, - sub_frame_t subframe, - int N_RBG[NFAPI_CC_MAX], - int *mbsfn_flag); + slice_id_t slice_idP, + frame_t frameP, + sub_frame_t subframe, + int *mbsfn_flag); +void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], + int *mbsfn_flag); + +void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int min_rb_unit[NFAPI_CC_MAX], + uint8_t total_ue_count[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]); + +void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, + slice_id_t slice_id, + int min_rb_unit[NFAPI_CC_MAX], + uint8_t total_ue_count[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int UE_id, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index c212418431..b299ad33ea 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -191,12 +191,11 @@ store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, // This function returns the estimated number of RBs required by each UE for downlink scheduling void assign_rbs_required(module_id_t Mod_id, - slice_id_t slice_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t - nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - int min_rb_unit[NFAPI_CC_MAX]) + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframe, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { uint16_t TBS = 0; @@ -517,37 +516,29 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP, - int N_RBG[NFAPI_CC_MAX], int min_rb_unit[NFAPI_CC_MAX], - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { - - + uint8_t total_ue_count[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) +{ int UE_id, CC_id; - int ii, r1; + int i; rnti_t rnti; uint8_t harq_pid, round, transmission_mode; uint8_t total_rbs_used[NFAPI_CC_MAX]; - uint8_t total_ue_count[NFAPI_CC_MAX]; uint16_t average_rbs_per_user[NFAPI_CC_MAX]; - uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; int N_RB_DL; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; + // Reset for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { total_ue_count[CC_id] = 0; total_rbs_used[CC_id] = 0; average_rbs_per_user[CC_id] = 0; - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - nb_rbs_required_remaining[CC_id][UE_id] = 0; - } } // loop over all active UEs @@ -559,8 +550,8 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (!ue_slice_membership(UE_id, slice_id)) continue; - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; // TODO Can we use subframe2harqpid() here? @@ -595,8 +586,8 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (!ue_slice_membership(UE_id, slice_id)) continue; - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; // hypothetical assignment /* @@ -638,8 +629,8 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (!ue_slice_membership(UE_id, slice_id)) continue; - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); @@ -654,15 +645,40 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, } } } +} + +void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, + slice_id_t slice_id, + int min_rb_unit[NFAPI_CC_MAX], + uint8_t total_ue_count[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { + + int UE_id, CC_id; + int i; + uint8_t transmission_mode; + + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + int N_RBG[NFAPI_CC_MAX]; + + rnti_t rnti; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + + decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); //Allocation to UEs is done in 2 rounds, // 1st stage: average number of RBs allocated to each UE // 2nd stage: remaining RBs are allocated to high priority UEs - for (r1 = 0; r1 < 2; r1++) { + for (int r1 = 0; r1 < 2; r1++) { for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + N_RBG[i] = to_rbg(cc->mib->message.dl_Bandwidth); if (r1 == 0) { nb_rbs_required_remaining[CC_id][UE_id] = @@ -692,9 +708,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + CC_id = UE_list->ordered_CCids[i][UE_id]; // if there are UEs with traffic if (total_ue_count[CC_id] > 0) { // ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; @@ -749,10 +765,10 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, && (nb_rbs_required_remaining[CC_id][UE_id] > 0)) { - for (ii = UE_list->next[UE_id + 1]; ii >= 0; - ii = UE_list->next[ii]) { + for (i = UE_list->next[UE_id + 1]; i >= 0; + i = UE_list->next[i]) { - UE_id2 = ii; + UE_id2 = i; rnti2 = UE_RNTI(Mod_id, UE_id2); ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2]; @@ -903,19 +919,19 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP, - int N_RBG[NFAPI_CC_MAX], - int *mbsfn_flag) { - + int *mbsfn_flag) +{ int UE_id; uint8_t CC_id; uint16_t i, j; uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t total_ue_count[NFAPI_CC_MAX]; uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting int min_rb_unit[NFAPI_CC_MAX]; uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -932,59 +948,41 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; #endif - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { - - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; - - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - if (UE_list->active[UE_id] != TRUE) - continue; - - if (!ue_slice_membership(UE_id, slice_id)) - continue; - - // Initialize scheduling information for all active UEs - dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, - frameP, - subframeP, - N_RBG[CC_id], - nb_rbs_required, - rballoc_sub, - MIMO_mode_indicator); - - } - } + // Initialize scheduling information for all active UEs + dlsch_scheduler_pre_processor_reset(Mod_id, slice_id, frameP, subframeP, + min_rb_unit, + nb_rbs_required, + rballoc_sub, + MIMO_mode_indicator, + mbsfn_flag); // TODO Not sure if useful // Store the DLSCH buffer for each logical channel store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, min_rb_unit); + assign_rbs_required(Mod_id, slice_id, frameP, subframeP, + min_rb_unit, + nb_rbs_required); // Sorts the user on the basis of dlsch logical channel buffer and CQI sort_UEs(Mod_id, slice_id, frameP, subframeP); - // TODO: When accounting() is revised, this will be moved inside positioning() - decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); - // ACCOUNTING - // This function does the main allocation of the *number* of RBs - dlsch_scheduler_pre_processor_accounting(Mod_id, - slice_id, - frameP, - subframeP, - N_RBG, + // This procedure decides the number of RBs to allocate + dlsch_scheduler_pre_processor_accounting(Mod_id, slice_id, frameP, subframeP, min_rb_unit, - rballoc_sub, - slice_allocation_mask, - MIMO_mode_indicator, - nb_rbs_required); - + total_ue_count, + nb_rbs_required, + nb_rbs_accounted); + // POSITIONING + // This procedure does the main allocation of the RBs + dlsch_scheduler_pre_processor_positioning(Mod_id, slice_id, + min_rb_unit, + total_ue_count, + nb_rbs_required, + nb_rbs_accounted, + rballoc_sub, + MIMO_mode_indicator); #ifdef TM5 // This has to be revisited!!!! @@ -1034,13 +1032,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", UE_id); LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, ue_sched_ctl->dl_pow_off[CC_id]); LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", UE_id); - for (j = 0; j < N_RBG[CC_id]; j++) { + for (j = 0; j < N_RBG; j++) { //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id]; LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", UE_id, j, ue_sched_ctl->rballoc_sub_UE[CC_id][j]); } @@ -1056,186 +1056,225 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, #define SF0_LIMIT 1 void -dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[NFAPI_CC_MAX] - [MAX_MOBILES_PER_ENB], - unsigned char - rballoc_sub[NFAPI_CC_MAX] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[NFAPI_CC_MAX] - [N_RBG_MAX]) +dlsch_scheduler_pre_processor_reset(module_id_t module_idP, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], + int *mbsfn_flag) { + + int UE_id; + uint8_t CC_id; int i, j; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; - int N_RB_DL = - to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); - int RBGsize = N_RB_DL / N_RBG, RBGsize_last; -#ifdef SF0_LIMIT - int sf0_upper = -1, sf0_lower = -1; -#endif - - - LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id,(int)(UE_RNTI(module_idP, UE_id))); - // initialize harq_pid and round - - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; - - /* - eNB_UE_stats *eNB_UE_stats; - - if (eNB_UE_stats == NULL) - return; - - - mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti, - frameP,subframeP, - &ue_sched_ctl->harq_pid[CC_id], - &ue_sched_ctl->round[CC_id], - openair_harq_DL); - - if (ue_sched_ctl->ta_timer == 0) { - - // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... - - ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY - switch (N_RB_DL) { - case 6: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update; - break; - - case 15: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2; - break; - - case 25: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4; - break; - - case 50: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8; - break; - - case 75: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12; - break; - - case 100: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16; - break; - } - // clear the update in case PHY does not have a new measurement after timer expiry - eNB_UE_stats->timing_advance_update = 0; - } - else { - ue_sched_ctl->ta_timer--; - ue_sched_ctl->ta_update =0; // don't trigger a timing advance command - } - - - if (UE_id==0) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update); - } - */ - - nb_rbs_required[CC_id][UE_id] = 0; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; - ue_sched_ctl->dl_pow_off[CC_id] = 2; - - switch (N_RB_DL) { - case 6: - RBGsize = 1; - RBGsize_last = 1; - break; - case 15: - RBGsize = 2; - RBGsize_last = 1; - break; - case 25: - RBGsize = 2; - RBGsize_last = 1; - break; - case 50: - RBGsize = 3; - RBGsize_last = 2; - break; - case 75: - RBGsize = 4; - RBGsize_last = 3; - break; - case 100: - RBGsize = 4; - RBGsize_last = 4; - break; - default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + int N_RB_DL, RBGsize, RBGsize_last; + int N_RBG[NFAPI_CC_MAX]; #ifdef SF0_LIMIT - switch (N_RBG) { - case 6: - sf0_lower = 0; - sf0_upper = 5; - break; - case 8: - sf0_lower = 2; - sf0_upper = 5; - break; - case 13: - sf0_lower = 4; - sf0_upper = 7; - break; - case 17: - sf0_lower = 7; - sf0_upper = 9; - break; - case 25: - sf0_lower = 11; - sf0_upper = 13; - break; - default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + int sf0_lower, sf0_upper; #endif - // Initialize Subbands according to VRB map - for (i = 0; i < N_RBG; i++) { - int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; + rnti_t rnti; + UE_list_t *UE_list; + UE_sched_ctrl *ue_sched_ctl; + uint8_t *vrb_map; + COMMON_channels_t *cc; +// + for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; + LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id,(int)(UE_RNTI(module_idP, UE_id))); + // initialize harq_pid and round + cc = &RC.mac[module_idP]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + + if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here + continue; + + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { + + + UE_list = &RC.mac[module_idP]->UE_list; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti = UE_RNTI(module_idP, UE_id); + + + if (rnti == NOT_A_RNTI) + continue; + + if (UE_list->active[UE_id] != TRUE) + continue; + + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; + N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); #ifdef SF0_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) - /* TODO: make it proper - allocate those RBs, do not "protect" them, but - * compute number of available REs and limit MCS according to the - * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) - */ - if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) - rballoc_sub[CC_id][i] = 1; + sf0_lower = -1; + sf0_upper = -1; #endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < rb_size; j++) { - if (vrb_map[j + (i * RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", - frameP, subframeP, j + (i * RBGsize)); - break; + LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); + // initialize harq_pid and round + if (ue_sched_ctl->ta_timer) + ue_sched_ctl->ta_timer--; + + + /* + eNB_UE_stats *eNB_UE_stats; + + if (eNB_UE_stats == NULL) + return; + + + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti, + frameP,subframeP, + &ue_sched_ctl->harq_pid[CC_id], + &ue_sched_ctl->round[CC_id], + openair_harq_DL); + + + if (ue_sched_ctl->ta_timer == 0) { + + // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... + + ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY + switch (N_RB_DL) { + case 6: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update; + break; + + case 15: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2; + break; + + case 25: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4; + break; + + case 50: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8; + break; + + case 75: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12; + break; + + case 100: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16; + break; + } + // clear the update in case PHY does not have a new measurement after timer expiry + eNB_UE_stats->timing_advance_update = 0; + } + else { + ue_sched_ctl->ta_timer--; + ue_sched_ctl->ta_update =0; // don't trigger a timing advance command + } + + + if (UE_id==0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update); + } + */ + + nb_rbs_required[CC_id][UE_id] = 0; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; + ue_sched_ctl->dl_pow_off[CC_id] = 2; + + switch (N_RB_DL) { + case 6: + RBGsize = 1; + RBGsize_last = 1; + break; + case 15: + RBGsize = 2; + RBGsize_last = 1; + break; + case 25: + RBGsize = 2; + RBGsize_last = 1; + break; + case 50: + RBGsize = 3; + RBGsize_last = 2; + break; + case 75: + RBGsize = 4; + RBGsize_last = 3; + break; + case 100: + RBGsize = 4; + RBGsize_last = 4; + break; + default: + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } + +#ifdef SF0_LIMIT + switch (N_RBG[CC_id]) { + case 6: + sf0_lower = 0; + sf0_upper = 5; + break; + case 8: + sf0_lower = 2; + sf0_upper = 5; + break; + case 13: + sf0_lower = 4; + sf0_upper = 7; + break; + case 17: + sf0_lower = 7; + sf0_upper = 9; + break; + case 25: + sf0_lower = 11; + sf0_upper = 13; + break; + default: + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } +#endif + + // Initialize Subbands according to VRB map + for (i = 0; i < N_RBG[CC_id]; i++) { + int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize; + + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; + rballoc_sub[CC_id][i] = 0; + +#ifdef SF0_LIMIT + // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) + /* TODO: make it proper - allocate those RBs, do not "protect" them, but + * compute number of available REs and limit MCS according to the + * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) + */ + if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) + rballoc_sub[CC_id][i] = 1; +#endif + + // for SI-RNTI,RA-RNTI and P-RNTI allocations + for (j = 0; j < rb_size; j++) { + if (vrb_map[j + (i*RBGsize)] != 0) { + rballoc_sub[CC_id][i] = 1; + LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", frameP, subframeP, j + (i*RBGsize)); + break; + } + } + LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", + frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + MIMO_mode_indicator[CC_id][i] = 2; } } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; } } From 53c617cdcfb1fd375036be79e1298b9ea477e4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Fri, 23 Feb 2018 17:14:44 +0100 Subject: [PATCH 03/99] Move slicing configuration variables in header files --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 39 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 77 +++ .../LAYER2/MAC/eNB_scheduler_primitives.c | 2 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 33 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.h | 71 +++ openair2/LAYER2/MAC/mac_proto.h | 11 +- openair2/LAYER2/MAC/pre_processor.c | 509 ++++++++++-------- 7 files changed, 435 insertions(+), 307 deletions(-) create mode 100644 openair2/LAYER2/MAC/eNB_scheduler_dlsch.h create mode 100644 openair2/LAYER2/MAC/eNB_scheduler_ulsch.h diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index d090d9a05b..e6989d676c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -44,6 +44,7 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" +#include "eNB_scheduler_dlsch.h" #include "pdcp.h" #include "SIMULATION/TOOLS/sim.h" // for taus @@ -68,44 +69,6 @@ extern RAN_CONTEXT_t RC; extern uint8_t nfapi_mode; - -// number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; - -// RB share for each slice for past and current time -float avg_slice_percentage=0.25; -float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage = 0; -float total_slice_percentage_current = 0; - -// Frequency ranges for slice positioning -int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; -int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; - -// MAX MCS for each slice for past and current time -int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; -int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; - -int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; -int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; - -// name of available scheduler -char *dl_scheduler_type[MAX_NUM_SLICES] = - { "schedule_ue_spec", - "schedule_ue_spec", - "schedule_ue_spec", - "schedule_ue_spec" - }; - -// The lists of criteria that enforce the sorting policies of the slices -uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; -uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; - -// pointer to the slice specific scheduler -slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; - //------------------------------------------------------------------------------ void add_ue_dlsch_info(module_id_t module_idP, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h new file mode 100644 index 0000000000..29ce735b05 --- /dev/null +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -0,0 +1,77 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file LAYER2/MAC/eNB_scheduler_dlsch.h +* \brief DLSCH Scheduler policy variables used during different phases of scheduling +* \author Navid Nikaein and Niccolo' Iardella +* \date 2018 +* \version 0.2 +* \email navid.nikaein@eurecom.fr + +*/ +/** @defgroup _oai2 openair2 Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +/*@}*/ + +#ifndef __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ +#define __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ + +// number of active slices for past and current time +int n_active_slices = 1; +int n_active_slices_current = 1; + +// RB share for each slice for past and current time +float avg_slice_percentage=0.25; +float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float total_slice_percentage = 0; +float total_slice_percentage_current = 0; + +// Frequency ranges for slice positioning +int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; +int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; + +// MAX MCS for each slice for past and current time +int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; +int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; + +int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; +int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; + +// name of available scheduler +char *dl_scheduler_type[MAX_NUM_SLICES] = + { "schedule_ue_spec", + "schedule_ue_spec", + "schedule_ue_spec", + "schedule_ue_spec" + }; + +// The lists of criteria that enforce the sorting policies of the slices +uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; +uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; + +// pointer to the slice specific scheduler +slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; + +#endif //__LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index b85335caab..5328920af3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -4536,7 +4536,7 @@ harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, // Flexran Slicing functions -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) +uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs) { return (uint16_t) floor(rb_percentage * total_rbs); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index f48cf50bce..7c06a52909 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -48,6 +48,7 @@ #include "assertions.h" //#include "LAYER2/MAC/pre_processor.c" +#include "eNB_scheduler_ulsch.h" #include "pdcp.h" #if defined(ENABLE_ITTI) @@ -72,46 +73,14 @@ extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offs extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); extern uint8_t nfapi_mode; -extern uint8_t nfapi_mode; - // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[34] = { 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, 64, 72, 75, 80, 81, 90, 96, 100 }; -/* number of active slices for past and current time*/ -int n_active_slices_uplink = 1; -int n_active_slices_current_uplink = 1; - -/* RB share for each slice for past and current time*/ -float avg_slice_percentage_uplink=0.25; -float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage_uplink = 0; -float total_slice_percentage_current_uplink = 0; - -// MAX MCS for each slice for past and current time -int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20}; -int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20}; - -/*resource blocks allowed*/ -uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; -/*Slice Update */ -int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; -int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; - -/* name of available scheduler*/ -char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti", - "schedule_ulsch_rnti", - "schedule_ulsch_rnti", - "schedule_ulsch_rnti" -}; extern mui_t rrc_eNB_mui; -/* Slice Function Pointer */ -slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; - void rx_sdu(const module_id_t enb_mod_idP, const int CC_idP, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h new file mode 100644 index 0000000000..45d7a4e709 --- /dev/null +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h @@ -0,0 +1,71 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file LAYER2/MAC/eNB_scheduler_ulsch.h +* \brief ULSCH Scheduler policy variables used during different phases of scheduling +* \author Navid Nikaein and Niccolo' Iardella +* \date 2018 +* \version 0.2 +* \email navid.nikaein@eurecom.fr + +*/ +/** @defgroup _oai2 openair2 Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +/*@}*/ + +#ifndef __LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__ +#define __LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__ + +/* number of active slices for past and current time*/ +int n_active_slices_uplink = 1; +int n_active_slices_current_uplink = 1; + +/* RB share for each slice for past and current time*/ +float avg_slice_percentage_uplink=0.25; +float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float total_slice_percentage_uplink = 0; +float total_slice_percentage_current_uplink = 0; + +// MAX MCS for each slice for past and current time +int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20}; +int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20}; + +/*resource blocks allowed*/ +uint16_t nb_rbs_allowed_slice_uplink[NFAPI_CC_MAX][MAX_NUM_SLICES]; +/*Slice Update */ +int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; +int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; + +/* name of available scheduler*/ +char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti", + "schedule_ulsch_rnti", + "schedule_ulsch_rnti", + "schedule_ulsch_rnti" +}; + +/* Slice Function Pointer */ +slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; + +#endif //__LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 1086d8eef7..85f6489e22 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -237,14 +237,14 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int min_rb_unit[NFAPI_CC_MAX], uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]); + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]); void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, slice_id_t slice_id, int min_rb_unit[NFAPI_CC_MAX], uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); @@ -252,10 +252,10 @@ void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int UE_id, uint8_t CC_id, int N_RBG, - int transmission_mode, + int tm, int min_rb_unit, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); @@ -1256,8 +1256,7 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, #endif /*Slice related functions */ -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); - +uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); int ue_slice_membership(int UE_id, int slice_id); /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index b299ad33ea..ed91254c6a 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -271,7 +271,8 @@ assign_rbs_required(module_id_t Mod_id, to_prb(RC.mac[Mod_id]->common_channels[CC_id]. mib->message.dl_Bandwidth); - UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); + UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] = + nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); /* calculating required number of RBs for each UE */ while (TBS < @@ -477,39 +478,108 @@ void decode_slice_positioning(module_id_t Mod_idP, // This fuction sorts the UE in order their dlsch buffer and CQI void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP) { - int i; - int list[MAX_MOBILES_PER_ENB]; - int list_size = 0; - int rnti; - struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP, slice_id }; + int i; + int list[MAX_MOBILES_PER_ENB]; + int list_size = 0; + struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_id}; + + UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + + if (UE_list->active[i] == FALSE) continue; + if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(i, slice_id)) continue; + + list[list_size] = i; + list_size++; + } + + decode_sorting_policy(Mod_idP, slice_id); + + qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); + + if (list_size) { + for (i = 0; i < list_size - 1; ++i) + UE_list->next[list[i]] = list[i + 1]; + UE_list->next[list[list_size - 1]] = -1; + UE_list->head = list[0]; + } else { + UE_list->head = -1; + } + +#if 0 + + + int UE_id1, UE_id2; + int pCC_id1, pCC_id2; + int cqi1, cqi2, round1, round2; + int i = 0, ii = 0; //,j=0; + rnti_t rnti1, rnti2; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - if (UE_list->active[i] == FALSE) - continue; - if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) - continue; - if (!ue_slice_membership(i, slice_id)) - continue; + for (ii = UE_list->next[i]; ii >= 0; ii = UE_list->next[ii]) { - list[list_size] = i; - list_size++; - } + UE_id1 = i; + rnti1 = UE_RNTI(Mod_idP, UE_id1); + if (rnti1 == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1) + continue; + pCC_id1 = UE_PCCID(Mod_idP, UE_id1); + cqi1 = maxcqi(Mod_idP, UE_id1); // + round1 = maxround(Mod_idP, rnti1, frameP, subframeP, 0); - decode_sorting_policy(Mod_idP, slice_id); + UE_id2 = ii; + rnti2 = UE_RNTI(Mod_idP, UE_id2); + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1) + continue; + cqi2 = maxcqi(Mod_idP, UE_id2); + round2 = maxround(Mod_idP, rnti2, frameP, subframeP, 0); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0); + pCC_id2 = UE_PCCID(Mod_idP, UE_id2); - qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); + if (round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order + swap_UEs(UE_list, UE_id1, UE_id2, 0); + } else if (round2 == round1) { + // RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service. + // for(j=0;jnext[list[i]] = list[i + 1]; - UE_list->next[list[list_size - 1]] = -1; - UE_list->head = list[0]; - } else { - UE_list->head = -1; + // first check the buffer status for SRB1 and SRB2 + + if ((UE_list->UE_template[pCC_id1][UE_id1]. + dl_buffer_info[1] + + UE_list->UE_template[pCC_id1][UE_id1]. + dl_buffer_info[2]) < + (UE_list->UE_template[pCC_id2][UE_id2]. + dl_buffer_info[1] + + UE_list->UE_template[pCC_id2][UE_id2]. + dl_buffer_info[2])) { + swap_UEs(UE_list, UE_id1, UE_id2, 0); + } else if (UE_list->UE_template[pCC_id1] + [UE_id1].dl_buffer_head_sdu_creation_time_max < + UE_list->UE_template[pCC_id2] + [UE_id2].dl_buffer_head_sdu_creation_time_max) { + swap_UEs(UE_list, UE_id1, UE_id2, 0); + } else if (UE_list->UE_template[pCC_id1][UE_id1]. + dl_buffer_total < + UE_list->UE_template[pCC_id2][UE_id2]. + dl_buffer_total) { + swap_UEs(UE_list, UE_id1, UE_id2, 0); + } else if (cqi1 < cqi2) { + swap_UEs(UE_list, UE_id1, UE_id2, 0); + } + } } + } +#endif } void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, @@ -519,7 +589,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int min_rb_unit[NFAPI_CC_MAX], uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { int UE_id, CC_id; int i; @@ -541,16 +611,15 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, average_rbs_per_user[CC_id] = 0; } - // loop over all active UEs + // Find total UE count, and account the RBs required for retransmissions for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); - if (rnti == NOT_A_RNTI) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; - for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; @@ -579,12 +648,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -603,8 +669,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // recalculate based on the what is left after retransmission ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = - flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); if (total_ue_count[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; @@ -612,8 +677,8 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { average_rbs_per_user[CC_id] = (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); - } else { - // consider the total number of use that can be scheduled UE + } else { + // consider the total number of use that can be scheduled UE average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; } } @@ -639,9 +704,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // control channel or retransmission /* TODO: do we have to check for retransmission? */ if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) { - nb_rbs_required_remaining_1[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; + nb_rbs_accounted[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; } else { - nb_rbs_required_remaining_1[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + nb_rbs_accounted[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); } } } @@ -652,7 +717,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, int min_rb_unit[NFAPI_CC_MAX], uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { @@ -682,11 +747,11 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, if (r1 == 0) { nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining_1[CC_id][UE_id]; + nb_rbs_accounted[CC_id][UE_id]; } else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id] - - nb_rbs_required_remaining_1[CC_id][UE_id] + + nb_rbs_accounted[CC_id][UE_id] + nb_rbs_required_remaining[CC_id][UE_id]; if (nb_rbs_required_remaining[CC_id][UE_id] < 0) abort(); @@ -697,7 +762,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", r1, CC_id, UE_id, nb_rbs_required_remaining[CC_id][UE_id], - nb_rbs_required_remaining_1[CC_id][UE_id], + nb_rbs_accounted[CC_id][UE_id], nb_rbs_required[CC_id][UE_id], UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], N_RBG[CC_id], @@ -713,8 +778,6 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[i][UE_id]; // if there are UEs with traffic if (total_ue_count[CC_id] > 0) { - // ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - // round = ue_sched_ctl->round[CC_id][harq_pid]; rnti = UE_RNTI(Mod_id, UE_id); @@ -725,9 +788,6 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, continue; transmission_mode = get_tmode(Mod_id, CC_id, UE_id); - // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); - // rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); - /* 1st allocate for the retx */ // retransmission in data channels // control channel in the 1st transmission @@ -746,166 +806,166 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, MIMO_mode_indicator); #ifdef TM5 - // data chanel TM5: to be revisited - if ((round == 0) && - (transmission_mode == 5) && - (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + // data chanel TM5: to be revisited + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { - for (j = 0; j < N_RBG[CC_id]; j += 2) { + for (j = 0; j < N_RBG[CC_id]; j += 2) { - if ((((j == (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j] == 0) + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_remaining[CC_id][UE_id] + > 0)) { + + for (i = UE_list->next[UE_id + 1]; i >= 0; + i = UE_list->next[i]) { + + UE_id2 = i; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) && (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j + 1] == 0) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j + 1] == 0))) - && (nb_rbs_required_remaining[CC_id][UE_id] - > 0)) { + dl_pow_off[CC_id] != 1)) { - for (i = UE_list->next[UE_id + 1]; i >= 0; - i = UE_list->next[i]) { - - UE_id2 = i; - rnti2 = UE_RNTI(Mod_id, UE_id2); - ue_sched_ctl2 = - &UE_list->UE_sched_ctrl[UE_id2]; - round2 = ue_sched_ctl2->round[CC_id]; - if (rnti2 == NOT_A_RNTI) - continue; - if (UE_list-> - UE_sched_ctrl - [UE_id2].ul_out_of_sync == 1) - continue; - - eNB_UE_stats2 = - UE_list-> - eNB_UE_stats[CC_id][UE_id2]; - //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); - - if ((mac_eNB_get_rrc_status - (Mod_id, - rnti2) >= RRC_RECONFIGURED) - && (round2 == 0) - && - (get_tmode(Mod_id, CC_id, UE_id2) - == 5) - && (ue_sched_ctl-> - dl_pow_off[CC_id] != 1)) { - - if ((((j == (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j + - 1] - == 0))) + if ((((j == (N_RBG[CC_id] - 1)) && - (nb_rbs_required_remaining - [CC_id] - [UE_id2] > 0)) { + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_remaining + [CC_id] + [UE_id2] > 0)) { - if ((((eNB_UE_stats2-> - DL_pmi_single ^ - eNB_UE_stats1-> - DL_pmi_single) - << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration - rballoc_sub[CC_id][j] = 1; - ue_sched_ctl-> - rballoc_sub_UE[CC_id] - [j] = 1; - ue_sched_ctl2-> - rballoc_sub_UE[CC_id] - [j] = 1; - MIMO_mode_indicator[CC_id] - [j] = 0; + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> + rballoc_sub_UE[CC_id] + [j] = 1; + ue_sched_ctl2-> + rballoc_sub_UE[CC_id] + [j] = 1; + MIMO_mode_indicator[CC_id] + [j] = 0; - if (j < N_RBG[CC_id] - 1) { - rballoc_sub[CC_id][j + - 1] = - 1; - ue_sched_ctl-> - rballoc_sub_UE - [CC_id][j + 1] = 1; - ue_sched_ctl2->rballoc_sub_UE - [CC_id][j + 1] = 1; - MIMO_mode_indicator - [CC_id][j + 1] - = 0; - } + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } - ue_sched_ctl-> - dl_pow_off[CC_id] - = 0; - ue_sched_ctl2-> - dl_pow_off[CC_id] - = 0; + ue_sched_ctl-> + dl_pow_off[CC_id] + = 0; + ue_sched_ctl2-> + dl_pow_off[CC_id] + = 0; - if ((j == N_RBG[CC_id] - 1) - && ((N_RB_DL == 25) - || (N_RB_DL == - 50))) { + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - } else { + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - 4; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + 4; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - 4; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + 4; - } + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } - break; - } - } - } - } - } - } - } + break; + } + } + } + } + } + } + } #endif } // total_ue_count } // CC @@ -1284,10 +1344,10 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int UE_id, uint8_t CC_id, int N_RBG, - int transmission_mode, + int tm, int min_rb_unit, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) @@ -1300,51 +1360,38 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, for (i = 0; i < N_RBG; i++) { - if (rballoc_sub[CC_id][i] != 0) - continue; - if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0) - continue; - if (nb_rbs_required_remaining[CC_id][UE_id] <= 0) - continue; - if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) - continue; - if (ue_sched_ctl->dl_pow_off[CC_id] == 0) - continue; - if (slice_allocation_mask[CC_id][i] == 0) - continue; - -// if ((rballoc_sub[CC_id][i] == 0) && -// (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && -// (nb_rbs_required_remaining[CC_id][UE_id] > 0) && -// (ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) { -// // if this UE is not scheduled for TM5 -// if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { + if (rballoc_sub[CC_id][i] != 0) continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0) continue; + if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue; + if (slice_allocation_mask[CC_id][i] == 0) continue; if ((i == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { - if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit - 1) { + // Allocating last, smaller RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) { rballoc_sub[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { + if (tm == 5) { ue_sched_ctl->dl_pow_off[CC_id] = 1; } - nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit + 1; + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1; ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; } } else { - if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit) { + // Allocating a standard-sized RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) { rballoc_sub[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { + if (tm == 5) { ue_sched_ctl->dl_pow_off[CC_id] = 1; } - nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit; + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit; ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; } } -// } // dl_pow_off[CC_id][UE_id] ! = 0 -// } } } @@ -1442,7 +1489,8 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = + nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], N_RB_UL); if (total_ue_count[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; @@ -1614,7 +1662,8 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = + nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; if (bytes_to_schedule < 0) bytes_to_schedule = 0; From 71d1b1ab9a9aea726b8c0fa722a0760960b2db30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Mon, 26 Feb 2018 11:49:03 +0100 Subject: [PATCH 04/99] Refactoring and optimization --- openair2/LAYER2/MAC/mac_proto.h | 19 +++--- openair2/LAYER2/MAC/pre_processor.c | 92 ++++++++++++++--------------- 2 files changed, 53 insertions(+), 58 deletions(-) diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 85f6489e22..76bcc2c8f6 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -249,16 +249,15 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int tm, - int min_rb_unit, - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); + int UE_id, + uint8_t CC_id, + int N_RBG, + int min_rb_unit, + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], + unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f. diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index ed91254c6a..cba110894f 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -595,9 +595,12 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int i; rnti_t rnti; - uint8_t harq_pid, round, transmission_mode; - uint8_t total_rbs_used[NFAPI_CC_MAX]; + uint8_t harq_pid, round; + uint8_t rbs_retx[NFAPI_CC_MAX]; uint16_t average_rbs_per_user[NFAPI_CC_MAX]; + int ue_count_newtx[NFAPI_CC_MAX]; + int ue_count_retx[NFAPI_CC_MAX]; + uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; int N_RB_DL; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; @@ -607,8 +610,13 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Reset for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { total_ue_count[CC_id] = 0; - total_rbs_used[CC_id] = 0; + ue_count_newtx[CC_id] = 0; + ue_count_retx[CC_id] = 0; + rbs_retx[CC_id] = 0; average_rbs_per_user[CC_id] = 0; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { + ue_retx_flag[CC_id][UE_id] = 0; + } } // Find total UE count, and account the RBs required for retransmissions @@ -630,16 +638,17 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, harq_pid = ((frameP * 10) + subframeP) & 7; round = ue_sched_ctl->round[CC_id][harq_pid]; - average_rbs_per_user[CC_id] = 0; + if (nb_rbs_required[CC_id][UE_id] > 0) { + total_ue_count[CC_id]++; + } if (round != 8) { nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - total_rbs_used[CC_id] += nb_rbs_required[CC_id][UE_id]; - } - - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count[CC_id] = total_ue_count[CC_id] + 1; + rbs_retx[CC_id] += nb_rbs_required[CC_id][UE_id]; + ue_count_retx[CC_id]++; + ue_retx_flag[CC_id][UE_id] = 1; + } else { + ue_count_newtx[CC_id]++; } } } @@ -652,20 +661,10 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (!ue_slice_membership(UE_id, slice_id)) continue; - for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; - // hypothetical assignment - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ - - N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - total_rbs_used[CC_id]; + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - rbs_retx[CC_id]; // recalculate based on the what is left after retransmission ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; @@ -679,7 +678,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); } else { // consider the total number of use that can be scheduled UE - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; + average_rbs_per_user[CC_id] = (uint16_t)min_rb_unit[CC_id]; } } } @@ -688,11 +687,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // extend nb_rbs_required to capture per LCID RB required for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); - - if (rnti == NOT_A_RNTI) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -726,7 +723,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, uint8_t transmission_mode; uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; - uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; int N_RBG[NFAPI_CC_MAX]; rnti_t rnti; @@ -746,22 +743,22 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, N_RBG[i] = to_rbg(cc->mib->message.dl_Bandwidth); if (r1 == 0) { - nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_accounted[CC_id][UE_id]; } else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id] - nb_rbs_accounted[CC_id][UE_id] + - nb_rbs_required_remaining[CC_id][UE_id]; - if (nb_rbs_required_remaining[CC_id][UE_id] < 0) + nb_rbs_remaining[CC_id][UE_id]; + if (nb_rbs_remaining[CC_id][UE_id] < 0) abort(); } if (nb_rbs_required[CC_id][UE_id] > 0) LOG_D(MAC, - "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + "round %d : nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", r1, CC_id, UE_id, - nb_rbs_required_remaining[CC_id][UE_id], + nb_rbs_remaining[CC_id][UE_id], nb_rbs_accounted[CC_id][UE_id], nb_rbs_required[CC_id][UE_id], UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], @@ -797,10 +794,9 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, UE_id, CC_id, N_RBG[CC_id], - transmission_mode, min_rb_unit[CC_id], nb_rbs_required, - nb_rbs_required_remaining, + nb_rbs_remaining, rballoc_sub, slice_allocation_mask, MIMO_mode_indicator); @@ -1016,6 +1012,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, MIMO_mode_indicator, mbsfn_flag); // TODO Not sure if useful + // STATUS // Store the DLSCH buffer for each logical channel store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); @@ -1341,19 +1338,18 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int tm, - int min_rb_unit, - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) + int UE_id, + uint8_t CC_id, + int N_RBG, + int min_rb_unit, + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], + unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { - int i; + int tm = get_tmode(Mod_id, CC_id, UE_id); UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); From 89f5659586301c182f360cb3085a167c2f8114a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Mon, 26 Feb 2018 14:29:55 +0100 Subject: [PATCH 05/99] Add accounting policy to pre_processor --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 13 +++ openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 4 + openair2/LAYER2/MAC/pre_processor.c | 98 ++++++++++++++++------- 3 files changed, 85 insertions(+), 30 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index e6989d676c..22ea114273 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -537,6 +537,19 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in sorting_policy_current[i] = sorting_policy[i]; } + // Check for new accounting policy + if (accounting_policy_current[i] != accounting_policy[i]) { + if (accounting_policy[i] > 1 || accounting_policy[i] < 0) { + LOG_W(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", + module_idP, i, frameP, subframeP, accounting_policy[i], accounting_policy_current[i]); + accounting_policy[i] = accounting_policy_current[i]; + } else { + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, accounting_policy_current[i], accounting_policy[i]); + accounting_policy_current[i] = accounting_policy[i]; + } + } + // Run each enabled slice-specific schedulers one by one slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h index 29ce735b05..2112bc4038 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -71,6 +71,10 @@ char *dl_scheduler_type[MAX_NUM_SLICES] = uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; +// Accounting policy (just greedy(1) or fair(0) setting for now) +int accounting_policy[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int accounting_policy_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; + // pointer to the slice specific scheduler slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index cba110894f..253f5736a6 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -58,6 +58,7 @@ extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES]; extern int slice_position[MAX_NUM_SLICES*2]; extern uint32_t sorting_policy[MAX_NUM_SLICES]; +extern int accounting_policy[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; @@ -596,6 +597,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti_t rnti; uint8_t harq_pid, round; + uint16_t available_rbs; uint8_t rbs_retx[NFAPI_CC_MAX]; uint16_t average_rbs_per_user[NFAPI_CC_MAX]; int ue_count_newtx[NFAPI_CC_MAX]; @@ -622,7 +624,6 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Find total UE count, and account the RBs required for retransmissions for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); - if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (!ue_slice_membership(UE_id, slice_id)) continue; @@ -653,38 +654,77 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, } } - // loop over all active UEs and calculate avg rb per user based on total active UEs - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - rnti = UE_RNTI(Mod_id, UE_id); + switch (accounting_policy[slice_id]) { - if (rnti == NOT_A_RNTI) continue; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + // If greedy scheduling, try to account all the required RBs + case 1: + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; - for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { - CC_id = UE_list->ordered_CCids[i][UE_id]; - - N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - rbs_retx[CC_id]; - - // recalculate based on the what is left after retransmission - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); - - if (total_ue_count[CC_id] == 0) { - average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= - (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { - average_rbs_per_user[CC_id] = - (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); - } else { - // consider the total number of use that can be scheduled UE - average_rbs_per_user[CC_id] = (uint16_t)min_rb_unit[CC_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + nb_rbs_accounted[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; + } } - } + break; + + // Use the old, fair algorithm + // Loop over all active UEs and account the avg number of RBs to each UE, based on all non-retx UEs. + default: + // FIXME: This is not ideal, why loop on UEs to find average_rbs_per_user[], that is per-CC? + // TODO: Look how to loop on active CCs only without using the UE_num_active_CC() function. + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; + + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - rbs_retx[CC_id]; + // recalculate based on the what is left after retransmission + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + + available_rbs = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]; + + if (total_ue_count[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= available_rbs) { + average_rbs_per_user[CC_id] = (uint16_t) floor(available_rbs / total_ue_count[CC_id]); + } else { + // consider the total number of use that can be scheduled UE + average_rbs_per_user[CC_id] = (uint16_t)min_rb_unit[CC_id]; + } + } + } + + // note: nb_rbs_required is assigned according to total_buffer_dl + // extend nb_rbs_required to capture per LCID RB required + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; + + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + nb_rbs_accounted[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + } + } + break; } - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required + + + + // Check retransmissions + // TODO: Do this once at the beginning for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; @@ -702,8 +742,6 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, /* TODO: do we have to check for retransmission? */ if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) { nb_rbs_accounted[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; - } else { - nb_rbs_accounted[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); } } } From d5415b209685614f707f0a2e7a0e93f5f68097be Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 13 Jun 2018 14:47:17 +0200 Subject: [PATCH 06/99] Fix: provide N_RBG in TM5 mode --- openair2/LAYER2/MAC/pre_processor.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 253f5736a6..e4d8fde584 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1082,11 +1082,13 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, #ifdef TM5 // This has to be revisited!!!! for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { - i1 = 0; - i2 = 0; - i3 = 0; + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); + i1 = 0; + i2 = 0; + i3 = 0; - for (j = 0; j < N_RBG[CC_id]; j++) { + for (j = 0; j < N_RBG; j++) { if (MIMO_mode_indicator[CC_id][j] == 2) { i1 = i1 + 1; } else if (MIMO_mode_indicator[CC_id][j] == 1) { @@ -1094,27 +1096,27 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } else if (MIMO_mode_indicator[CC_id][j] == 0) { i3 = i3 + 1; } - } + } - if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { + if ((i1 < N_RBG) && (i2 > 0) && (i3 == 0)) { PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]-> check_for_SUMIMO_transmissions + 1; - } + } - if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { + if (i3 == N_RBG && i1 == 0 && i2 == 0) { PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1; - } + } - if ((i1 < N_RBG[CC_id]) && (i3 > 0)) { + if ((i1 < N_RBG) && (i3 > 0)) { PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]-> check_for_MUMIMO_transmissions + 1; - } + } - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + 1; From e80f64c8e5a47b4926842c2e89867b195d67862b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Mon, 26 Feb 2018 15:09:36 +0100 Subject: [PATCH 07/99] Split positioning() in positioning() and intraslice_sharing() --- openair2/LAYER2/MAC/mac_proto.h | 12 +- openair2/LAYER2/MAC/pre_processor.c | 358 ++++++++++++++++++++++------ 2 files changed, 291 insertions(+), 79 deletions(-) diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 76bcc2c8f6..2bfee4daa1 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -235,19 +235,27 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, frame_t frameP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], - uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]); void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, slice_id_t slice_id, int min_rb_unit[NFAPI_CC_MAX], - uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); +void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, + slice_id_t slice_id, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); + void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int UE_id, uint8_t CC_id, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e4d8fde584..1e5bb541a5 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -588,7 +588,6 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, frame_t frameP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], - uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { @@ -600,6 +599,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, uint16_t available_rbs; uint8_t rbs_retx[NFAPI_CC_MAX]; uint16_t average_rbs_per_user[NFAPI_CC_MAX]; + int total_ue_count[NFAPI_CC_MAX]; int ue_count_newtx[NFAPI_CC_MAX]; int ue_count_retx[NFAPI_CC_MAX]; uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; @@ -750,94 +750,63 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, slice_id_t slice_id, int min_rb_unit[NFAPI_CC_MAX], - uint8_t total_ue_count[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { - + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) +{ int UE_id, CC_id; int i; uint8_t transmission_mode; uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; - uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; int N_RBG[NFAPI_CC_MAX]; - rnti_t rnti; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); - //Allocation to UEs is done in 2 rounds, - // 1st stage: average number of RBs allocated to each UE - // 2nd stage: remaining RBs are allocated to high priority UEs - for (int r1 = 0; r1 < 2; r1++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + } - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { - CC_id = UE_list->ordered_CCids[i][UE_id]; - COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; - N_RBG[i] = to_rbg(cc->mib->message.dl_Bandwidth); + // Try to allocate accounted RBs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - if (r1 == 0) { - nb_rbs_remaining[CC_id][UE_id] = - nb_rbs_accounted[CC_id][UE_id]; - } else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round - nb_rbs_remaining[CC_id][UE_id] = - nb_rbs_required[CC_id][UE_id] - - nb_rbs_accounted[CC_id][UE_id] + - nb_rbs_remaining[CC_id][UE_id]; - if (nb_rbs_remaining[CC_id][UE_id] < 0) - abort(); - } + if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; - if (nb_rbs_required[CC_id][UE_id] > 0) - LOG_D(MAC, - "round %d : nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", - r1, CC_id, UE_id, - nb_rbs_remaining[CC_id][UE_id], - nb_rbs_accounted[CC_id][UE_id], - nb_rbs_required[CC_id][UE_id], - UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], - N_RBG[CC_id], - min_rb_unit[CC_id]); + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_accounted[CC_id][UE_id]; + transmission_mode = get_tmode(Mod_id, CC_id, UE_id); - } - } + if (nb_rbs_required[CC_id][UE_id] > 0) + LOG_D(MAC, + "Step 1: nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + CC_id, + UE_id, + nb_rbs_remaining[CC_id][UE_id], + nb_rbs_accounted[CC_id][UE_id], + nb_rbs_required[CC_id][UE_id], + UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], + N_RBG[CC_id], + min_rb_unit[CC_id]); - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - - for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { - - CC_id = UE_list->ordered_CCids[i][UE_id]; - // if there are UEs with traffic - if (total_ue_count[CC_id] > 0) { - - rnti = UE_RNTI(Mod_id, UE_id); - - // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); - if (rnti == NOT_A_RNTI) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; - - transmission_mode = get_tmode(Mod_id, CC_id, UE_id); - - // retransmission in data channels - // control channel in the 1st transmission - // data channel for all TM - LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n "); - dlsch_scheduler_pre_processor_allocate(Mod_id, - UE_id, - CC_id, - N_RBG[CC_id], - min_rb_unit[CC_id], - nb_rbs_required, - nb_rbs_remaining, - rballoc_sub, - slice_allocation_mask, - MIMO_mode_indicator); + LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, + UE_id, + CC_id, + N_RBG[CC_id], + min_rb_unit[CC_id], + nb_rbs_required, + nb_rbs_remaining, + rballoc_sub, + slice_allocation_mask, + MIMO_mode_indicator); #ifdef TM5 // data chanel TM5: to be revisited @@ -1001,10 +970,236 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, } } #endif - } // total_ue_count - } // CC - } // UE - } // end of for for r1 and r2 + } + } +} + +void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, + slice_id_t slice_id, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { + + int UE_id, CC_id; + int i; + uint8_t transmission_mode; + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int N_RBG[NFAPI_CC_MAX]; + + decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); + + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + } + + // Remaining RBs are allocated to high priority UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + + if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; + + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + nb_rbs_remaining[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id] - nb_rbs_accounted[CC_id][UE_id] + nb_rbs_remaining[CC_id][UE_id]; + if (nb_rbs_remaining[CC_id][UE_id] < 0) + abort(); + transmission_mode = get_tmode(Mod_id, CC_id, UE_id); + + if (nb_rbs_required[CC_id][UE_id] > 0) + LOG_D(MAC, + "Step 2: nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + CC_id, + UE_id, + nb_rbs_remaining[CC_id][UE_id], + nb_rbs_accounted[CC_id][UE_id], + nb_rbs_required[CC_id][UE_id], + UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], + N_RBG[CC_id], + min_rb_unit[CC_id]); + + LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, + UE_id, + CC_id, + N_RBG[CC_id], + min_rb_unit[CC_id], + nb_rbs_required, + nb_rbs_remaining, + rballoc_sub, + slice_allocation_mask, + MIMO_mode_indicator); + +#ifdef TM5 + // data chanel TM5: to be revisited + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + + for (j = 0; j < N_RBG[CC_id]; j += 2) { + + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_remaining[CC_id][UE_id] + > 0)) { + + for (i = UE_list->next[UE_id + 1]; i >= 0; + i = UE_list->next[i]) { + + UE_id2 = i; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { + + if ((((j == (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_remaining + [CC_id] + [UE_id2] > 0)) { + + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> + rballoc_sub_UE[CC_id] + [j] = 1; + ue_sched_ctl2-> + rballoc_sub_UE[CC_id] + [j] = 1; + MIMO_mode_indicator[CC_id] + [j] = 0; + + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } + + ue_sched_ctl-> + dl_pow_off[CC_id] + = 0; + ue_sched_ctl2-> + dl_pow_off[CC_id] + = 0; + + + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { + + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { + + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } + + break; + } + } + } + } + } + } + } +#endif + } + } } // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done @@ -1020,12 +1215,12 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, uint16_t i, j; uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; - uint8_t total_ue_count[NFAPI_CC_MAX]; uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting int min_rb_unit[NFAPI_CC_MAX]; uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -1066,19 +1261,28 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // This procedure decides the number of RBs to allocate dlsch_scheduler_pre_processor_accounting(Mod_id, slice_id, frameP, subframeP, min_rb_unit, - total_ue_count, nb_rbs_required, nb_rbs_accounted); // POSITIONING // This procedure does the main allocation of the RBs dlsch_scheduler_pre_processor_positioning(Mod_id, slice_id, min_rb_unit, - total_ue_count, nb_rbs_required, nb_rbs_accounted, + nb_rbs_remaining, rballoc_sub, MIMO_mode_indicator); + // SHARING + // If there are available RBs left in the slice, allocate them to the highest priority UEs + dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_id, + min_rb_unit, + nb_rbs_required, + nb_rbs_accounted, + nb_rbs_remaining, + rballoc_sub, + MIMO_mode_indicator); + #ifdef TM5 // This has to be revisited!!!! for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { From ee4972cd2c65bdb99817eb953d408a3db5d6f325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Mon, 26 Feb 2018 16:12:37 +0100 Subject: [PATCH 08/99] Add partitioning as a separate function --- openair2/LAYER2/MAC/mac_proto.h | 4 +++ openair2/LAYER2/MAC/pre_processor.c | 40 ++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 2bfee4daa1..23d7fb49d7 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -230,6 +230,10 @@ void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], int *mbsfn_flag); +void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, + slice_id_t slice_id, + const uint8_t rbs_retx[NFAPI_CC_MAX]); + void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 1e5bb541a5..24621f5874 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -583,6 +583,29 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t #endif } +void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, + slice_id_t slice_id, + const uint8_t rbs_retx[NFAPI_CC_MAX]) { + int UE_id, CC_id, N_RB_DL, i; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + + if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; + + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL) - rbs_retx[CC_id]; + } + } +} + void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, @@ -604,7 +627,6 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int ue_count_retx[NFAPI_CC_MAX]; uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - int N_RB_DL; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; @@ -654,6 +676,10 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, } } + // PARTITIONING + // Reduces the available RBs according to slicing configuration + dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); + switch (accounting_policy[slice_id]) { // If greedy scheduling, try to account all the required RBs @@ -684,19 +710,15 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (!ue_slice_membership(UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { + CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - rbs_retx[CC_id]; - // recalculate based on the what is left after retransmission - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); - available_rbs = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]; - if (total_ue_count[CC_id] == 0) { + if (ue_count_newtx[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= available_rbs) { - average_rbs_per_user[CC_id] = (uint16_t) floor(available_rbs / total_ue_count[CC_id]); + } else if (min_rb_unit[CC_id]*ue_count_newtx[CC_id] <= available_rbs) { + average_rbs_per_user[CC_id] = (uint16_t)floor(available_rbs/ue_count_newtx[CC_id]); } else { // consider the total number of use that can be scheduled UE average_rbs_per_user[CC_id] = (uint16_t)min_rb_unit[CC_id]; From df36e3f054b960ae077d55c598a6e9888c1caa96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Tue, 6 Mar 2018 11:16:59 +0100 Subject: [PATCH 09/99] Bugfix: value of available RBs per slice could be negative --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 38 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 42 +-- openair2/LAYER2/MAC/pre_processor.c | 409 ++++++++++------------ 3 files changed, 232 insertions(+), 257 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 22ea114273..962c871c6b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -417,8 +417,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in int i = 0; - total_slice_percentage=0; - avg_slice_percentage=1.0/n_active_slices; + slice_percentage_total=0; + slice_percentage_avg=1.0/n_active_slices; // reset the slice percentage for inactive slices for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { @@ -430,7 +430,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in module_idP, frameP, subframeP, i, slice_percentage[i]); slice_percentage[i]=0; } - total_slice_percentage+=slice_percentage[i]; + slice_percentage_total+=slice_percentage[i]; } for (i = 0; i < n_active_slices; i++) { @@ -443,7 +443,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in LOG_I(MAC,"update dl scheduler slice %d\n", i); } - if (total_slice_percentage <= 1.0){ // the new total RB share is within the range + if (slice_percentage_total <= 1.0){ // the new total RB share is within the range // check if the number of slices has changed, and log if (n_active_slices_current != n_active_slices ){ @@ -462,9 +462,9 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (slice_percentage_current[i] != slice_percentage[i]) { // new slice percentage LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, + module_idP, i, frameP, subframeP, slice_percentage_total_current, slice_percentage_total, slice_percentage_current[i], slice_percentage[i]); - total_slice_percentage_current = total_slice_percentage; + slice_percentage_total_current = slice_percentage_total; slice_percentage_current[i] = slice_percentage[i]; } @@ -493,14 +493,14 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (n_active_slices == n_active_slices_current){ LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, total_slice_percentage_current, total_slice_percentage); - if (slice_percentage[i] >= avg_slice_percentage){ + module_idP, i, slice_percentage_total_current, slice_percentage_total); + if (slice_percentage[i] >= slice_percentage_avg){ slice_percentage[i]-=0.1; - total_slice_percentage-=0.1; + slice_percentage_total-=0.1; } } else { LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, total_slice_percentage_current, total_slice_percentage, + module_idP, i, slice_percentage_total_current, slice_percentage_total, n_active_slices, n_active_slices_current ); n_active_slices = n_active_slices_current; slice_percentage[i] = slice_percentage_current[i]; @@ -531,22 +531,22 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in } // Check for new sorting policy - if (sorting_policy_current[i] != sorting_policy[i]) { + if (slice_sorting_policy_current[i] != slice_sorting_policy[i]) { LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, sorting_policy_current[i], sorting_policy[i]); - sorting_policy_current[i] = sorting_policy[i]; + module_idP, i, frameP, subframeP, slice_sorting_policy_current[i], slice_sorting_policy[i]); + slice_sorting_policy_current[i] = slice_sorting_policy[i]; } // Check for new accounting policy - if (accounting_policy_current[i] != accounting_policy[i]) { - if (accounting_policy[i] > 1 || accounting_policy[i] < 0) { + if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) { + if (slice_accounting_policy[i] > 1 || slice_accounting_policy[i] < 0) { LOG_W(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, accounting_policy[i], accounting_policy_current[i]); - accounting_policy[i] = accounting_policy_current[i]; + module_idP, i, frameP, subframeP, slice_accounting_policy[i], slice_accounting_policy_current[i]); + slice_accounting_policy[i] = slice_accounting_policy_current[i]; } else { LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, accounting_policy_current[i], accounting_policy[i]); - accounting_policy_current[i] = accounting_policy[i]; + module_idP, i, frameP, subframeP, slice_accounting_policy_current[i], slice_accounting_policy[i]); + slice_accounting_policy_current[i] = slice_accounting_policy[i]; } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h index 2112bc4038..8a5422a890 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -38,26 +38,34 @@ #define __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ // number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; +int n_active_slices = 1; +int n_active_slices_current = 1; // RB share for each slice for past and current time -float avg_slice_percentage=0.25; -float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage = 0; -float total_slice_percentage_current = 0; +float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_total = 0; +float slice_percentage_total_current = 0; +float slice_percentage_avg = 0.25; // Frequency ranges for slice positioning -int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; -int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; +int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; +int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; // MAX MCS for each slice for past and current time -int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; -int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; +int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; +int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; -int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; -int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; +// The lists of criteria that enforce the sorting policies of the slices +uint32_t slice_sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; +uint32_t slice_sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; + +// Accounting policy (just greedy(1) or fair(0) setting for now) +int slice_accounting_policy[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_accounting_policy_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; + +int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; +int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; // name of available scheduler char *dl_scheduler_type[MAX_NUM_SLICES] = @@ -67,14 +75,6 @@ char *dl_scheduler_type[MAX_NUM_SLICES] = "schedule_ue_spec" }; -// The lists of criteria that enforce the sorting policies of the slices -uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; -uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; - -// Accounting policy (just greedy(1) or fair(0) setting for now) -int accounting_policy[MAX_NUM_SLICES] = {0, 0, 0, 0}; -int accounting_policy_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; - // pointer to the slice specific scheduler slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 24621f5874..4f8510f49c 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -54,14 +54,13 @@ extern RAN_CONTEXT_t RC; #define DEBUG_HEADER_PARSING 1 //#define DEBUG_PACKET_TRACE 1 -extern float slice_percentage[MAX_NUM_SLICES]; -extern float slice_percentage_uplink[MAX_NUM_SLICES]; -extern int slice_position[MAX_NUM_SLICES*2]; -extern uint32_t sorting_policy[MAX_NUM_SLICES]; -extern int accounting_policy[MAX_NUM_SLICES]; - -extern int slice_maxmcs[MAX_NUM_SLICES]; -extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; +extern float slice_percentage[MAX_NUM_SLICES]; +extern float slice_percentage_uplink[MAX_NUM_SLICES]; +extern int slice_position[MAX_NUM_SLICES*2]; +extern uint32_t slice_sorting_policy[MAX_NUM_SLICES]; +extern int slice_accounting_policy[MAX_NUM_SLICES]; +extern int slice_maxmcs[MAX_NUM_SLICES]; +extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; //#define ICIC 0 @@ -97,95 +96,89 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) // This function stores the downlink buffer for all the logical channels void -store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, - sub_frame_t subframeP) -{ +store_dlsch_buffer(module_id_t Mod_id, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP) { - int UE_id, i; - rnti_t rnti; - mac_rlc_status_resp_t rlc_status; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_TEMPLATE *UE_template; + int UE_id, i; + rnti_t rnti; + mac_rlc_status_resp_t rlc_status; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_TEMPLATE *UE_template; - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_list->active[UE_id] != TRUE) + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; - UE_template = - &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; + UE_template = + &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; - // clear logical channel interface variables - UE_template->dl_buffer_total = 0; - UE_template->dl_pdus_total = 0; + // clear logical channel interface variables + UE_template->dl_buffer_total = 0; + UE_template->dl_pdus_total = 0; - for (i = 0; i < MAX_NUM_LCID; i++) { - UE_template->dl_buffer_info[i] = 0; - UE_template->dl_pdus_in_buffer[i] = 0; - UE_template->dl_buffer_head_sdu_creation_time[i] = 0; - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0; - } + for (i = 0; i < MAX_NUM_LCID; i++) { + UE_template->dl_buffer_info[i] = 0; + UE_template->dl_pdus_in_buffer[i] = 0; + UE_template->dl_buffer_head_sdu_creation_time[i] = 0; + UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0; + } + rnti = UE_RNTI(Mod_id, UE_id); - rnti = UE_RNTI(Mod_id, UE_id); + for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels - for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels - - rlc_status = - mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, + rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, i, 0 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); - - UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel - UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; - UE_template->dl_buffer_head_sdu_creation_time[i] = - rlc_status.head_sdu_creation_time; - UE_template->dl_buffer_head_sdu_creation_time_max = - cmax(UE_template->dl_buffer_head_sdu_creation_time_max, - rlc_status.head_sdu_creation_time); - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = - rlc_status.head_sdu_remaining_size_to_send; - UE_template->dl_buffer_head_sdu_is_segmented[i] = - rlc_status.head_sdu_is_segmented; - UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer - UE_template->dl_pdus_total += - UE_template->dl_pdus_in_buffer[i]; + UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel + UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; + UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time; + UE_template->dl_buffer_head_sdu_creation_time_max = + cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time); + UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = + rlc_status.head_sdu_remaining_size_to_send; + UE_template->dl_buffer_head_sdu_is_segmented[i] = + rlc_status.head_sdu_is_segmented; + UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer + UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[i]; #ifdef DEBUG_eNB_SCHEDULER - /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : - * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent - */ - if (UE_template->dl_buffer_info[i] > 0) - LOG_D(MAC, - "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, slice_id, frameP, subframeP, UE_id, - i, UE_template->dl_pdus_in_buffer[i], - UE_template->dl_buffer_info[i], - UE_template->dl_buffer_head_sdu_creation_time[i], - UE_template-> - dl_buffer_head_sdu_remaining_size_to_send[i], - UE_template->dl_buffer_head_sdu_is_segmented[i]); + /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : + * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent + */ + if (UE_template->dl_buffer_info[i] > 0) + LOG_D(MAC, + "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", + Mod_id, slice_id, frameP, subframeP, UE_id, + i, UE_template->dl_pdus_in_buffer[i], + UE_template->dl_buffer_info[i], + UE_template->dl_buffer_head_sdu_creation_time[i], + UE_template->dl_buffer_head_sdu_remaining_size_to_send[i], + UE_template->dl_buffer_head_sdu_is_segmented[i]); #endif - } - - //#ifdef DEBUG_eNB_SCHEDULER - if (UE_template->dl_buffer_total > 0) - LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", - Mod_id, frameP, subframeP, UE_id, - UE_template->dl_buffer_total, - UE_template->dl_pdus_total); - - //#endif } + + //#ifdef DEBUG_eNB_SCHEDULER + if (UE_template->dl_buffer_total > 0) + LOG_D(MAC, + "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", + Mod_id, frameP, subframeP, UE_id, + UE_template->dl_buffer_total, + UE_template->dl_pdus_total); + + //#endif + } } @@ -199,156 +192,133 @@ assign_rbs_required(module_id_t Mod_id, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { - uint16_t TBS = 0; + uint16_t TBS = 0; - int UE_id, n, i, j, CC_id, pCCid, tmp; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j; - int N_RB_DL; + int UE_id, n, i, j, CC_id, pCCid, tmp; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j; + int N_RB_DL; - // clear rb allocations across all CC_id - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; - pCCid = UE_PCCID(Mod_id, UE_id); + // clear rb allocations across all CC_id + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (UE_list->active[UE_id] != TRUE) continue; + if (!ue_slice_membership(UE_id, slice_id)) continue; + pCCid = UE_PCCID(Mod_id, UE_id); - //update CQI information across component carriers - for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { - CC_id = UE_list->ordered_CCids[n][UE_id]; - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + //update CQI information across component carriers + for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { - eNB_UE_stats->dlsch_mcs1 =cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], - slice_maxmcs[slice_id]); + CC_id = UE_list->ordered_CCids[n][UE_id]; + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], slice_maxmcs[slice_id]); - } + } - // provide the list of CCs sorted according to MCS - for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { - eNB_UE_stats_i = - &UE_list->eNB_UE_stats[UE_list-> - ordered_CCids[i][UE_id]][UE_id]; - for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { - DevAssert(j < NFAPI_CC_MAX); - eNB_UE_stats_j = - &UE_list-> - eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; - if (eNB_UE_stats_j->dlsch_mcs1 > - eNB_UE_stats_i->dlsch_mcs1) { - tmp = UE_list->ordered_CCids[i][UE_id]; - UE_list->ordered_CCids[i][UE_id] = - UE_list->ordered_CCids[j][UE_id]; - UE_list->ordered_CCids[j][UE_id] = tmp; - } - } - } + // provide the list of CCs sorted according to MCS + for (i = 0; i < UE_list->numactiveCCs[UE_id]; ++i) { + eNB_UE_stats_i = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]][UE_id]; + for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { + DevAssert(j < NFAPI_CC_MAX); + eNB_UE_stats_j = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; + if (eNB_UE_stats_j->dlsch_mcs1 > eNB_UE_stats_i->dlsch_mcs1) { + tmp = UE_list->ordered_CCids[i][UE_id]; + UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id]; + UE_list->ordered_CCids[j][UE_id] = tmp; + } + } + } - if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) { - LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id); + if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) { + LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id); - for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { - CC_id = UE_list->ordered_CCids[i][UE_id]; - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - if (eNB_UE_stats->dlsch_mcs1 == 0) { - nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small - } else { - nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; - } + if (eNB_UE_stats->dlsch_mcs1 == 0) { + nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small + } else { + nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; + } - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_rbs_required[CC_id][UE_id]); + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]); - LOG_D(MAC, - "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", - UE_id, CC_id, - UE_list->UE_template[pCCid][UE_id].dl_buffer_total, - nb_rbs_required[CC_id][UE_id], - eNB_UE_stats->dlsch_mcs1, TBS); + LOG_D(MAC, + "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", + UE_id, CC_id, + UE_list->UE_template[pCCid][UE_id].dl_buffer_total, + nb_rbs_required[CC_id][UE_id], + eNB_UE_stats->dlsch_mcs1, TBS); - N_RB_DL = - to_prb(RC.mac[Mod_id]->common_channels[CC_id]. - mib->message.dl_Bandwidth); + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] = + UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); - /* calculating required number of RBs for each UE */ - while (TBS < - UE_list->UE_template[pCCid][UE_id]. - dl_buffer_total) { - nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; + /* calculating required number of RBs for each UE */ + while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { + nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; - if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); - nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; - break; - } + if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); + nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; + break; + } + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]); + } // end of while - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_rbs_required[CC_id][UE_id]); - } // end of while - - LOG_D(MAC, - "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n", - Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id], - nb_rbs_required[CC_id][UE_id], TBS, - eNB_UE_stats->dlsch_mcs1); - } - } + LOG_D(MAC, + "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n", + Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id], + nb_rbs_required[CC_id][UE_id], TBS, + eNB_UE_stats->dlsch_mcs1); + } } + } } // This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes - int maxround(module_id_t Mod_id, uint16_t rnti, int frame, - sub_frame_t subframe, uint8_t ul_flag) -{ + sub_frame_t subframe, uint8_t ul_flag) { - uint8_t round, round_max = 0, UE_id; - int CC_id, harq_pid; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - COMMON_channels_t *cc; + uint8_t round, round_max = 0, UE_id; + int CC_id, harq_pid; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + COMMON_channels_t *cc; - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + cc = &RC.mac[Mod_id]->common_channels[CC_id]; - cc = &RC.mac[Mod_id]->common_channels[CC_id]; + UE_id = find_UE_id(Mod_id, rnti); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe); - UE_id = find_UE_id(Mod_id, rnti); - - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe); - - round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; - if (round > round_max) { - round_max = round; - } + round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; + if (round > round_max) { + round_max = round; } + } - return round_max; + return round_max; } // This function scans all CC_ids for a particular UE to find the maximum DL CQI // it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL) -int maxcqi(module_id_t Mod_id, int32_t UE_id) -{ - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - int CC_id, n; - int CQI = 0; +int maxcqi(module_id_t Mod_id, int32_t UE_id) { + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int CC_id, n; + int CQI = 0; - for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { - CC_id = UE_list->ordered_CCids[n][UE_id]; + for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { + CC_id = UE_list->ordered_CCids[n][UE_id]; - if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) { - CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; - } + if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) { + CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; } + } - return CQI; + return CQI; } struct sort_ue_dl_params { @@ -360,24 +330,24 @@ struct sort_ue_dl_params { static int ue_dl_compare(const void *_a, const void *_b, void *_params) { - struct sort_ue_dl_params *params = _params; - UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; + struct sort_ue_dl_params *params = _params; + UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; - int i; - int slice_id = params->slice_id; - int UE_id1 = *(const int *) _a; - int UE_id2 = *(const int *) _b; + int i; + int slice_id = params->slice_id; + int UE_id1 = *(const int *) _a; + int UE_id2 = *(const int *) _b; - int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); - int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); - int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); + int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); + int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); + int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); - int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); - int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); - int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); + int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); + int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); + int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); - int cqi1 = maxcqi(params->Mod_idP, UE_id1); - int cqi2 = maxcqi(params->Mod_idP, UE_id2); + int cqi1 = maxcqi(params->Mod_idP, UE_id1); + int cqi2 = maxcqi(params->Mod_idP, UE_id2); for (i = 0; i < CR_NUM; ++i) { switch (UE_list->sorting_criteria[slice_id][i]) { @@ -435,22 +405,22 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) } void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { - int i; + int i; - UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - uint32_t policy = sorting_policy[slice_id]; - uint32_t mask = 0x0000000F; - uint16_t criterion; + UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + uint32_t policy = slice_sorting_policy[slice_id]; + uint32_t mask = 0x0000000F; + uint16_t criterion; - for(i = 0; i < CR_NUM; ++i) { - criterion = (uint16_t)(policy >> 4*(CR_NUM - 1 - i) & mask); - if (criterion >= CR_NUM) { - LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); - sorting_policy[slice_id] = 0x1234; - break; - } - UE_list->sorting_criteria[slice_id][i] = criterion; - } + for (i = 0; i < CR_NUM; ++i) { + criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); + if (criterion >= CR_NUM) { + LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); + slice_sorting_policy[slice_id] = 0x1234; + break; + } + UE_list->sorting_criteria[slice_id][i] = criterion; + } } void decode_slice_positioning(module_id_t Mod_idP, @@ -589,6 +559,7 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, int UE_id, CC_id, N_RB_DL, i; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; + uint16_t available_rbs; for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { @@ -601,7 +572,11 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL) - rbs_retx[CC_id]; + available_rbs = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + if (rbs_retx[CC_id] < available_rbs) + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = available_rbs - rbs_retx[CC_id]; + else + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = 0; } } } @@ -680,7 +655,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Reduces the available RBs according to slicing configuration dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); - switch (accounting_policy[slice_id]) { + switch (slice_accounting_policy[slice_id]) { // If greedy scheduling, try to account all the required RBs case 1: From e2c270ee948f52d09aa6b5f5da346168d6a36072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Wed, 7 Mar 2018 11:23:20 +0100 Subject: [PATCH 10/99] Fix indentation in schedule_ue_spec() and pre_processor.c --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 709 +++++++++++----------- openair2/LAYER2/MAC/pre_processor.c | 52 +- 2 files changed, 365 insertions(+), 396 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 962c871c6b..db9ec66ef7 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -560,8 +560,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in //------------------------------------------------------------------------------ void -schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) +schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { int CC_id; @@ -601,49 +601,46 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, int header_length_total; start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); // for TDD: check that we have to act here, otherwise return if (cc[0].tdd_Config) { tdd_sfa = cc[0].tdd_Config->subframeAssignment; switch (subframeP) { - case 0: - // always continue - break; - case 1: - return; - break; - case 2: - return; - break; - case 3: - if ((tdd_sfa != 2) && (tdd_sfa != 5)) - return; - break; - case 4: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 5: - break; - case 6: - case 7: - if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) - return; - break; - case 8: - if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 9: - if (tdd_sfa == 0) - return; - break; - + case 0: + // always continue + break; + case 1: + return; + break; + case 2: + return; + break; + case 3: + if ((tdd_sfa != 2) && (tdd_sfa != 5)) + return; + break; + case 4: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 5: + break; + case 6: + case 7: + if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) + return; + break; + case 8: + if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 9: + if (tdd_sfa == 0) + return; + break; } } //weight = get_ue_weight(module_idP,UE_id); @@ -655,7 +652,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; for (i = 0; i < N_RB_DL[CC_id]; i++) if (cc[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; + total_nb_available_rb[CC_id]--; N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); @@ -667,10 +664,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; } - /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) + // CALLING Pre_Processor for downlink scheduling + // (Returns estimation of RBs required by each UE and the allocation on sub-band) + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor(module_idP, slice_idP, @@ -678,8 +675,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, subframeP, mbsfn_flag); stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); @@ -689,49 +686,45 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (mbsfn_flag[CC_id] > 0) continue; - for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { - continue_flag = 0; // reset the flag to allow allocation for the remaining UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs rnti = UE_RNTI(module_idP, UE_id); eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - if (rnti == NOT_A_RNTI) { - LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", - UE_id, UE_list->num_UEs); - continue_flag = 1; + LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id, UE_list->num_UEs); + continue_flag = 1; } if (eNB_UE_stats == NULL) { - LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); - continue_flag = 1; + LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); + continue_flag = 1; } + if (!ue_slice_membership(UE_id, slice_idP)) - continue; + continue; if (continue_flag != 1) { - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC, "Unsupported transmission mode %d\n", - get_tmode(module_idP, CC_id, UE_id)); - aggregation = 2; - } + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; + case 3: + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + default: + LOG_W(MAC, "Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id)); + aggregation = 2; + } } + /* if (continue_flag != 1 */ if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, @@ -742,78 +735,71 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 } - if (cc[CC_id].tdd_Config != NULL) { //TDD - set_ue_dai(subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); - // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + // If TDD + if (cc[CC_id].tdd_Config != NULL) { //TDD + set_ue_dai(subframeP, + UE_id, + CC_id, + cc[CC_id].tdd_Config->subframeAssignment, + UE_list); + // update UL DAI after DLSCH scheduling + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); } if (continue_flag == 1) { - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, S_DL_NONE); - continue; + add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_NONE); + continue; } nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; + 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; /* - DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), - eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); + DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || + (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), + eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); */ if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - else { // this operation is also done in the preprocessor - eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } else { // this operation is also done in the preprocessor + eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } + // Store stats + // UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - - // store stats - //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - - // initializing the rb allocation indicator for each UE + // Initializing the rb allocation indicator for each UE for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; } LOG_D(MAC, - "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, - nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], - eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); - - + "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, + nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], + eNB_UE_stats->dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); /* process retransmission */ - if (round != 8) { - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], - nb_rb); + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], nb_rb); if (nb_rb <= nb_available_rb) { if (cc[CC_id].tdd_Config != NULL) { @@ -826,82 +812,82 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->UE_template[CC_id][UE_id].DAI); } - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) - printf("WARN: rballoc_subband not free for retrans?\n"); - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) + printf("WARN: rballoc_subband not free for retrans?\n"); + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } - } + if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + } - j = j + 1; - } - } + j = j + 1; + } + } - nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + nb_available_rb -= nb_rb; + /* + eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - */ + for(j = 0; j < N_RBG[CC_id]; ++j) { + eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } + */ - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - default: - LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + default: + LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n", rnti); - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI: see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); - } else { - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + // TDD + if (cc[CC_id].tdd_Config != NULL) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = + (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + } else { + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); } if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, @@ -913,48 +899,44 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 - /* retransmission, no pdu_index */ - , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); + fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1, + /* retransmission, no pdu_index */ + rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), + round & 3, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", - eNB->pdu_index[CC_id], round); + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", + eNB->pdu_index[CC_id], round); - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - // No TX request for retransmission (check if null request for FAPI) - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", - frameP, subframeP, UE_id, rnti); - } - } + program_dlsch_acknak(module_idP, CC_id, UE_id, frameP, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + // No TX request for retransmission (check if null request for FAPI) + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP, subframeP, UE_id, rnti); + } + } - - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); + add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); //eNB_UE_stats->dlsch_trials[round]++; UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; @@ -976,17 +958,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, // add the length for all the control elements (timing adv, drx, etc) : header + payload - if (ue_sched_ctl->ta_timer == 0) { - ta_update = ue_sched_ctl->ta_update; - /* if we send TA then set timer to not send it for a while */ - if (ta_update != 31) ue_sched_ctl->ta_timer = 20; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - } else { - ta_update = 31; - } + if (ue_sched_ctl->ta_timer == 0) { + ta_update = ue_sched_ctl->ta_update; + /* if we send TA then set timer to not send it for a while */ + if (ta_update != 31) + ue_sched_ctl->ta_timer = 20; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + } else { + ta_update = 31; + } - ta_len = (ta_update != 31) ? 2 : 0; + ta_len = (ta_update != 31) ? 2 : 0; // RLC data on DCCH if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { @@ -997,7 +980,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, #endif ); - sdu_lengths[0] = 0; + sdu_lengths[0] = 0; 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", @@ -1063,10 +1046,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } } - 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])); + 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", module_idP, CC_id, sdu_lengths[0]); @@ -1084,15 +1067,15 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, num_sdus = 1; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); + LOG_T(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[0]); - for (j = 0; j < sdu_lengths[0]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } + for (j = 0; j < sdu_lengths[0]; ++j) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif } } @@ -1122,10 +1105,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, #endif ); - 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 + 1), T_INT(sdu_lengths[num_sdus])); + 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 + 1), T_INT(sdu_lengths[num_sdus])); sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; @@ -1140,15 +1123,15 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, num_sdus++; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); + LOG_T(MAC, + "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[num_sdus]); - for (j = 0; j < sdu_lengths[num_sdus]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } + for (j = 0; j < sdu_lengths[num_sdus]; ++j) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif } @@ -1237,15 +1220,14 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, // Now compute number of required RBs for total sdu length // Assume RAH format 2 - mcs = eNB_UE_stats->dlsch_mcs1; + mcs = eNB_UE_stats->dlsch_mcs1; - if (mcs == 0) { - nb_rb = 4; // don't let the TBS get too small - } else { - nb_rb = min_rb_unit[CC_id]; - } - - TBS = get_TBS_DL(mcs, nb_rb); + if (mcs == 0) { + nb_rb = 4; // don't let the TBS get too small + } else { + nb_rb = min_rb_unit[CC_id]; + } + TBS = get_TBS_DL(mcs, nb_rb); while (TBS < sdu_length_total + header_length_total + ta_len) { nb_rb += min_rb_unit[CC_id]; // @@ -1257,33 +1239,31 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, break; } - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); - } + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + } - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } - } + if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + } - j = j + 1; - } - } + j = j + 1; + } + } // decrease mcs until TBS falls below required length while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { @@ -1301,16 +1281,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, TBS = get_TBS_DL(mcs, nb_rb); } - LOG_D(MAC, - "dlsch_mcs before and after the rate matching = (%d, %d)\n", - eNB_UE_stats->dlsch_mcs1, mcs); + LOG_D(MAC, + "dlsch_mcs before and after the rate matching = (%d, %d)\n", + eNB_UE_stats->dlsch_mcs1, mcs); #ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); + LOG_D(MAC, + "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { @@ -1321,12 +1301,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, 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 - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); + 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 + ta_update, // timing advance + NULL, // contention res id + padding, post_padding); //#ifdef DEBUG_eNB_SCHEDULER if (ta_update != 31) { @@ -1340,19 +1321,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } //#endif #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); + LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } + for (i = 0; i < 16; ++i) { + LOG_T(MAC, "%x.", dlsch_buffer[i]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], - dlsch_buffer, sdu_length_total); - // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + // cycle through SDUs and place in dlsch_buffer + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); + // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); // fill remainder of DLSCH with 0 for (j = 0; j < (TBS - sdu_length_total - offset); j++) { @@ -1376,14 +1356,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, T_INT(subframeP), T_INT(harq_pid), 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; + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; + add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); + // store stats + eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; + eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].num_mac_sdu_tx = num_sdus; @@ -1392,10 +1370,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; if (cc[CC_id].tdd_Config != NULL) { // TDD UE_list->UE_template[CC_id][UE_id].DAI++; @@ -1420,8 +1398,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; if (normalized_rx_power > (target_rx_power + 4)) { tpc = 0; //-1 @@ -1444,39 +1422,40 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, tpc = 1; //0 } - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = + get_aggregation(get_bw_index(module_idP, CC_id), ue_sched_ctl->dl_cqi[CC_id], format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - //deactivate second codeword - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), - mcs); - } else { - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", - module_idP, CC_id, harq_pid, mcs); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = + 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = + (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + mcs); + } else { + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP, CC_id, harq_pid, mcs); } @@ -1491,16 +1470,14 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - // Toggle NDI for next time - LOG_D(MAC, - "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP, subframeP, UE_id, rnti, - harq_pid, - UE_list-> - UE_template[CC_id][UE_id].oldNDI[harq_pid]); + // Toggle NDI for next time + LOG_D(MAC, + "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP, subframeP, UE_id, rnti, harq_pid, + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); 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; @@ -1551,14 +1528,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } } - if (cc[CC_id].tdd_Config != NULL) { // TDD - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + if (cc[CC_id].tdd_Config != NULL) { // TDD + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); } - } // UE_id loop } // CC_id loop - fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); stop_meas(&eNB->schedule_dlsch); diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 4f8510f49c..e6bb773c86 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -101,7 +101,7 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, sub_frame_t subframeP) { - int UE_id, i; + int UE_id, lcid; rnti_t rnti; mac_rlc_status_resp_t rlc_status; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; @@ -114,70 +114,64 @@ store_dlsch_buffer(module_id_t Mod_id, if (!ue_slice_membership(UE_id, slice_id)) continue; - UE_template = - &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; + UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; // clear logical channel interface variables UE_template->dl_buffer_total = 0; UE_template->dl_pdus_total = 0; - for (i = 0; i < MAX_NUM_LCID; i++) { - UE_template->dl_buffer_info[i] = 0; - UE_template->dl_pdus_in_buffer[i] = 0; - UE_template->dl_buffer_head_sdu_creation_time[i] = 0; - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0; + for (lcid = 0; lcid < MAX_NUM_LCID; ++lcid) { + UE_template->dl_buffer_info[lcid] = 0; + UE_template->dl_pdus_in_buffer[lcid] = 0; + UE_template->dl_buffer_head_sdu_creation_time[lcid] = 0; + UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid] = 0; } rnti = UE_RNTI(Mod_id, UE_id); - for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels + for (lcid = 0; lcid < MAX_NUM_LCID; ++lcid) { // loop over all the logical channels rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, - ENB_FLAG_YES, MBMS_FLAG_NO, i, 0 + ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); - UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel - UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; - UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time; + UE_template->dl_buffer_info[lcid] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel + UE_template->dl_pdus_in_buffer[lcid] = rlc_status.pdus_in_buffer; + UE_template->dl_buffer_head_sdu_creation_time[lcid] = rlc_status.head_sdu_creation_time; UE_template->dl_buffer_head_sdu_creation_time_max = cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time); - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = - rlc_status.head_sdu_remaining_size_to_send; - UE_template->dl_buffer_head_sdu_is_segmented[i] = - rlc_status.head_sdu_is_segmented; - UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer - UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[i]; + UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid] = rlc_status.head_sdu_remaining_size_to_send; + UE_template->dl_buffer_head_sdu_is_segmented[lcid] = rlc_status.head_sdu_is_segmented; + UE_template->dl_buffer_total += UE_template->dl_buffer_info[lcid]; //storing the total dlsch buffer + UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[lcid]; #ifdef DEBUG_eNB_SCHEDULER - /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : + /* note for dl_buffer_head_sdu_remaining_size_to_send[lcid] : * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent */ - if (UE_template->dl_buffer_info[i] > 0) + if (UE_template->dl_buffer_info[lcid] > 0) LOG_D(MAC, "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", Mod_id, slice_id, frameP, subframeP, UE_id, - i, UE_template->dl_pdus_in_buffer[i], - UE_template->dl_buffer_info[i], - UE_template->dl_buffer_head_sdu_creation_time[i], - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i], - UE_template->dl_buffer_head_sdu_is_segmented[i]); + lcid, UE_template->dl_pdus_in_buffer[lcid], + UE_template->dl_buffer_info[lcid], + UE_template->dl_buffer_head_sdu_creation_time[lcid], + UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid], + UE_template->dl_buffer_head_sdu_is_segmented[lcid]); #endif } - //#ifdef DEBUG_eNB_SCHEDULER if (UE_template->dl_buffer_total > 0) LOG_D(MAC, "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", Mod_id, frameP, subframeP, UE_id, UE_template->dl_buffer_total, UE_template->dl_pdus_total); - - //#endif } } From 56405aeef08bd2734888ff0d8980bac634c9f583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Fri, 9 Mar 2018 16:15:04 +0100 Subject: [PATCH 11/99] Implement interslice_multiplexing, add new constants --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 822 +++++++++++++--------- openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 4 + openair2/LAYER2/MAC/mac.h | 10 + openair2/LAYER2/MAC/mac_proto.h | 12 +- openair2/LAYER2/MAC/pre_processor.c | 24 +- openair2/RRC/LTE/rrc_extern.h | 2 +- openair2/RRC/LTE/rrc_vars.h | 2 +- 7 files changed, 527 insertions(+), 349 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index db9ec66ef7..44083a4610 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -68,18 +68,20 @@ extern RAN_CONTEXT_t RC; extern uint8_t nfapi_mode; +extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; +extern int slice_isolation[MAX_NUM_SLICES]; //------------------------------------------------------------------------------ void add_ue_dlsch_info(module_id_t module_idP, - int CC_id, - int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) + int CC_id, + int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) //------------------------------------------------------------------------------ { //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); + UE_RNTI(module_idP, UE_id); // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; @@ -91,7 +93,7 @@ add_ue_dlsch_info(module_id_t module_idP, //------------------------------------------------------------------------------ int schedule_next_dlue(module_id_t module_idP, int CC_id, - sub_frame_t subframeP) + sub_frame_t subframeP) //------------------------------------------------------------------------------ { @@ -101,7 +103,7 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, for (next_ue = UE_list->head; next_ue >= 0; next_ue = UE_list->next[next_ue]) { if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_WAITING) { + S_DL_WAITING) { return next_ue; } } @@ -113,21 +115,21 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, } } - return (-1); //next_ue; + return (-1); //next_ue; } //------------------------------------------------------------------------------ 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) + 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) //------------------------------------------------------------------------------ { @@ -185,10 +187,10 @@ generate_dlsch_header(unsigned char *mac_header, // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; AssertFatal(timing_advance_cmd < 64, - "timing_advance_cmd %d > 63\n", timing_advance_cmd); - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; + "timing_advance_cmd %d > 63\n", timing_advance_cmd); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); ce_ptr += sizeof(TIMING_ADVANCE_CMD); //msg("offset %d\n",ce_ptr-mac_header_control_elements); } @@ -213,9 +215,9 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 1; LOG_T(MAC, - "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", - ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], - ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); + "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], + ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); memcpy(ce_ptr, ue_cont_res_id, 6); ce_ptr += 6; @@ -225,7 +227,7 @@ generate_dlsch_header(unsigned char *mac_header, for (i = 0; i < num_sdus; i++) { LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", - num_sdus, sdu_lengths[i]); + num_sdus, sdu_lengths[i]); if (first_element > 0) { mac_header_ptr->E = 1; @@ -258,10 +260,10 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 3; #ifdef DEBUG_HEADER_PARSING LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); + "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); #endif } } @@ -283,7 +285,7 @@ generate_dlsch_header(unsigned char *mac_header, printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); } */ - if (post_padding > 0) { // we have lots of padding at the end of the packet + if (post_padding > 0) { // we have lots of padding at the end of the packet mac_header_ptr->E = 1; mac_header_ptr += last_size; // add a padding element @@ -291,7 +293,7 @@ generate_dlsch_header(unsigned char *mac_header, mac_header_ptr->E = 0; mac_header_ptr->LCID = SHORT_PADDING; mac_header_ptr++; - } else { // no end of packet padding + } else { // no end of packet padding // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) mac_header_ptr++; } @@ -301,9 +303,9 @@ generate_dlsch_header(unsigned char *mac_header, if ((ce_ptr - mac_header_control_elements) > 0) { // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); + ce_ptr - mac_header_control_elements); mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); + (unsigned char) (ce_ptr - mac_header_control_elements); } //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); @@ -313,7 +315,7 @@ generate_dlsch_header(unsigned char *mac_header, //------------------------------------------------------------------------------ void set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, - int subframeP) + int subframeP) //------------------------------------------------------------------------------ { @@ -321,132 +323,131 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, UE_list_t *UE_list = &eNB->UE_list; unsigned char DAI; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - if (cc->tdd_Config != NULL) { //TDD + if (cc->tdd_Config != NULL) { //TDD DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", - module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); + "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", + module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); // Save DAI for Format 0 DCI switch (cc->tdd_Config->subframeAssignment) { - case 0: - // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) - break; - - case 1: - switch (subframeP) { case 0: + // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) + break; + case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; - break; + switch (subframeP) { + case 0: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; + break; + + case 4: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + break; + + case 5: + case 6: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; + + case 9: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + } + + case 2: + // if ((subframeP==3)||(subframeP==8)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; + + case 3: + + //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { + // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; + //} + switch (subframeP) { + case 5: + case 6: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; + + case 7: + case 8: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + + case 9: + case 0: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; + break; + + default: + break; + } + + break; case 4: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + // if ((subframeP==8)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; break; case 5: - case 6: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + // if (subframeP==8) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; break; - case 9: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; - } - break; - - case 2: - // if ((subframeP==3)||(subframeP==8)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; - - case 3: - - //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { - // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; - //} - switch (subframeP) { - case 5: case 6: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; - - case 7: - case 8: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; - - case 9: - case 0: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; - break; + // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; default: - break; - } - - break; - - case 4: - // if ((subframeP==8)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; - - case 5: - // if (subframeP==8) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; - - case 6: - // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; - - default: - break; + break; } } } //------------------------------------------------------------------------------ void -schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) -{ +schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) { int i = 0; - slice_percentage_total=0; - slice_percentage_avg=1.0/n_active_slices; + slice_percentage_total = 0; + slice_percentage_avg = 1.0 / n_active_slices; + slice_counter = n_active_slices; // reset the slice percentage for inactive slices - for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { - slice_percentage[i]=0; + for (i = n_active_slices; i < MAX_NUM_SLICES; i++) { + slice_percentage[i] = 0; } for (i = 0; i < n_active_slices; i++) { - if (slice_percentage[i] < 0 ){ + if (slice_percentage[i] < 0) { LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", module_idP, frameP, subframeP, i, slice_percentage[i]); - slice_percentage[i]=0; + slice_percentage[i] = 0; } - slice_percentage_total+=slice_percentage[i]; + slice_percentage_total += slice_percentage[i]; } for (i = 0; i < n_active_slices; i++) { // Load any updated functions - if (update_dl_scheduler[i] > 0 ) { + if (update_dl_scheduler[i] > 0) { slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); - update_dl_scheduler[i] = 0 ; + update_dl_scheduler[i] = 0; update_dl_scheduler_current[i] = 0; - LOG_I(MAC,"update dl scheduler slice %d\n", i); + LOG_I(MAC, "update dl scheduler slice %d\n", i); } - if (slice_percentage_total <= 1.0){ // the new total RB share is within the range + if (slice_percentage_total <= 1.0) { // the new total RB share is within the range // check if the number of slices has changed, and log - if (n_active_slices_current != n_active_slices ){ + if (n_active_slices_current != n_active_slices) { if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { LOG_I(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); @@ -483,56 +484,58 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in // check if a new scheduler, and log the console if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - module_idP, i, frameP, subframeP, dl_scheduler_type[i]); - update_dl_scheduler_current[i] = update_dl_scheduler[i]; + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", + module_idP, i, frameP, subframeP, dl_scheduler_type[i]); + update_dl_scheduler_current[i] = update_dl_scheduler[i]; } } else { // here we can correct the values, e.g. reduce proportionally - if (n_active_slices == n_active_slices_current){ - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, slice_percentage_total_current, slice_percentage_total); - if (slice_percentage[i] >= slice_percentage_avg){ - slice_percentage[i]-=0.1; - slice_percentage_total-=0.1; - } + if (n_active_slices == n_active_slices_current) { + LOG_W(MAC, + "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", + module_idP, i, slice_percentage_total_current, slice_percentage_total); + if (slice_percentage[i] >= slice_percentage_avg) { + slice_percentage[i] -= 0.1; + slice_percentage_total -= 0.1; + } } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, slice_percentage_total_current, slice_percentage_total, - n_active_slices, n_active_slices_current ); - n_active_slices = n_active_slices_current; - slice_percentage[i] = slice_percentage_current[i]; + LOG_W(MAC, + "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", + module_idP, i, slice_percentage_total_current, slice_percentage_total, + n_active_slices, n_active_slices_current); + n_active_slices = n_active_slices_current; + slice_percentage[i] = slice_percentage_current[i]; } } // Check for new slice positions - if (slice_position[i*2] > slice_position[i*2 + 1] || - slice_position[i*2] < 0 || - slice_position[i*2 + 1] > N_RBG_MAX) { + if (slice_position[i * 2] > slice_position[i * 2 + 1] || + slice_position[i * 2] < 0 || + slice_position[i * 2 + 1] > N_RBG_MAX) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n", module_idP, i, - slice_position[i*2], slice_position[i*2 + 1], - slice_position_current[i*2], slice_position_current[i*2 + 1]); - slice_position[i*2] = slice_position_current[i*2]; - slice_position[i*2 + 1] = slice_position_current[i*2 + 1]; + slice_position[i * 2], slice_position[i * 2 + 1], + slice_position_current[i * 2], slice_position_current[i * 2 + 1]); + slice_position[i * 2] = slice_position_current[i * 2]; + slice_position[i * 2 + 1] = slice_position_current[i * 2 + 1]; } else { - if (slice_position_current[i*2] != slice_position[i*2]) { - LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", - module_idP, i, frameP, subframeP, slice_position_current[i*2], slice_position[i*2]); - slice_position_current[i*2] = slice_position[i*2]; + if (slice_position_current[i * 2] != slice_position[i * 2]) { + LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", + module_idP, i, frameP, subframeP, slice_position_current[i * 2], slice_position[i * 2]); + slice_position_current[i * 2] = slice_position[i * 2]; } - if (slice_position_current[i*2 + 1] != slice_position[i*2 + 1]) { - LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", - module_idP, i, frameP, subframeP, slice_position_current[i*2 + 1], slice_position[i*2 + 1]); - slice_position_current[i*2 + 1] = slice_position[i*2 + 1]; + if (slice_position_current[i * 2 + 1] != slice_position[i * 2 + 1]) { + LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", + module_idP, i, frameP, subframeP, slice_position_current[i * 2 + 1], slice_position[i * 2 + 1]); + slice_position_current[i * 2 + 1] = slice_position[i * 2 + 1]; } } // Check for new sorting policy if (slice_sorting_policy_current[i] != slice_sorting_policy[i]) { - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", module_idP, i, frameP, subframeP, slice_sorting_policy_current[i], slice_sorting_policy[i]); slice_sorting_policy_current[i] = slice_sorting_policy[i]; } @@ -540,11 +543,12 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in // Check for new accounting policy if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) { if (slice_accounting_policy[i] > 1 || slice_accounting_policy[i] < 0) { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", + LOG_W(MAC, + "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", module_idP, i, frameP, subframeP, slice_accounting_policy[i], slice_accounting_policy_current[i]); slice_accounting_policy[i] = slice_accounting_policy_current[i]; } else { - LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", + LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", module_idP, i, frameP, subframeP, slice_accounting_policy_current[i], slice_accounting_policy[i]); slice_accounting_policy_current[i] = slice_accounting_policy[i]; } @@ -589,10 +593,10 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, UE_sched_ctrl *ue_sched_ctl; int mcs; int i; - int min_rb_unit[MAX_NUM_CCs]; - int N_RB_DL[MAX_NUM_CCs]; - int total_nb_available_rb[MAX_NUM_CCs]; - int N_RBG[MAX_NUM_CCs]; + int min_rb_unit[NFAPI_CC_MAX]; + int N_RB_DL[NFAPI_CC_MAX]; + int total_nb_available_rb[NFAPI_CC_MAX]; + int N_RBG[NFAPI_CC_MAX]; nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_pdu_t *dl_config_pdu; int tdd_sfa; @@ -645,7 +649,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, } //weight = get_ue_weight(module_idP,UE_id); aggregation = 2; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); // get number of PRBs less those used by common channels @@ -678,7 +682,17 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + slice_counter--; + // Do the multiplexing and actual allocation only when all slices have been pre-processed. + if (slice_counter > 0) { + stop_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + return; + } + + dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP); + + for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; @@ -776,7 +790,8 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, if (nfapi_mode) { eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } else { // this operation is also done in the preprocessor - eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, + slice_maxmcs[slice_idP]); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } // Store stats @@ -1540,10 +1555,154 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); } +//------------------------------------------------------------------------------ +void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + // FIXME: I'm prototyping the algorithm, so there may be arrays and variables that carry redundant information here and in pre_processor_results struct. + + int UE_id, CC_id, rbg, i; + int N_RB_DL, min_rb_unit, tm; + int owned, used; + + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; + COMMON_channels_t *cc; + int N_RBG[NFAPI_CC_MAX]; + + int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX]; + int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES]; + uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + + uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB]; + uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB]; + uint8_t (*rballoc_sub)[N_RBG_MAX]; + uint8_t (*MIMO_mode_indicator)[N_RBG_MAX]; + + // Initialize the free RBGs map + // free_rbgs_map[CC_id][rbg] = -1 if RBG is allocated, + // otherwise it contains the id of the slice it belongs to. + // (Information about slicing must be retained to deal with isolation). + // FIXME: This method does not consider RBGs that are free and belong to no slices + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { + for (i = 0; i < n_active_slices; ++i) { + owned = pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; + if (owned) { + used = pre_processor_results[i].slice_allocated_rbgs[CC_id][rbg]; + free_rbgs_map[CC_id][rbg] = used ? -1 : i; + break; + } + } + } + } + + // Find out which slices need other resources. + // FIXME: I don't think is really needed since we check nb_rbs_remaining later + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (i = 0; i < n_active_slices; ++i) { + has_traffic[CC_id][i] = 0; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { + if (pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) { + has_traffic[CC_id][i] = 1; + break; + } + } + } + } + + // TODO: Sort slices by priority and use the sorted list in the code below (For now we assume 0 = max_priority) + + // MULTIPLEXING + // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + min_rb_unit = get_min_rb_unit(Mod_id, CC_id); + + for (i = 0; i < n_active_slices; ++i) { + + if (has_traffic[CC_id][i] == 0) continue; + + // Build an ad-hoc allocation mask fo the slice + for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { + if (free_rbgs_map[CC_id][rbg] == -1) { + // RBG is already allocated + allocation_mask[CC_id][rbg] = 0; + continue; + } + if (slice_isolation[free_rbgs_map[CC_id][rbg]] == 1) { + // RBG belongs to an isolated slice + allocation_mask[CC_id][rbg] = 0; + continue; + } + // RBG is free + allocation_mask[CC_id][rbg] = 1; + } + + // Sort UE again + // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point) + sort_UEs(Mod_id, (slice_id_t) i, frameP, subframeP); + + nb_rbs_remaining = pre_processor_results[i].nb_rbs_remaining; + nb_rbs_required = pre_processor_results[i].nb_rbs_required; + rballoc_sub = pre_processor_results[i].slice_allocated_rbgs; + MIMO_mode_indicator = pre_processor_results[i].MIMO_mode_indicator; + + // Allocation + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + tm = get_tmode(Mod_id, CC_id, UE_id); + + for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { + + // FIXME: I think that some of these checks are redundant + if (allocation_mask[CC_id][rbg] == 0) continue; + if (rballoc_sub[CC_id][rbg] != 0) continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] != 0) continue; + if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue; + + if ((rbg == N_RBG[CC_id] - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { + // Allocating last, smaller RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) { + rballoc_sub[CC_id][rbg] = 1; + free_rbgs_map[CC_id][rbg] = -1; + ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1; + MIMO_mode_indicator[CC_id][rbg] = 1; + if (tm == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; + } + } else { + // Allocating a standard-sized RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) { + rballoc_sub[CC_id][rbg] = 1; + free_rbgs_map[CC_id][rbg] = -1; + ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1; + MIMO_mode_indicator[CC_id][rbg] = 1; + if (tm == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; + } + } + } + } + } + } +} + //------------------------------------------------------------------------------ void fill_DLSCH_dci(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) //------------------------------------------------------------------------------ { @@ -1567,9 +1726,9 @@ fill_DLSCH_dci(module_id_t module_idP, start_meas(&eNB->fill_DLSCH_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); + (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); if (mbsfn_flagP[CC_id] > 0) @@ -1581,42 +1740,43 @@ fill_DLSCH_dci(module_id_t module_idP, // UE specific DCIs for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { + UE_id = UE_list->next[UE_id]) { LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, - eNB_dlsch_info[module_idP][CC_id][UE_id].status); + eNB_dlsch_info[module_idP][CC_id][UE_id].status); if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag - eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; - rnti = UE_RNTI(module_idP, UE_id); + // clear scheduling flag + eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; + rnti = UE_RNTI(module_idP, UE_id); harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - /// Synchronizing rballoc with rballoc_sub - for (i = 0; i < N_RBG; i++) { - rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; - } + /// Synchronizing rballoc with rballoc_sub + for (i = 0; i < N_RBG; i++) { + rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; + } - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; - nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_pdu_t *dl_config_pdu; - for (i = 0; - i < DL_req[CC_id].dl_config_request_body.number_pdu; - i++) { - dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; - if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; - } else - if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); - } - } + for (i = 0; + i < DL_req[CC_id].dl_config_request_body.number_pdu; + i++) { + dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, + rballoc_sub); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; + } else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, + rballoc_sub); + } + } } } @@ -1628,8 +1788,8 @@ fill_DLSCH_dci(module_id_t module_idP, //------------------------------------------------------------------------------ unsigned char *get_dlsch_sdu(module_id_t module_idP, - int CC_id, frame_t frameP, rnti_t rntiP, - uint8_t TBindex) + int CC_id, frame_t frameP, rnti_t rntiP, + uint8_t TBindex) //------------------------------------------------------------------------------ { @@ -1638,28 +1798,28 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, if (rntiP == SI_RNTI) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", - module_idP, CC_id, frameP); + module_idP, CC_id, frameP); return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]); } - if (rntiP==P_RNTI) { - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); + if (rntiP == P_RNTI) { + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); - return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); + return ((unsigned char *) &eNB->common_channels[CC_id].PCCH_pdu.payload[0]); } - UE_id = find_UE_id(module_idP,rntiP); + UE_id = find_UE_id(module_idP, rntiP); if (UE_id != -1) { LOG_D(MAC, - "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", - module_idP, frameP, CC_id, rntiP, UE_id); + "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", + module_idP, frameP, CC_id, rntiP, UE_id); return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); } else { LOG_E(MAC, - "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", - module_idP, frameP, CC_id, rntiP); + "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", + module_idP, frameP, CC_id, rntiP); return NULL; } @@ -1676,7 +1836,7 @@ update_ul_dci(module_id_t module_idP, nfapi_hi_dci0_request_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; int i; @@ -1687,8 +1847,8 @@ update_ul_dci(module_id_t module_idP, i++) { if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; } } @@ -1698,84 +1858,83 @@ update_ul_dci(module_id_t module_idP, //------------------------------------------------------------------------------ void set_ue_dai(sub_frame_t subframeP, - int UE_id, uint8_t CC_id, uint8_t tdd_config, - UE_list_t * UE_list) + int UE_id, uint8_t CC_id, uint8_t tdd_config, + UE_list_t *UE_list) //------------------------------------------------------------------------------ { switch (tdd_config) { - case 0: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) - || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + case 0: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) + || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 1: + if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) + || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 2: + if ((subframeP == 4) || (subframeP == 5)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 3: + if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 4: + if ((subframeP == 0) || (subframeP == 6)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 5: + if (subframeP == 9) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 6: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) + || (subframeP == 6) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + default: UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 1: - if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) - || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 2: - if ((subframeP == 4) || (subframeP == 5)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 3: - if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 4: - if ((subframeP == 0) || (subframeP == 6)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 5: - if (subframeP == 9) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 6: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) - || (subframeP == 6) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - default: - UE_list->UE_template[CC_id][UE_id].DAI = 0; - LOG_I(MAC, "unknow TDD config %d\n", tdd_config); - break; + LOG_I(MAC, "unknown TDD config %d\n", tdd_config); + break; } } -void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) -{ +void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { /* DCI:format 1A/1C P-RNTI:0xFFFE */ /* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */ - uint16_t pcch_sdu_length; - int mcs = -1; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - uint8_t *vrb_map; - int n_rb_dl; - int first_rb = -1; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; + uint16_t pcch_sdu_length; + int mcs = -1; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int n_rb_dl; + int first_rb = -1; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; nfapi_dl_config_request_body_t *dl_req; #ifdef FORMAT1C int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ @@ -1799,9 +1958,9 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) start_meas(&eNB->schedule_pch); - for (CC_id=0; CC_idcommon_channels[CC_id]; - vrb_map = (void*)&cc->vrb_map; + vrb_map = (void *) &cc->vrb_map; n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { @@ -1809,17 +1968,18 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) continue; } if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { - pcch_sdu_length = mac_rrc_data_req(module_idP, + pcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, - PCCH,1, + PCCH, 1, &cc->PCCH_pdu.payload[0], i); // used for ue index - if (pcch_sdu_length == 0) { - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); - continue; - } - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); + if (pcch_sdu_length == 0) { + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP, frameP, subframeP); + continue; + } + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, + frameP, subframeP, CC_id, i, pcch_sdu_length); #ifdef FORMAT1C //NO SIB if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || @@ -1944,65 +2104,65 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) } } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= get_TBS_DL(0,3)) { - mcs=0; - } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { - mcs=1; - } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { - mcs=2; - } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { - mcs=3; - } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { - mcs=4; - } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { - mcs=5; - } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { - mcs=6; - } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { - mcs=7; - } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { - mcs=8; - } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { - mcs=9; - } + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= get_TBS_DL(0, 3)) { + mcs = 0; + } else if (pcch_sdu_length <= get_TBS_DL(1, 3)) { + mcs = 1; + } else if (pcch_sdu_length <= get_TBS_DL(2, 3)) { + mcs = 2; + } else if (pcch_sdu_length <= get_TBS_DL(3, 3)) { + mcs = 3; + } else if (pcch_sdu_length <= get_TBS_DL(4, 3)) { + mcs = 4; + } else if (pcch_sdu_length <= get_TBS_DL(5, 3)) { + mcs = 5; + } else if (pcch_sdu_length <= get_TBS_DL(6, 3)) { + mcs = 6; + } else if (pcch_sdu_length <= get_TBS_DL(7, 3)) { + mcs = 7; + } else if (pcch_sdu_length <= get_TBS_DL(8, 3)) { + mcs = 8; + } else if (pcch_sdu_length <= get_TBS_DL(9, 3)) { + mcs = 9; + } #endif - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); #ifdef FORMAT1C - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; #else - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; #endif - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - // Rel10 fields + // Rel10 fields #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; #endif - // Rel13 fields + // Rel13 fields #if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; #endif if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { @@ -2020,12 +2180,12 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; #ifdef FORMAT1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); #else - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized #endif dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h index 8a5422a890..8bd227645c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -40,6 +40,7 @@ // number of active slices for past and current time int n_active_slices = 1; int n_active_slices_current = 1; +int slice_counter = 0; // RB share for each slice for past and current time float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; @@ -47,6 +48,7 @@ float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_total = 0; float slice_percentage_total_current = 0; float slice_percentage_avg = 0.25; +int slice_isolation[MAX_NUM_SLICES] = {0, 0, 0, 0}; // Frequency ranges for slice positioning int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; @@ -78,4 +80,6 @@ char *dl_scheduler_type[MAX_NUM_SLICES] = // pointer to the slice specific scheduler slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; +pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; + #endif //__LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index f8121310b1..7bc73e11b9 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1571,6 +1571,16 @@ typedef struct { mui_t rrc_mui[128]; }mac_rlc_am_muilist_t; +/// Structure for saving the output of each pre_processor instance +typedef struct { + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; +} pre_processor_results_t; + #include "mac_proto.h" /*@}*/ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 23d7fb49d7..56bf7a25d4 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -226,8 +226,8 @@ void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], int *mbsfn_flag); void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, @@ -260,6 +260,10 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); +void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP); + void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int UE_id, uint8_t CC_id, @@ -267,9 +271,9 @@ void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int min_rb_unit, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f. diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e6bb773c86..73f9724c8a 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -61,7 +61,7 @@ extern uint32_t slice_sorting_policy[MAX_NUM_SLICES]; extern int slice_accounting_policy[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; - +extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; //#define ICIC 0 @@ -977,7 +977,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, int UE_id, CC_id; int i; uint8_t transmission_mode; - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t (*slice_allocation_mask)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocation_mask; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; int N_RBG[NFAPI_CC_MAX]; @@ -1205,13 +1205,13 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, uint8_t CC_id; uint16_t i, j; - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting - int min_rb_unit[NFAPI_CC_MAX]; - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + + uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_required; + uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_accounted; + uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_remaining; + uint8_t (*rballoc_sub)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocated_rbgs; + uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = pre_processor_results[slice_id].MIMO_mode_indicator; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -1354,8 +1354,8 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], int *mbsfn_flag) { @@ -1579,9 +1579,9 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int min_rb_unit, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { int i; int tm = get_tmode(Mod_id, CC_id, UE_id); diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h index 6c19fa9c70..59200fb9cc 100644 --- a/openair2/RRC/LTE/rrc_extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -75,7 +75,7 @@ extern uint32_t timeToTrigger_ms[16]; extern float RSRP_meas_mapping[98]; extern float RSRQ_meas_mapping[35]; -extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; +extern UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; extern pthread_mutex_t ue_pf_po_mutex; extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2]; diff --git a/openair2/RRC/LTE/rrc_vars.h b/openair2/RRC/LTE/rrc_vars.h index 8a71858101..028a59f7d9 100644 --- a/openair2/RRC/LTE/rrc_vars.h +++ b/openair2/RRC/LTE/rrc_vars.h @@ -36,7 +36,7 @@ #include "COMMON/mac_rrc_primitives.h" #include "LAYER2/MAC/mac.h" -UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; +UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; pthread_mutex_t ue_pf_po_mutex; UE_RRC_INST *UE_rrc_inst; #include "LAYER2/MAC/mac_extern.h" From 5634aa92a1a8549e697d77d781cc2d1fdc9099bc Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Mon, 12 Mar 2018 16:39:00 +0100 Subject: [PATCH 12/99] Keep the LCID priority in MAC layer to sort the UE accordingly --- openair2/LAYER2/MAC/config.c | 17 +++++++++++------ openair2/LAYER2/MAC/mac.h | 3 +++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 8fd85e7811..a7bf532b09 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -852,16 +852,21 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); } else { - if (logicalChannelConfig) + if (logicalChannelConfig) { UE_list-> UE_template[CC_idP][UE_id].lcgidmap [logicalChannelIdentity] = *logicalChannelConfig-> - ul_SpecificParameters->logicalChannelGroup; - else - UE_list-> - UE_template[CC_idP][UE_id].lcgidmap - [logicalChannelIdentity] = 0; + ul_SpecificParameters->logicalChannelGroup; + UE_list-> + UE_template[CC_idP][UE_id].lcgidpriority + [logicalChannelIdentity]= + logicalChannelConfig->ul_SpecificParameters->priority; + + } else + UE_list-> + UE_template[CC_idP][UE_id].lcgidmap + [logicalChannelIdentity] = 0; } } diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 7bc73e11b9..8fa2e3bdc9 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -849,6 +849,9 @@ typedef struct { /// LCGID mapping long lcgidmap[11]; + ///UE logical channel priority + long lcgidpriority[11]; + /// phr information int8_t phr_info; From 8d9a8ab59a40cf4aa73bf464ddb2184d519bb530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Tue, 13 Mar 2018 15:22:14 +0100 Subject: [PATCH 13/99] Add UE sorting on LCID priority --- openair2/COMMON/platform_types.h | 3 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 104 ++++++++++++++++++---- openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 12 ++- openair2/LAYER2/MAC/mac_proto.h | 6 ++ openair2/LAYER2/MAC/pre_processor.c | 33 +++++-- 5 files changed, 132 insertions(+), 26 deletions(-) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 3f736e5b3c..a94d785bee 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -110,7 +110,8 @@ typedef enum { CR_HOL = 2, CR_LC = 3, CR_CQI = 4, - CR_NUM = 5 + CR_LCP = 5, + CR_NUM = 6 } sorting_criterion_t; //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 44083a4610..472c4e2a11 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -70,6 +70,7 @@ extern RAN_CONTEXT_t RC; extern uint8_t nfapi_mode; extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; extern int slice_isolation[MAX_NUM_SLICES]; +extern int slice_priority[MAX_NUM_SLICES]; //------------------------------------------------------------------------------ void @@ -534,23 +535,44 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in } // Check for new sorting policy - if (slice_sorting_policy_current[i] != slice_sorting_policy[i]) { + if (slice_sorting_current[i] != slice_sorting[i]) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_sorting_policy_current[i], slice_sorting_policy[i]); - slice_sorting_policy_current[i] = slice_sorting_policy[i]; + module_idP, i, frameP, subframeP, slice_sorting_current[i], slice_sorting[i]); + slice_sorting_current[i] = slice_sorting[i]; + } + + // Check for new slice isolation + if (slice_isolation_current[i] != slice_isolation[i]) { + if (slice_isolation[i] != 1 && slice_isolation[i] != 0) { + LOG_W(MAC, + "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid slice isolation setting (%d), revert to its previous value (%d)\n", + module_idP, i, frameP, subframeP, slice_isolation[i], slice_isolation_current[i]); + slice_isolation[i] = slice_isolation_current[i]; + } else { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice isolation setting has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, slice_isolation_current[i], slice_isolation[i]); + slice_isolation_current[i] = slice_isolation[i]; + } + } + + // Check for new slice priority + if (slice_priority_current[i] != slice_priority[i]) { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, slice_priority_current[i], slice_priority[i]); + slice_priority_current[i] = slice_priority[i]; } // Check for new accounting policy - if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) { - if (slice_accounting_policy[i] > 1 || slice_accounting_policy[i] < 0) { + if (slice_accounting_current[i] != slice_accounting[i]) { + if (slice_accounting[i] > 1 || slice_accounting[i] < 0) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, slice_accounting_policy[i], slice_accounting_policy_current[i]); - slice_accounting_policy[i] = slice_accounting_policy_current[i]; + module_idP, i, frameP, subframeP, slice_accounting[i], slice_accounting_current[i]); + slice_accounting[i] = slice_accounting_current[i]; } else { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_accounting_policy_current[i], slice_accounting_policy[i]); - slice_accounting_policy_current[i] = slice_accounting_policy[i]; + module_idP, i, frameP, subframeP, slice_accounting_current[i], slice_accounting[i]); + slice_accounting_current[i] = slice_accounting[i]; } } @@ -1570,6 +1592,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub COMMON_channels_t *cc; int N_RBG[NFAPI_CC_MAX]; + int slice_sorted_list[MAX_NUM_SLICES], slice_id; int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX]; int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES]; uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; @@ -1613,7 +1636,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub } } - // TODO: Sort slices by priority and use the sorted list in the code below (For now we assume 0 = max_priority) + slice_priority_sort(slice_sorted_list); // MULTIPLEXING // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code @@ -1623,8 +1646,9 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub min_rb_unit = get_min_rb_unit(Mod_id, CC_id); for (i = 0; i < n_active_slices; ++i) { + slice_id = slice_sorted_list[i]; - if (has_traffic[CC_id][i] == 0) continue; + if (has_traffic[CC_id][slice_id] == 0) continue; // Build an ad-hoc allocation mask fo the slice for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { @@ -1644,12 +1668,13 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub // Sort UE again // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point) - sort_UEs(Mod_id, (slice_id_t) i, frameP, subframeP); + // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it + sort_UEs(Mod_id, (slice_id_t) slice_id, frameP, subframeP); - nb_rbs_remaining = pre_processor_results[i].nb_rbs_remaining; - nb_rbs_required = pre_processor_results[i].nb_rbs_required; - rballoc_sub = pre_processor_results[i].slice_allocated_rbgs; - MIMO_mode_indicator = pre_processor_results[i].MIMO_mode_indicator; + nb_rbs_remaining = pre_processor_results[slice_id].nb_rbs_remaining; + nb_rbs_required = pre_processor_results[slice_id].nb_rbs_required; + rballoc_sub = pre_processor_results[slice_id].slice_allocated_rbgs; + MIMO_mode_indicator = pre_processor_results[slice_id].MIMO_mode_indicator; // Allocation for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { @@ -1699,6 +1724,32 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub } } +//------------------------------------------------------------------------------ +void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + int UE_id, CC_id, i; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; ++CC_id) { + for (i = 0; i < n_active_slices; ++i) { + + // Sort UE again + // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it + sort_UEs(Mod_id, (slice_id_t) i, frameP, subframeP); + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + // TODO: Do something here + ue_sched_ctl->pre_nb_available_rbs[CC_id]; + } + } + } +} + + //------------------------------------------------------------------------------ void fill_DLSCH_dci(module_id_t module_idP, @@ -2252,3 +2303,24 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) stop_meas(&eNB->schedule_pch); return; } + +static int slice_priority_compare(const void *_a, const void *_b) { + + int slice_id1 = *(const int *) _a; + int slice_id2 = *(const int *) _b; + + if (slice_priority[slice_id1] > slice_priority[slice_id2]) { + return -1; + } + return 1; +} + +void slice_priority_sort(int slice_list[MAX_NUM_SLICES]) { + + int i; + for (i = 0; i < MAX_NUM_SLICES; ++i) { + slice_list[i] = i; + } + + qsort(slice_list, MAX_NUM_SLICES, sizeof(int), slice_priority_compare); +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h index 8bd227645c..321f83c20d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -48,7 +48,11 @@ float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_total = 0; float slice_percentage_total_current = 0; float slice_percentage_avg = 0.25; + int slice_isolation[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_isolation_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_priority[MAX_NUM_SLICES] = {10, 5, 2, 0}; +int slice_priority_current[MAX_NUM_SLICES] = {10, 5, 2, 0}; // Frequency ranges for slice positioning int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; @@ -59,12 +63,12 @@ int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; // The lists of criteria that enforce the sorting policies of the slices -uint32_t slice_sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; -uint32_t slice_sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; +uint32_t slice_sorting[MAX_NUM_SLICES] = {0x012345, 0x012345, 0x012345, 0x012345}; +uint32_t slice_sorting_current[MAX_NUM_SLICES] = {0x012345, 0x012345, 0x012345, 0x012345}; // Accounting policy (just greedy(1) or fair(0) setting for now) -int slice_accounting_policy[MAX_NUM_SLICES] = {0, 0, 0, 0}; -int slice_accounting_policy_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_accounting[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_accounting_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 56bf7a25d4..98b6c8fbe0 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -260,10 +260,16 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); +void slice_priority_sort(int slice_list[MAX_NUM_SLICES]); + void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP); +void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP); + void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int UE_id, uint8_t CC_id, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 73f9724c8a..48987d785e 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -57,8 +57,8 @@ extern RAN_CONTEXT_t RC; extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES]; extern int slice_position[MAX_NUM_SLICES*2]; -extern uint32_t slice_sorting_policy[MAX_NUM_SLICES]; -extern int slice_accounting_policy[MAX_NUM_SLICES]; +extern uint32_t slice_sorting[MAX_NUM_SLICES]; +extern int slice_accounting[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; @@ -315,6 +315,20 @@ int maxcqi(module_id_t Mod_id, int32_t UE_id) { return CQI; } +long min_lcgidpriority(module_id_t Mod_id, int32_t UE_id) { + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int i; + int pCC_id = UE_PCCID(Mod_id, UE_id); + long ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[0]; + + for (i = 1; i < 11; ++i) { + if (UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i] < ret) + ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i]; + } + + return ret; +} + struct sort_ue_dl_params { int Mod_idP; int frameP; @@ -343,6 +357,9 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) int cqi1 = maxcqi(params->Mod_idP, UE_id1); int cqi2 = maxcqi(params->Mod_idP, UE_id2); + long lcgid1 = min_lcgidpriority(params->Mod_idP, UE_id1); + long lcgid2 = min_lcgidpriority(params->Mod_idP, UE_id2); + for (i = 0; i < CR_NUM; ++i) { switch (UE_list->sorting_criteria[slice_id][i]) { @@ -390,6 +407,12 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) if (cqi1 < cqi2) return 1; + case CR_LCP : + if (lcgid1 < lcgid2) + return -1; + if (lcgid1 > lcgid2) + return 1; + default : break; } @@ -402,7 +425,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { int i; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - uint32_t policy = slice_sorting_policy[slice_id]; + uint32_t policy = slice_sorting[slice_id]; uint32_t mask = 0x0000000F; uint16_t criterion; @@ -410,7 +433,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); if (criterion >= CR_NUM) { LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); - slice_sorting_policy[slice_id] = 0x1234; + slice_sorting[slice_id] = 0x1234; break; } UE_list->sorting_criteria[slice_id][i] = criterion; @@ -649,7 +672,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Reduces the available RBs according to slicing configuration dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); - switch (slice_accounting_policy[slice_id]) { + switch (slice_accounting[slice_id]) { // If greedy scheduling, try to account all the required RBs case 1: From 9efd5d6f27c8a436c036a89df219a39ce620e4b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Thu, 22 Mar 2018 14:17:07 +0100 Subject: [PATCH 14/99] Inter/intra-slice sharing are now optional --- openair2/COMMON/platform_types.h | 5 +++ openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 34 +++++++++++++++++++-- openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 5 +++ openair2/LAYER2/MAC/mac.h | 4 +++ openair2/LAYER2/MAC/pre_processor.c | 37 ++++++++++++++++------- 5 files changed, 72 insertions(+), 13 deletions(-) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index a94d785bee..b641475864 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -114,6 +114,11 @@ typedef enum { CR_NUM = 6 } sorting_criterion_t; +typedef enum { + POL_FAIR = 0, + POL_GREEDY = 1, + POL_NUM = 2 +} accounting_policy_t; //----------------------------------------------------------------------------- // PHY TYPES //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 472c4e2a11..a03f95c47f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -435,6 +435,34 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in slice_percentage_total += slice_percentage[i]; } + // Check for *intra*slice share activation + if (intraslice_share_active_current != intraslice_share_active) { + if (intraslice_share_active != 1 && intraslice_share_active != 0) { + LOG_W(MAC, + "[eNB %d][DL] frame %d subframe %d: invalid intraslice sharing status (%d), revert to its previous value (%d)\n", + module_idP, i, frameP, subframeP, intraslice_share_active, intraslice_share_active_current); + intraslice_share_active = intraslice_share_active_current; + } else { + LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: intraslice sharing status has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, intraslice_share_active_current, intraslice_share_active); + intraslice_share_active_current = intraslice_share_active; + } + } + + // Check for *inter*slice share activation + if (interslice_share_active_current != interslice_share_active) { + if (interslice_share_active != 1 && interslice_share_active != 0) { + LOG_W(MAC, + "[eNB %d][DL] frame %d subframe %d: invalid interslice sharing status (%d), revert to its previous value (%d)\n", + module_idP, i, frameP, subframeP, interslice_share_active, interslice_share_active_current); + interslice_share_active = interslice_share_active_current; + } else { + LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: interslice sharing status has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, interslice_share_active_current, interslice_share_active); + interslice_share_active_current = interslice_share_active; + } + } + for (i = 0; i < n_active_slices; i++) { // Load any updated functions @@ -712,7 +740,9 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, return; } - dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP); + if (interslice_share_active) { + dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP); + } for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); @@ -1732,7 +1762,7 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; - for (CC_id = 0; CC_id < MAX_NUM_CCs; ++CC_id) { + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (i = 0; i < n_active_slices; ++i) { // Sort UE again diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h index 321f83c20d..e2aac32bf0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -42,6 +42,11 @@ int n_active_slices = 1; int n_active_slices_current = 1; int slice_counter = 0; +int intraslice_share_active = 1; +int intraslice_share_active_current = 1; +int interslice_share_active = 1; +int interslice_share_active_current = 1; + // RB share for each slice for past and current time float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 8fa2e3bdc9..d8fe034183 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1582,6 +1582,10 @@ typedef struct { uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX]; uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; + + uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID]; + uint32_t wb_pmi[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; + uint8_t mcs[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; } pre_processor_results_t; #include "mac_proto.h" diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 48987d785e..d04d89f7b1 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -63,6 +63,8 @@ extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; +extern int intraslice_share_active; + //#define ICIC 0 /* this function checks that get_eNB_UE_stats returns @@ -164,6 +166,7 @@ store_dlsch_buffer(module_id_t Mod_id, #endif + } if (UE_template->dl_buffer_total > 0) @@ -204,7 +207,8 @@ assign_rbs_required(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[n][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], slice_maxmcs[slice_id]); +// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], slice_maxmcs[slice_id]); + eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), slice_maxmcs[slice_id]); } @@ -266,6 +270,8 @@ assign_rbs_required(module_id_t Mod_id, Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats->dlsch_mcs1); + + pre_processor_results[slice_id].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; } } } @@ -646,7 +652,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; - // TODO Can we use subframe2harqpid() here? + // FIXME: Can we use subframe2harqpid() here? if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10; else @@ -675,7 +681,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, switch (slice_accounting[slice_id]) { // If greedy scheduling, try to account all the required RBs - case 1: + case POL_GREEDY: for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; @@ -691,6 +697,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Use the old, fair algorithm // Loop over all active UEs and account the avg number of RBs to each UE, based on all non-retx UEs. + // case POL_FAIR: default: // FIXME: This is not ideal, why loop on UEs to find average_rbs_per_user[], that is per-CC? // TODO: Look how to loop on active CCs only without using the UE_num_active_CC() function. @@ -1252,12 +1259,14 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, #endif // Initialize scheduling information for all active UEs + memset(&pre_processor_results[slice_id], 0, sizeof(pre_processor_results)); + // FIXME: After the memset above, some of the resets in reset() are redundant dlsch_scheduler_pre_processor_reset(Mod_id, slice_id, frameP, subframeP, min_rb_unit, nb_rbs_required, rballoc_sub, MIMO_mode_indicator, - mbsfn_flag); // TODO Not sure if useful + mbsfn_flag); // FIXME: Not sure if useful // STATUS // Store the DLSCH buffer for each logical channel @@ -1289,13 +1298,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // SHARING // If there are available RBs left in the slice, allocate them to the highest priority UEs - dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_id, - min_rb_unit, - nb_rbs_required, - nb_rbs_accounted, - nb_rbs_remaining, - rballoc_sub, - MIMO_mode_indicator); + if (intraslice_share_active) { + dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_id, + min_rb_unit, + nb_rbs_required, + nb_rbs_accounted, + nb_rbs_remaining, + rballoc_sub, + MIMO_mode_indicator); + } #ifdef TM5 // This has to be revisited!!!! @@ -2075,3 +2086,7 @@ void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP) UE_list->head_ul = -1; } } + +int cqi2mcs(int cqi) { + return cqi_to_mcs[cqi]; +} From 853ef6fe185122a1d977f4a5d9b53613aac685bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Tue, 27 Mar 2018 15:31:29 +0200 Subject: [PATCH 15/99] Fix warnings in schedule_dlsch --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index a03f95c47f..a8703050f3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -440,11 +440,11 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (intraslice_share_active != 1 && intraslice_share_active != 0) { LOG_W(MAC, "[eNB %d][DL] frame %d subframe %d: invalid intraslice sharing status (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, intraslice_share_active, intraslice_share_active_current); + module_idP, frameP, subframeP, intraslice_share_active, intraslice_share_active_current); intraslice_share_active = intraslice_share_active_current; } else { LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: intraslice sharing status has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, intraslice_share_active_current, intraslice_share_active); + module_idP, frameP, subframeP, intraslice_share_active_current, intraslice_share_active); intraslice_share_active_current = intraslice_share_active; } } @@ -454,11 +454,11 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (interslice_share_active != 1 && interslice_share_active != 0) { LOG_W(MAC, "[eNB %d][DL] frame %d subframe %d: invalid interslice sharing status (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, interslice_share_active, interslice_share_active_current); + module_idP, frameP, subframeP, interslice_share_active, interslice_share_active_current); interslice_share_active = interslice_share_active_current; } else { LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: interslice sharing status has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, interslice_share_active_current, interslice_share_active); + module_idP, frameP, subframeP, interslice_share_active_current, interslice_share_active); interslice_share_active_current = interslice_share_active; } } @@ -1773,7 +1773,7 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; // TODO: Do something here - ue_sched_ctl->pre_nb_available_rbs[CC_id]; + // ue_sched_ctl->pre_nb_available_rbs[CC_id]; } } } From e6168667d3cb9e3136d586305e20236b374846ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Fri, 6 Apr 2018 11:57:18 +0200 Subject: [PATCH 16/99] Add first_rb_offset --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 66 +++++++++++++++-------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.h | 3 ++ openair2/LAYER2/MAC/mac.h | 1 + openair2/LAYER2/MAC/pre_processor.c | 43 +++++++++------ 4 files changed, 75 insertions(+), 38 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 7c06a52909..fffc1a2209 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -401,10 +401,10 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[bsr]; UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); @@ -435,10 +435,10 @@ rx_sdu(const module_id_t enb_mod_idP, int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); int bsr3 = payload_ptr[2] & 0x3F; - lcgid_updated[0] = 1; - lcgid_updated[1] = 1; - lcgid_updated[2] = 1; - lcgid_updated[3] = 1; + lcgid_updated[LCGID0] = 1; + lcgid_updated[LCGID1] = 1; + lcgid_updated[LCGID2] = 1; + lcgid_updated[LCGID3] = 1; // update buffer info UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; @@ -447,10 +447,10 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; LOG_D(MAC, @@ -920,7 +920,7 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - uint16_t first_rb[MAX_NUM_CCs], i; + uint16_t first_rb[NFAPI_CC_MAX], i; int CC_id; eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc; @@ -1005,7 +1005,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } if (sched_subframe < subframeP) sched_frame++; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { @@ -1104,6 +1104,18 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } } + if (slice_first_rb_current[i] != slice_first_rb[i]){ + if (slice_first_rb[i] >= 0){ // FIXME: Max limit is checked in the scheduler + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice first rb has changed: %d-->%d\n", + module_idP, i, frameP, subframeP, slice_first_rb_current[i], slice_first_rb[i]); + slice_first_rb_current[i] = slice_first_rb[i]; + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice first rb %d, revert the previous value %d\n", + module_idP, i, slice_first_rb[i],slice_first_rb_current[i]); + slice_first_rb[i] = slice_first_rb_current[i]; + } + } + // check if a new scheduler, and log the console if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", @@ -1166,6 +1178,7 @@ schedule_ulsch_rnti(module_id_t module_idP, int rvidx_tab[4] = { 0, 2, 3, 1 }; uint16_t ul_req_index; uint8_t dlsch_flag; + int first_rb_slice[NFAPI_CC_MAX]; if (sched_subframeP < subframeP) sched_frame++; @@ -1177,9 +1190,18 @@ schedule_ulsch_rnti(module_id_t module_idP, nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; + + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); + UE_list->first_rb_offset[CC_id][slice_id] = cmin(N_RB_UL, slice_first_rb[slice_id]); + } + //LOG_D(MAC, "entering ulsch preprocesor\n"); ulsch_scheduler_pre_processor(module_idP, slice_id, frameP, subframeP, sched_subframeP, first_rb); + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_id]; + } //LOG_D(MAC, "exiting ulsch preprocesor\n"); hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; @@ -1265,7 +1287,7 @@ schedule_ulsch_rnti(module_id_t module_idP, } /* be sure that there are some free RBs */ - if (first_rb[CC_id] >= N_RB_UL - 1) { + if (first_rb_slice[CC_id] >= N_RB_UL - 1) { LOG_W(MAC, "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", module_idP, frameP, subframeP, UE_id, rnti, CC_id); @@ -1390,7 +1412,7 @@ schedule_ulsch_rnti(module_id_t module_idP, // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index] > (N_RB_UL - 1 - first_rb[CC_id])) + while (((rb_table[rb_table_index] > (N_RB_UL - 1 - first_rb_slice[CC_id])) || (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) { rb_table_index--; @@ -1407,7 +1429,7 @@ schedule_ulsch_rnti(module_id_t module_idP, T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), + T_INT(first_rb_slice[CC_id]), T_INT(rb_table[rb_table_index]), T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); @@ -1417,14 +1439,14 @@ schedule_ulsch_rnti(module_id_t module_idP, module_idP, harq_pid, rnti, CC_id, frameP, subframeP, UE_id, UE_template->mcs_UL[harq_pid], - first_rb[CC_id], rb_table[rb_table_index], + first_rb_slice[CC_id], rb_table[rb_table_index], rb_table_index, UE_template->TBS_UL[harq_pid], harq_pid); // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) //store for possible retransmission UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + UE_template->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); if (UE_id == UE_list->head) @@ -1456,7 +1478,7 @@ schedule_ulsch_rnti(module_id_t module_idP, hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; @@ -1554,13 +1576,13 @@ schedule_ulsch_rnti(module_id_t module_idP, LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); // increment first rb for next UE allocation - first_rb[CC_id] += rb_table[rb_table_index]; + first_rb_slice[CC_id] += rb_table[rb_table_index]; } else { // round > 0 => retransmission T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), + T_INT(first_rb_slice[CC_id]), T_INT(rb_table[rb_table_index]), T_INT(round)); // Add UL_config PDUs diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h index 45d7a4e709..517c13b1f3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h @@ -52,6 +52,9 @@ float total_slice_percentage_current_uplink = 0; int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20}; int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20}; +int slice_first_rb[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_first_rb_current[MAX_NUM_SLICES] = {0,0,0,0}; + /*resource blocks allowed*/ uint16_t nb_rbs_allowed_slice_uplink[NFAPI_CC_MAX][MAX_NUM_SLICES]; /*Slice Update */ diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index d8fe034183..fde36f3c98 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1102,6 +1102,7 @@ typedef struct { /// Sorting criteria for the UE list in the MAC preprocessor uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; + uint16_t first_rb_offset[NFAPI_CC_MAX][MAX_NUM_SLICES]; } UE_list_t; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index d04d89f7b1..edffc1d5db 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -178,6 +178,9 @@ store_dlsch_buffer(module_id_t Mod_id, } } +int cqi2mcs(int cqi) { + return cqi_to_mcs[cqi]; +} // This function returns the estimated number of RBs required by each UE for downlink scheduling void @@ -412,6 +415,7 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) return -1; if (cqi1 < cqi2) return 1; + break; case CR_LCP : if (lcgid1 < lcgid2) @@ -439,7 +443,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); if (criterion >= CR_NUM) { LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); - slice_sorting[slice_id] = 0x1234; + slice_sorting[slice_id] = 0x12345; break; } UE_list->sorting_criteria[slice_id][i] = criterion; @@ -1684,6 +1688,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, UE_TEMPLATE *UE_template = 0; UE_sched_ctrl *ue_sched_ctl; int N_RB_UL = 0; + uint16_t available_rbs, first_rb_offset; LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB @@ -1757,12 +1762,16 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], N_RB_UL); + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], + N_RB_UL - first_rb[CC_id] - first_rb_offset); + if (total_ue_count[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; } else if (total_ue_count[CC_id] == 1) { // increase the available RBs, special case, - average_rbs_per_user[CC_id] = ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] + 1; - } else if (total_ue_count[CC_id] <= (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) { - average_rbs_per_user[CC_id] = (uint16_t) floor((ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]) / total_ue_count[CC_id]); + average_rbs_per_user[CC_id] = (uint16_t) (available_rbs + 1); + } else if (total_ue_count[CC_id] <= available_rbs) { + average_rbs_per_user[CC_id] = (uint16_t) floor(available_rbs / total_ue_count[CC_id]); } else { average_rbs_per_user[CC_id] = 1; LOG_W(MAC, @@ -1834,8 +1843,11 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; - total_remaining_rbs[CC_id] = - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; + N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], + N_RB_UL - first_rb[CC_id] - first_rb_offset); + total_remaining_rbs[CC_id] = available_rbs - total_allocated_rbs[CC_id]; if (total_ue_count[CC_id] == 1) { total_remaining_rbs[CC_id] += 1; @@ -1885,6 +1897,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, UE_sched_ctrl *ue_sched_ctl; int Ncp; int N_RB_UL; + int first_rb_offset, available_rbs; for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (UE_list->active[i] != TRUE) @@ -1951,18 +1964,20 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs } + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], + N_RB_UL - first_rb[CC_id] - first_rb_offset); + while ((tbs < bits_to_schedule) - && (rb_table[rb_table_index] < (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) - && ((UE_template->phr_info - tx_power) > 0) - && (rb_table_index < 32)) { + && (rb_table[rb_table_index] < available_rbs) + && ((UE_template->phr_info - tx_power) > 0) + && (rb_table_index < 32)) { rb_table_index++; tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); } - UE_template->ue_tx_power = tx_power; - - if (rb_table[rb_table_index] > (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - 1)) { + if (rb_table[rb_table_index] > (available_rbs - 1)) { rb_table_index--; } // 1 or 2 PRB with cqi enabled does not work well @@ -2086,7 +2101,3 @@ void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP) UE_list->head_ul = -1; } } - -int cqi2mcs(int cqi) { - return cqi_to_mcs[cqi]; -} From 5cbe5c0df3a684d82f9ceabddb09840c258c1d9b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 27 Mar 2018 18:26:17 +0200 Subject: [PATCH 17/99] remove useless headers in scheduler --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index a8703050f3..d1849a2216 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -55,10 +55,6 @@ #include "intertask_interface.h" #endif -#include "ENB_APP/flexran_agent_defs.h" -#include "flexran_agent_ran_api.h" -#include "header.pb-c.h" -#include "flexran.pb-c.h" #include #include "T.h" From 1e840a9996920f8c022288aa583ab7e3115fd101 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 30 Mar 2018 12:08:38 +0200 Subject: [PATCH 18/99] FlexRAN: add slice configuration protobuf messages --- .../ENB_APP/MESSAGES/V2/config_common.proto | 83 ++++++++++++++++++- .../ENB_APP/MESSAGES/V2/config_messages.proto | 15 ++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index 7b392b6b3b..3af59c1537 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -58,6 +58,87 @@ enum flex_qam { FLEQ_MOD_64QAM = 1; } +// +// Slice config related structures and enums +// +enum flex_dl_sorting { + + CR_ROUND = 0; // Highest HARQ first + CR_SRB12 = 1; // Highest SRB1+2 first + CR_HOL = 2; // Highest HOL first + CR_LC = 3; // Greatest RLC buffer first + CR_CQI = 4; // Highest CQI first + CR_LCP = 5; // Highest LC priority first +} + +enum flex_ul_sorting { + CRU_ROUND = 0; // Highest HARQ first + CRU_BUF = 1; // Highest BSR first + CRU_BTS = 2; // More bytes to schedule first + CRU_MCS = 3; // Highest MCS first + CRU_LCP = 4; // Highest LC priority first + CRU_HOL = 5; // Highest HOL first +} + +enum flex_dl_accounting_policy { + POL_FAIR = 0; + POL_GREEDY = 1; + POL_NUM = 2; +} + +enum flex_ul_accounting_policy { + POLU_FAIR = 0; + POLU_GREEDY = 1; + POLU_NUM = 2; +} + +enum flex_slice_label { + xMBB = 0; + URLLC = 1; + mMTC = 2; + xMTC = 3; + Other = 4; +} + +message flex_dl_slice { + optional uint32 id = 1; + optional flex_slice_label label = 2; + // should be between 0 and 100 + optional uint32 percentage = 3; + // whether this slice should be exempted form interslice sharing + optional bool isolation = 4; + // increasing value means increasing prio + optional uint32 priority = 5; + // min and max RB to use (in frequency) in the range [0, N_RBG_MAX] + optional uint32 position_low = 6; + optional uint32 position_high = 7; + // maximum MCS to be allowed in this slice + optional uint32 maxmcs = 8; + repeated flex_dl_sorting sorting = 9; + optional flex_dl_accounting_policy accounting = 10; + optional string scheduler_name = 11; +} + +message flex_ul_slice { + optional uint32 id = 1; + optional flex_slice_label label = 2; + // should be between 0 and 100 + optional uint32 percentage = 3; + // whether this slice should be exempted form interslice sharing + optional bool isolation = 4; + // increasing value means increasing prio + optional uint32 priority = 5; + // RB start to use (in frequency) in the range [0, N_RB_MAX] + optional uint32 first_rb = 6; + // TODO RB number + //optional uint32 length_rb = 7; + // maximum MCS to be allowed in this slice + optional uint32 maxmcs = 8; + repeated flex_ul_sorting sorting = 9; + optional flex_ul_accounting_policy accounting = 10; + optional string scheduler_name = 11; +} + // // UE config related structures and enums // @@ -177,4 +258,4 @@ enum flex_ue_state_change_type { FLUESC_ACTIVATED = 1; FLUESC_DEACTIVATED = 2; FLUESC_MOVED = 3; -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index f734686f01..b186193b8c 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -43,6 +43,19 @@ message flex_cell_config { optional uint32 eutra_band= 37; // operating band optional int32 dl_pdsch_power = 38; // operating downlink power optional int32 ul_pusch_power = 39; // operating uplink power + + // whether remaining RBs after first intra-slice allocation will + // be allocated to UEs of the same slice + optional bool intraslice_share_active = 40; + // whether remaining RBs after slice allocation will be allocated + // to UEs of another slice. Isolated slices will be ignored. + optional bool interslice_share_active = 41; + optional flex_slice_config slice_config = 42; +} + +message flex_slice_config { + repeated flex_dl_slice dl = 1; + repeated flex_ul_slice ul = 2; } message flex_ue_config { @@ -82,6 +95,8 @@ message flex_ue_config { repeated flex_scell_config scell_config = 28; // Secondary cells configuration optional uint32 scell_deactivation_timer = 29;// Deactivation timer for secondary cell optional uint64 imsi = 30; + optional uint32 dl_slice_id = 31; + optional uint32 ul_slice_id = 32; } message flex_lc_ue_config { From 58c2a006265b5b22e0fc94b53c5c81b6ba9c1e31 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 30 Mar 2018 18:33:53 +0200 Subject: [PATCH 19/99] MAC: slicing conf struct in RC - introduce structure in RC for slicing conf (UL/DL) - move global variables regarding slice configuration into RC - change ue_slice_membership(): consider UL/DL - remove the unnecessary header files - set default parameters: one slice --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 245 +++++++++--------- openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 94 ------- .../LAYER2/MAC/eNB_scheduler_primitives.c | 4 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 124 ++++----- openair2/LAYER2/MAC/eNB_scheduler_ulsch.h | 74 ------ openair2/LAYER2/MAC/mac.h | 156 +++++++++-- openair2/LAYER2/MAC/mac_proto.h | 20 +- openair2/LAYER2/MAC/main.c | 46 +++- openair2/LAYER2/MAC/pre_processor.c | 98 ++++--- 9 files changed, 424 insertions(+), 437 deletions(-) delete mode 100644 openair2/LAYER2/MAC/eNB_scheduler_dlsch.h delete mode 100644 openair2/LAYER2/MAC/eNB_scheduler_ulsch.h diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index d1849a2216..236b0c05f1 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -29,6 +29,7 @@ */ +#define _GNU_SOURCE #include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac_proto.h" @@ -44,7 +45,6 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" -#include "eNB_scheduler_dlsch.h" #include "pdcp.h" #include "SIMULATION/TOOLS/sim.h" // for taus @@ -62,11 +62,9 @@ #define ENABLE_MAC_PAYLOAD_DEBUG //#define DEBUG_eNB_SCHEDULER 1 +#include "common/ran_context.h" extern RAN_CONTEXT_t RC; extern uint8_t nfapi_mode; -extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; -extern int slice_isolation[MAX_NUM_SLICES]; -extern int slice_priority[MAX_NUM_SLICES]; //------------------------------------------------------------------------------ void @@ -413,195 +411,196 @@ void schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) { int i = 0; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; - slice_percentage_total = 0; - slice_percentage_avg = 1.0 / n_active_slices; - slice_counter = n_active_slices; + sli->tot_pct_dl = 0; + sli->avg_pct_dl = 1.0 / sli->n_dl; + sli->slice_counter = sli->n_dl; // reset the slice percentage for inactive slices - for (i = n_active_slices; i < MAX_NUM_SLICES; i++) { - slice_percentage[i] = 0; + for (i = sli->n_dl; i < MAX_NUM_SLICES; i++) { + sli->dl[i].pct = 0; } - for (i = 0; i < n_active_slices; i++) { - if (slice_percentage[i] < 0) { + for (i = 0; i < sli->n_dl; i++) { + if (sli->dl[i].pct < 0) { LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, slice_percentage[i]); - slice_percentage[i] = 0; + module_idP, frameP, subframeP, i, sli->dl[i].pct); + sli->dl[i].pct = 0; } - slice_percentage_total += slice_percentage[i]; + sli->tot_pct_dl += sli->dl[i].pct; } // Check for *intra*slice share activation - if (intraslice_share_active_current != intraslice_share_active) { - if (intraslice_share_active != 1 && intraslice_share_active != 0) { + if (sli->intraslice_share_active_current != sli->intraslice_share_active) { + if (sli->intraslice_share_active != 1 && sli->intraslice_share_active != 0) { LOG_W(MAC, "[eNB %d][DL] frame %d subframe %d: invalid intraslice sharing status (%d), revert to its previous value (%d)\n", - module_idP, frameP, subframeP, intraslice_share_active, intraslice_share_active_current); - intraslice_share_active = intraslice_share_active_current; + module_idP, frameP, subframeP, sli->intraslice_share_active, sli->intraslice_share_active_current); + sli->intraslice_share_active = sli->intraslice_share_active_current; } else { LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: intraslice sharing status has changed (%x-->%x)\n", - module_idP, frameP, subframeP, intraslice_share_active_current, intraslice_share_active); - intraslice_share_active_current = intraslice_share_active; + module_idP, frameP, subframeP, sli->intraslice_share_active_current, sli->intraslice_share_active); + sli->intraslice_share_active_current = sli->intraslice_share_active; } } // Check for *inter*slice share activation - if (interslice_share_active_current != interslice_share_active) { - if (interslice_share_active != 1 && interslice_share_active != 0) { + if (sli->interslice_share_active_current != sli->interslice_share_active) { + if (sli->interslice_share_active != 1 && sli->interslice_share_active != 0) { LOG_W(MAC, "[eNB %d][DL] frame %d subframe %d: invalid interslice sharing status (%d), revert to its previous value (%d)\n", - module_idP, frameP, subframeP, interslice_share_active, interslice_share_active_current); - interslice_share_active = interslice_share_active_current; + module_idP, frameP, subframeP, sli->interslice_share_active, sli->interslice_share_active_current); + sli->interslice_share_active = sli->interslice_share_active_current; } else { LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: interslice sharing status has changed (%x-->%x)\n", - module_idP, frameP, subframeP, interslice_share_active_current, interslice_share_active); - interslice_share_active_current = interslice_share_active; + module_idP, frameP, subframeP, sli->interslice_share_active_current, sli->interslice_share_active); + sli->interslice_share_active_current = sli->interslice_share_active; } } - for (i = 0; i < n_active_slices; i++) { + for (i = 0; i < sli->n_dl; i++) { // Load any updated functions - if (update_dl_scheduler[i] > 0) { - slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); - update_dl_scheduler[i] = 0; - update_dl_scheduler_current[i] = 0; + if (sli->dl[i].update_sched > 0) { + sli->dl[i].sched_cb = dlsym(NULL, sli->dl[i].sched_name); + sli->dl[i].update_sched = 0; + sli->dl[i].update_sched_current = 0; LOG_I(MAC, "update dl scheduler slice %d\n", i); } - if (slice_percentage_total <= 1.0) { // the new total RB share is within the range + if (sli->tot_pct_dl <= 1.0) { // the new total RB share is within the range // check if the number of slices has changed, and log - if (n_active_slices_current != n_active_slices) { - if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + if (sli->n_dl_current != sli->n_dl) { + if ((sli->n_dl > 0) && (sli->n_dl <= MAX_NUM_SLICES)) { LOG_I(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); - n_active_slices_current = n_active_slices; + module_idP, frameP, subframeP, sli->n_dl_current, sli->n_dl); + sli->n_dl_current = sli->n_dl; } else { LOG_W(MAC, "invalid number of DL slices %d, revert to the previous value %d\n", - n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; + sli->n_dl, sli->n_dl_current); + sli->n_dl = sli->n_dl_current; } } // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]) { // new slice percentage + if (sli->dl[i].pct_current != sli->dl[i].pct) { // new slice percentage LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, slice_percentage_total_current, slice_percentage_total, - slice_percentage_current[i], slice_percentage[i]); - slice_percentage_total_current = slice_percentage_total; - slice_percentage_current[i] = slice_percentage[i]; + module_idP, i, frameP, subframeP, sli->tot_pct_dl_current, sli->tot_pct_dl, + sli->dl[i].pct_current, sli->dl[i].pct); + sli->tot_pct_dl_current = sli->tot_pct_dl; + sli->dl[i].pct_current = sli->dl[i].pct; } // check if the slice max MCS, and log the console - if (slice_maxmcs_current[i] != slice_maxmcs[i]) { - if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)) { + if (sli->dl[i].maxmcs_current != sli->dl[i].maxmcs) { + if ((sli->dl[i].maxmcs >= 0) && (sli->dl[i].maxmcs < 29)) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); - slice_maxmcs_current[i] = slice_maxmcs[i]; + module_idP, i, frameP, subframeP, sli->dl[i].maxmcs_current, sli->dl[i].maxmcs); + sli->dl[i].maxmcs_current = sli->dl[i].maxmcs; } else { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n", - module_idP, i, slice_maxmcs[i], slice_maxmcs_current[i]); - slice_maxmcs[i] = slice_maxmcs_current[i]; + module_idP, i, sli->dl[i].maxmcs, sli->dl[i].maxmcs_current); + sli->dl[i].maxmcs = sli->dl[i].maxmcs_current; } } // check if a new scheduler, and log the console - if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ - LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - module_idP, i, frameP, subframeP, dl_scheduler_type[i]); - update_dl_scheduler_current[i] = update_dl_scheduler[i]; + if (sli->dl[i].update_sched_current != sli->dl[i].update_sched) { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", + module_idP, i, frameP, subframeP, sli->dl[i].sched_name); + sli->dl[i].update_sched_current = sli->dl[i].update_sched; } } else { // here we can correct the values, e.g. reduce proportionally - if (n_active_slices == n_active_slices_current) { + if (sli->n_dl == sli->n_dl_current) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, slice_percentage_total_current, slice_percentage_total); - if (slice_percentage[i] >= slice_percentage_avg) { - slice_percentage[i] -= 0.1; - slice_percentage_total -= 0.1; + module_idP, i, sli->tot_pct_dl_current, sli->tot_pct_dl); + if (sli->dl[i].pct >= sli->avg_pct_dl) { + sli->dl[i].pct -= 0.1; + sli->tot_pct_dl -= 0.1; } } else { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, slice_percentage_total_current, slice_percentage_total, - n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; - slice_percentage[i] = slice_percentage_current[i]; + module_idP, i, sli->tot_pct_dl_current, sli->tot_pct_dl, + sli->n_dl, sli->n_dl_current); + sli->n_dl = sli->n_dl_current; + sli->dl[i].pct = sli->dl[i].pct_current; } } // Check for new slice positions - if (slice_position[i * 2] > slice_position[i * 2 + 1] || - slice_position[i * 2] < 0 || - slice_position[i * 2 + 1] > N_RBG_MAX) { + if (sli->dl[i].pos_low > sli->dl[i].pos_high || + sli->dl[i].pos_low < 0 || + sli->dl[i].pos_high > N_RBG_MAX) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n", module_idP, i, - slice_position[i * 2], slice_position[i * 2 + 1], - slice_position_current[i * 2], slice_position_current[i * 2 + 1]); - slice_position[i * 2] = slice_position_current[i * 2]; - slice_position[i * 2 + 1] = slice_position_current[i * 2 + 1]; + sli->dl[i].pos_low, sli->dl[i].pos_high, + sli->dl[i].pos_low_current, sli->dl[i].pos_high_current); + sli->dl[i].pos_low = sli->dl[i].pos_low_current; + sli->dl[i].pos_high = sli->dl[i].pos_high_current; } else { - if (slice_position_current[i * 2] != slice_position[i * 2]) { + if (sli->dl[i].pos_low_current != sli->dl[i].pos_low) { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", - module_idP, i, frameP, subframeP, slice_position_current[i * 2], slice_position[i * 2]); - slice_position_current[i * 2] = slice_position[i * 2]; + module_idP, i, frameP, subframeP, sli->dl[i].pos_low_current, sli->dl[i].pos_low); + sli->dl[i].pos_low_current = sli->dl[i].pos_low; } - if (slice_position_current[i * 2 + 1] != slice_position[i * 2 + 1]) { + if (sli->dl[i].pos_high_current != sli->dl[i].pos_high) { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", - module_idP, i, frameP, subframeP, slice_position_current[i * 2 + 1], slice_position[i * 2 + 1]); - slice_position_current[i * 2 + 1] = slice_position[i * 2 + 1]; + module_idP, i, frameP, subframeP, sli->dl[i].pos_high_current, sli->dl[i].pos_high); + sli->dl[i].pos_high_current = sli->dl[i].pos_high; } } // Check for new sorting policy - if (slice_sorting_current[i] != slice_sorting[i]) { + if (sli->dl[i].sorting_current != sli->dl[i].sorting) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_sorting_current[i], slice_sorting[i]); - slice_sorting_current[i] = slice_sorting[i]; + module_idP, i, frameP, subframeP, sli->dl[i].sorting_current, sli->dl[i].sorting); + sli->dl[i].sorting_current = sli->dl[i].sorting; } // Check for new slice isolation - if (slice_isolation_current[i] != slice_isolation[i]) { - if (slice_isolation[i] != 1 && slice_isolation[i] != 0) { + if (sli->dl[i].isol_current != sli->dl[i].isol) { + if (sli->dl[i].isol != 1 && sli->dl[i].isol != 0) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid slice isolation setting (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, slice_isolation[i], slice_isolation_current[i]); - slice_isolation[i] = slice_isolation_current[i]; + module_idP, i, frameP, subframeP, sli->dl[i].isol, sli->dl[i].isol_current); + sli->dl[i].isol = sli->dl[i].isol_current; } else { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice isolation setting has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_isolation_current[i], slice_isolation[i]); - slice_isolation_current[i] = slice_isolation[i]; + module_idP, i, frameP, subframeP, sli->dl[i].isol_current, sli->dl[i].isol); + sli->dl[i].isol_current = sli->dl[i].isol; } } // Check for new slice priority - if (slice_priority_current[i] != slice_priority[i]) { - LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_priority_current[i], slice_priority[i]); - slice_priority_current[i] = slice_priority[i]; + if (sli->dl[i].prio_current != sli->dl[i].prio) { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%d-->%d)\n", + module_idP, i, frameP, subframeP, sli->dl[i].prio_current, sli->dl[i].prio); + sli->dl[i].prio_current = sli->dl[i].prio; } // Check for new accounting policy - if (slice_accounting_current[i] != slice_accounting[i]) { - if (slice_accounting[i] > 1 || slice_accounting[i] < 0) { + if (sli->dl[i].accounting_current != sli->dl[i].accounting) { + if (sli->dl[i].accounting > 1 || sli->dl[i].accounting < 0) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, slice_accounting[i], slice_accounting_current[i]); - slice_accounting[i] = slice_accounting_current[i]; + module_idP, i, frameP, subframeP, sli->dl[i].accounting, sli->dl[i].accounting_current); + sli->dl[i].accounting = sli->dl[i].accounting_current; } else { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_accounting_current[i], slice_accounting[i]); - slice_accounting_current[i] = slice_accounting[i]; + module_idP, i, frameP, subframeP, sli->dl[i].accounting_current, sli->dl[i].accounting); + sli->dl[i].accounting_current = sli->dl[i].accounting; } } // Run each enabled slice-specific schedulers one by one - slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); + sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } } @@ -728,15 +727,15 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - slice_counter--; + RC.mac[module_idP]->slice_info.slice_counter--; // Do the multiplexing and actual allocation only when all slices have been pre-processed. - if (slice_counter > 0) { + if (RC.mac[module_idP]->slice_info.slice_counter > 0) { stop_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); return; } - if (interslice_share_active) { + if (RC.mac[module_idP]->slice_info.interslice_share_active) { dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP); } @@ -764,7 +763,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, continue_flag = 1; } - if (!ue_slice_membership(UE_id, slice_idP)) + if (!ue_slice_membership(UE_id, slice_idP, RC.mac[module_idP]->slice_info.n_dl)) continue; if (continue_flag != 1) { @@ -839,7 +838,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } else { // this operation is also done in the preprocessor eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, - slice_maxmcs[slice_idP]); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + RC.mac[module_idP]->slice_info.dl[slice_idP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } // Store stats @@ -1614,6 +1613,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub int owned, used; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; int N_RBG[NFAPI_CC_MAX]; @@ -1637,10 +1637,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub cc = &RC.mac[Mod_id]->common_channels[CC_id]; N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { - for (i = 0; i < n_active_slices; ++i) { - owned = pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; + for (i = 0; i < sli->n_dl; ++i) { + owned = sli->pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; if (owned) { - used = pre_processor_results[i].slice_allocated_rbgs[CC_id][rbg]; + used = sli->pre_processor_results[i].slice_allocated_rbgs[CC_id][rbg]; free_rbgs_map[CC_id][rbg] = used ? -1 : i; break; } @@ -1651,10 +1651,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub // Find out which slices need other resources. // FIXME: I don't think is really needed since we check nb_rbs_remaining later for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { - for (i = 0; i < n_active_slices; ++i) { + for (i = 0; i < sli->n_dl; ++i) { has_traffic[CC_id][i] = 0; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - if (pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) { + if (sli->pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) { has_traffic[CC_id][i] = 1; break; } @@ -1662,7 +1662,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub } } - slice_priority_sort(slice_sorted_list); + slice_priority_sort(Mod_id, slice_sorted_list); // MULTIPLEXING // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code @@ -1671,7 +1671,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); min_rb_unit = get_min_rb_unit(Mod_id, CC_id); - for (i = 0; i < n_active_slices; ++i) { + for (i = 0; i < sli->n_dl; ++i) { slice_id = slice_sorted_list[i]; if (has_traffic[CC_id][slice_id] == 0) continue; @@ -1683,7 +1683,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub allocation_mask[CC_id][rbg] = 0; continue; } - if (slice_isolation[free_rbgs_map[CC_id][rbg]] == 1) { + if (sli->dl[free_rbgs_map[CC_id][rbg]].isol == 1) { // RBG belongs to an isolated slice allocation_mask[CC_id][rbg] = 0; continue; @@ -1697,10 +1697,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it sort_UEs(Mod_id, (slice_id_t) slice_id, frameP, subframeP); - nb_rbs_remaining = pre_processor_results[slice_id].nb_rbs_remaining; - nb_rbs_required = pre_processor_results[slice_id].nb_rbs_required; - rballoc_sub = pre_processor_results[slice_id].slice_allocated_rbgs; - MIMO_mode_indicator = pre_processor_results[slice_id].MIMO_mode_indicator; + nb_rbs_remaining = sli->pre_processor_results[slice_id].nb_rbs_remaining; + nb_rbs_required = sli->pre_processor_results[slice_id].nb_rbs_required; + rballoc_sub = sli->pre_processor_results[slice_id].slice_allocated_rbgs; + MIMO_mode_indicator = sli->pre_processor_results[slice_id].MIMO_mode_indicator; // Allocation for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { @@ -1756,10 +1756,11 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ { int UE_id, CC_id, i; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; UE_sched_ctrl *ue_sched_ctl; for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { - for (i = 0; i < n_active_slices; ++i) { + for (i = 0; i < sli->n_dl; ++i) { // Sort UE again // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it @@ -2330,23 +2331,25 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) return; } -static int slice_priority_compare(const void *_a, const void *_b) { +static int slice_priority_compare(const void *_a, const void *_b, void *_c) +{ + const int slice_id1 = *(const int *) _a; + const int slice_id2 = *(const int *) _b; + const module_id_t Mod_id = *(int *) _c; + const slice_info_t *sli = &RC.mac[Mod_id]->slice_info; - int slice_id1 = *(const int *) _a; - int slice_id2 = *(const int *) _b; - - if (slice_priority[slice_id1] > slice_priority[slice_id2]) { + if (sli->dl[slice_id1].prio > sli->dl[slice_id2].prio) { return -1; } return 1; } -void slice_priority_sort(int slice_list[MAX_NUM_SLICES]) { - +void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]) +{ int i; for (i = 0; i < MAX_NUM_SLICES; ++i) { slice_list[i] = i; } - qsort(slice_list, MAX_NUM_SLICES, sizeof(int), slice_priority_compare); + qsort_r(slice_list, MAX_NUM_SLICES, sizeof(int), slice_priority_compare, &Mod_id); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h deleted file mode 100644 index e2aac32bf0..0000000000 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file LAYER2/MAC/eNB_scheduler_dlsch.h -* \brief DLSCH Scheduler policy variables used during different phases of scheduling -* \author Navid Nikaein and Niccolo' Iardella -* \date 2018 -* \version 0.2 -* \email navid.nikaein@eurecom.fr - -*/ -/** @defgroup _oai2 openair2 Reference Implementation - * @ingroup _ref_implementation_ - * @{ - */ - -/*@}*/ - -#ifndef __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ -#define __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ - -// number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; -int slice_counter = 0; - -int intraslice_share_active = 1; -int intraslice_share_active_current = 1; -int interslice_share_active = 1; -int interslice_share_active_current = 1; - -// RB share for each slice for past and current time -float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_total = 0; -float slice_percentage_total_current = 0; -float slice_percentage_avg = 0.25; - -int slice_isolation[MAX_NUM_SLICES] = {0, 0, 0, 0}; -int slice_isolation_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; -int slice_priority[MAX_NUM_SLICES] = {10, 5, 2, 0}; -int slice_priority_current[MAX_NUM_SLICES] = {10, 5, 2, 0}; - -// Frequency ranges for slice positioning -int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; -int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; - -// MAX MCS for each slice for past and current time -int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; -int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; - -// The lists of criteria that enforce the sorting policies of the slices -uint32_t slice_sorting[MAX_NUM_SLICES] = {0x012345, 0x012345, 0x012345, 0x012345}; -uint32_t slice_sorting_current[MAX_NUM_SLICES] = {0x012345, 0x012345, 0x012345, 0x012345}; - -// Accounting policy (just greedy(1) or fair(0) setting for now) -int slice_accounting[MAX_NUM_SLICES] = {0, 0, 0, 0}; -int slice_accounting_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; - -int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; -int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; - -// name of available scheduler -char *dl_scheduler_type[MAX_NUM_SLICES] = - { "schedule_ue_spec", - "schedule_ue_spec", - "schedule_ue_spec", - "schedule_ue_spec" - }; - -// pointer to the slice specific scheduler -slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; - -pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; - -#endif //__LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 5328920af3..4643fe41a1 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -62,8 +62,6 @@ extern uint16_t frame_cnt; extern RAN_CONTEXT_t RC; -extern int n_active_slices; - int choose(int n, int k) { int res = 1; @@ -4541,7 +4539,7 @@ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs) return (uint16_t) floor(rb_percentage * total_rbs); } -int ue_slice_membership(int UE_id, int slice_id) +int ue_slice_membership(int UE_id, int slice_id, int n_active_slices) { if ((slice_id < 0) || (slice_id > n_active_slices)) LOG_W(MAC, "out of range slice id %d\n", slice_id); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index fffc1a2209..5c31a7ef43 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -48,7 +48,6 @@ #include "assertions.h" //#include "LAYER2/MAC/pre_processor.c" -#include "eNB_scheduler_ulsch.h" #include "pdcp.h" #if defined(ENABLE_ITTI) @@ -64,6 +63,9 @@ #include "T.h" +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 @@ -923,6 +925,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, uint16_t first_rb[NFAPI_CC_MAX], i; int CC_id; eNB_MAC_INST *mac = RC.mac[module_idP]; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; COMMON_channels_t *cc; start_meas(&mac->schedule_ulsch); @@ -1037,112 +1040,112 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, // perform slice-specifc operations - total_slice_percentage_uplink=0; - avg_slice_percentage_uplink=1.0/n_active_slices_uplink; + sli->tot_pct_ul = 0; + sli->avg_pct_ul = 1.0 / sli->n_ul; // reset the slice percentage for inactive slices - for (i = n_active_slices_uplink; i< MAX_NUM_SLICES; i++) { - slice_percentage_uplink[i]=0; + for (i = sli->n_ul; i< MAX_NUM_SLICES; i++) { + sli->ul[i].pct = 0; } - for (i = 0; i < n_active_slices_uplink; i++) { - if (slice_percentage_uplink[i] < 0 ){ + for (i = 0; i < sli->n_ul; i++) { + if (sli->ul[i].pct < 0 ){ LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, slice_percentage_uplink[i]); - slice_percentage_uplink[i]=0; + module_idP, frameP, subframeP, i, sli->ul[i].pct); + sli->ul[i].pct = 0; } - total_slice_percentage_uplink+=slice_percentage_uplink[i]; + sli->tot_pct_ul += sli->ul[i].pct; } - for (i = 0; i < n_active_slices_uplink; i++) { + for (i = 0; i < sli->n_ul; i++) { // Load any updated functions - if (update_ul_scheduler[i] > 0 ) { - slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); - update_ul_scheduler[i] = 0; - update_ul_scheduler_current[i] = 0; - //slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; - //total_slice_percentage_current_uplink+=slice_percentage_uplink[i]; - //if (total_slice_percentage_current_uplink> 1) - //total_slice_percentage_current_uplink=1; + if (sli->ul[i].update_sched > 0 ) { + sli->ul[i].sched_cb = dlsym(NULL, sli->ul[i].sched_name); + sli->ul[i].update_sched = 0; + sli->ul[i].update_sched_current = 0; + //sli->ul[i].pct_current = sli->ul[i].pct; + //sli->tot_pct_ul_current += sli->ul[i].pct; + //if (sli->tot_pct_ul_current > 1) + //sli->tot_pct_ul_current = 1; LOG_I(MAC,"update ul scheduler slice %d\n", i); } // the new total RB share is within the range - if (total_slice_percentage_uplink <= 1.0){ + if (sli->tot_pct_ul <= 1.0){ // check if the number of slices has changed, and log - if (n_active_slices_current_uplink != n_active_slices_uplink ){ - if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { + if (sli->n_ul_current != sli->n_ul ){ + if ((sli->n_ul > 0) && (sli->n_ul <= MAX_NUM_SLICES)) { LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, n_active_slices_current_uplink, n_active_slices_uplink); - n_active_slices_current_uplink = n_active_slices_uplink; + module_idP, frameP, subframeP, sli->n_ul_current, sli->n_ul); + sli->n_ul_current = sli->n_ul; } else { LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n", - n_active_slices_uplink, n_active_slices_current_uplink); - n_active_slices_uplink = n_active_slices_current_uplink; + sli->n_ul, sli->n_ul_current); + sli->n_ul = sli->n_ul_current; } } // check if the slice rb share has changed, and log the console - if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ + if (sli->ul[i].pct_current != sli->ul[i].pct){ LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, total_slice_percentage_current_uplink, - total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); - total_slice_percentage_current_uplink = total_slice_percentage_uplink; - slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; + module_idP, i, frameP, subframeP, sli->tot_pct_ul_current, + sli->tot_pct_ul, sli->ul[i].pct_current, sli->ul[i].pct); + sli->tot_pct_ul_current = sli->tot_pct_ul; + sli->ul[i].pct_current = sli->ul[i].pct; } // check if the slice max MCS, and log the console - if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ - if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ + if (sli->ul[i].maxmcs_current != sli->ul[i].maxmcs){ + if ((sli->ul[i].maxmcs >= 0) && (sli->ul[i].maxmcs <= 16)){ LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); - slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; + module_idP, i, frameP, subframeP, sli->ul[i].maxmcs_current, sli->ul[i].maxmcs); + sli->ul[i].maxmcs_current = sli->ul[i].maxmcs; } else { LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n", - module_idP, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); - slice_maxmcs_uplink[i] = slice_maxmcs_current_uplink[i]; + module_idP, i, sli->ul[i].maxmcs, sli->ul[i].maxmcs_current); + sli->ul[i].maxmcs = sli->ul[i].maxmcs_current; } } - if (slice_first_rb_current[i] != slice_first_rb[i]){ - if (slice_first_rb[i] >= 0){ // FIXME: Max limit is checked in the scheduler + if (sli->ul[i].first_rb_current != sli->ul[i].first_rb){ + if (sli->ul[i].first_rb >= 0){ // FIXME: Max limit is checked in the scheduler LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice first rb has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, slice_first_rb_current[i], slice_first_rb[i]); - slice_first_rb_current[i] = slice_first_rb[i]; + module_idP, i, frameP, subframeP, sli->ul[i].first_rb_current, sli->ul[i].first_rb); + sli->ul[i].first_rb_current = sli->ul[i].first_rb; } else { LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice first rb %d, revert the previous value %d\n", - module_idP, i, slice_first_rb[i],slice_first_rb_current[i]); - slice_first_rb[i] = slice_first_rb_current[i]; + module_idP, i, sli->ul[i].first_rb, sli->ul[i].first_rb_current); + sli->ul[i].first_rb = sli->ul[i].first_rb_current; } } // check if a new scheduler, and log the console - if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ + if (sli->ul[i].update_sched_current != sli->ul[i].update_sched) { LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", - module_idP, i, frameP, subframeP, ul_scheduler_type[i]); - update_ul_scheduler_current[i] = update_ul_scheduler[i]; + module_idP, i, frameP, subframeP, sli->ul[i].sched_name); + sli->ul[i].update_sched_current = sli->ul[i].update_sched; } } else { - if (n_active_slices_uplink == n_active_slices_current_uplink) { + if (sli->n_ul == sli->n_ul_current) { LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, total_slice_percentage_current_uplink, total_slice_percentage_uplink); - if (slice_percentage_uplink[i] > avg_slice_percentage_uplink) { - slice_percentage_uplink[i] -= 0.1; - total_slice_percentage_uplink -= 0.1; + module_idP, i, sli->tot_pct_ul_current, sli->tot_pct_ul); + if (sli->ul[i].pct > sli->avg_pct_ul) { + sli->ul[i].pct -= 0.1; + sli->tot_pct_ul -= 0.1; } } else { // here we can correct the values, e.g. reduce proportionally LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, total_slice_percentage_current_uplink, - total_slice_percentage_uplink, n_active_slices_uplink, - n_active_slices_current_uplink); - n_active_slices_uplink = n_active_slices_current_uplink; - slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; + module_idP, i, sli->tot_pct_ul_current, + sli->tot_pct_ul, sli->n_ul, + sli->n_ul_current); + sli->n_ul = sli->n_ul_current; + sli->ul[i].pct = sli->ul[i].pct_current; } } // Run each enabled slice-specific schedulers one by one - slice_sched_ul[i](module_idP, i, frameP, subframeP, sched_subframe, first_rb); + sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb); } stop_meas(&mac->schedule_ulsch); @@ -1172,6 +1175,7 @@ schedule_ulsch_rnti(module_id_t module_idP, eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc = mac->common_channels; UE_list_t *UE_list = &mac->UE_list; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_TEMPLATE *UE_template; UE_sched_ctrl *UE_sched_ctrl; int sched_frame = frameP; @@ -1193,7 +1197,7 @@ schedule_ulsch_rnti(module_id_t module_idP, for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); - UE_list->first_rb_offset[CC_id][slice_id] = cmin(N_RB_UL, slice_first_rb[slice_id]); + UE_list->first_rb_offset[CC_id][slice_id] = cmin(N_RB_UL, sli->ul[slice_id].first_rb); } //LOG_D(MAC, "entering ulsch preprocesor\n"); @@ -1210,7 +1214,7 @@ schedule_ulsch_rnti(module_id_t module_idP, for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { - if (!ue_slice_membership(UE_id, slice_id)) + if (!ue_slice_membership(UE_id, slice_id, sli->n_ul)) continue; // don't schedule if Msg4 is not received yet @@ -1398,7 +1402,7 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_template->oldNDI_UL[harq_pid] = ndi; UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; - UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, slice_maxmcs_uplink[slice_id]); + UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_id].maxmcs); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS if (UE_template->pre_allocated_rb_table_index_ul >= 0) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h deleted file mode 100644 index 517c13b1f3..0000000000 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file LAYER2/MAC/eNB_scheduler_ulsch.h -* \brief ULSCH Scheduler policy variables used during different phases of scheduling -* \author Navid Nikaein and Niccolo' Iardella -* \date 2018 -* \version 0.2 -* \email navid.nikaein@eurecom.fr - -*/ -/** @defgroup _oai2 openair2 Reference Implementation - * @ingroup _ref_implementation_ - * @{ - */ - -/*@}*/ - -#ifndef __LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__ -#define __LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__ - -/* number of active slices for past and current time*/ -int n_active_slices_uplink = 1; -int n_active_slices_current_uplink = 1; - -/* RB share for each slice for past and current time*/ -float avg_slice_percentage_uplink=0.25; -float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage_uplink = 0; -float total_slice_percentage_current_uplink = 0; - -// MAX MCS for each slice for past and current time -int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20}; -int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20}; - -int slice_first_rb[MAX_NUM_SLICES] = {0, 0, 0, 0}; -int slice_first_rb_current[MAX_NUM_SLICES] = {0,0,0,0}; - -/*resource blocks allowed*/ -uint16_t nb_rbs_allowed_slice_uplink[NFAPI_CC_MAX][MAX_NUM_SLICES]; -/*Slice Update */ -int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; -int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; - -/* name of available scheduler*/ -char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti", - "schedule_ulsch_rnti", - "schedule_ulsch_rnti", - "schedule_ulsch_rnti" -}; - -/* Slice Function Pointer */ -slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; - -#endif //__LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__ diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index fde36f3c98..68d09ae6e8 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1122,6 +1122,143 @@ typedef struct { int tail_freelist; ///the tail position of the delete list } UE_free_list_t; +/// Structure for saving the output of each pre_processor instance +typedef struct { + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; + + uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID]; + uint32_t wb_pmi[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint8_t mcs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + +} pre_processor_results_t; + +/** + * slice specific scheduler for the DL + */ +typedef void (*slice_scheduler_dl)(module_id_t mod_id, + slice_id_t slice_id, + frame_t frame, + sub_frame_t subframe, + int *mbsfn_flag); + +typedef struct { + /// RB share for each slice for past and current time + float pct; + float pct_current; + + /// whether this slice is isolated from the others for past and current time + int isol; + int isol_current; + + int prio; + int prio_current; + + /// Frequency ranges for slice positioning + int pos_low; + int pos_high; + int pos_low_current; + int pos_high_current; + + // max mcs for each slice for past and current time + int maxmcs; + int maxmcs_current; + + /// criteria for sorting policies of the slices + uint32_t sorting; + uint32_t sorting_current; + + /// Accounting policy (just greedy(1) or fair(0) setting for now) + int accounting; + int accounting_current; + + /// Whether the scheduler callback should be updated + int update_sched; + int update_sched_current; + + /// name of available scheduler + char *sched_name; + + /// pointer to the slice specific scheduler in DL + slice_scheduler_dl sched_cb; + +} slice_sched_conf_dl_t; + +typedef void (*slice_scheduler_ul)(module_id_t mod_id, + slice_id_t slice_id, + frame_t frame, + sub_frame_t subframe, + unsigned char sched_subframe, + uint16_t *first_rb); + +typedef struct { + /// RB share for each slice for past and current time + float pct; + float pct_current; + + // MAX MCS for each slice for past and current time + int maxmcs; + int maxmcs_current; + + /// criteria for sorting policies of the slices + uint32_t sorting; + uint32_t sorting_current; + + /// starting RB (RB offset) of UL scheduling + int first_rb; + int first_rb_current; + + /// Slice scheduler callback update needed + int update_sched; + int update_sched_current; + + /// name of available scheduler + char *sched_name; + + /// pointer to the slice specific scheduler in UL + slice_scheduler_ul sched_cb; + +} slice_sched_conf_ul_t; + + +typedef struct { + /// counter used to indicate when all slices have pre-allocated UEs + int slice_counter; + + /// indicates whether remaining RBs after first intra-slice allocation will + /// be allocated to UEs of the same slice + int intraslice_share_active; + int intraslice_share_active_current; + /// indicates whether remaining RBs after slice allocation will be + /// allocated to UEs of another slice. Isolated slices will be ignored + int interslice_share_active; + int interslice_share_active_current; + + /// number of active slices for past and current time in DL + int n_dl; + int n_dl_current; + /// RB share stats for DL + float tot_pct_dl; + float tot_pct_dl_current; + float avg_pct_dl; + slice_sched_conf_dl_t dl[MAX_NUM_SLICES]; + + /// number of active slices for past and current time in UL + int n_ul; + int n_ul_current; + /// RB share stats for UL + float tot_pct_ul; + float tot_pct_ul_current; + float avg_pct_ul; + slice_sched_conf_ul_t ul[MAX_NUM_SLICES]; + + pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; +} slice_info_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1242,7 +1379,10 @@ typedef struct eNB_MAC_INST_s { /// UL handle uint32_t ul_handle; UE_list_t UE_list; - + + /// slice-related configuration + slice_info_t slice_info; + ///subband bitmap configuration SBMAP_CONF sbmap_conf; /// CCE table used to build DCI scheduling information @@ -1575,20 +1715,6 @@ typedef struct { mui_t rrc_mui[128]; }mac_rlc_am_muilist_t; -/// Structure for saving the output of each pre_processor instance -typedef struct { - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; - uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX]; - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; - - uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID]; - uint32_t wb_pmi[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; - uint8_t mcs[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; -} pre_processor_results_t; - #include "mac_proto.h" /*@}*/ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 98b6c8fbe0..257bae361e 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -36,22 +36,6 @@ * @{ */ -/** - * slice specific scheduler - */ -typedef void (*slice_scheduler_dl)(module_id_t mod_id, - slice_id_t slice_id, - frame_t frame, - sub_frame_t subframe, - int *mbsfn_flag); - -typedef void (*slice_scheduler_ul)(module_id_t mod_id, - slice_id_t slice_id, - frame_t frame, - sub_frame_t subframe, - unsigned char sched_subframe, - uint16_t *first_rb); - /** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); \brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. @param Mod_id Instance ID of eNB @@ -260,7 +244,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); -void slice_priority_sort(int slice_list[MAX_NUM_SLICES]); +void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]); void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, @@ -1278,7 +1262,7 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, /*Slice related functions */ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); -int ue_slice_membership(int UE_id, int slice_id); +int ue_slice_membership(int UE_id, int slice_id, int n_active_slices); /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index da2d977875..4c3e22acb7 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -52,6 +52,7 @@ void mac_top_init_eNB(void) module_id_t i, j; int list_el; UE_list_t *UE_list; + slice_info_t *sli; eNB_MAC_INST *mac; LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n", @@ -112,7 +113,7 @@ void mac_top_init_eNB(void) RC.mac = NULL; } - // Initialize Linked-List for Active UEs + // Initialize Linked-List for Active UEs and slice configuration for (i = 0; i < RC.nb_macrlc_inst; i++) { mac = RC.mac[i]; @@ -133,6 +134,49 @@ void mac_top_init_eNB(void) UE_list->next[list_el] = -1; UE_list->next_ul[list_el] = -1; + + sli = &mac->slice_info; + + sli->intraslice_share_active = 1; + sli->intraslice_share_active_current = 1; + sli->interslice_share_active = 1; + sli->interslice_share_active_current = 1; + + sli->n_dl = 1; + sli->n_dl_current = 1; + sli->tot_pct_dl = 1; + sli->tot_pct_dl_current = 1; + sli->avg_pct_dl = 0.25; + memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); + sli->dl[0].pct = 1.0; + sli->dl[0].pct_current = 1.0; + sli->dl[0].prio = 10; + sli->dl[0].prio_current = 10; + sli->dl[0].pos_high = N_RBG_MAX; + sli->dl[0].pos_high_current = N_RBG_MAX; + sli->dl[0].maxmcs = 28; + sli->dl[0].maxmcs_current = 28; + sli->dl[0].sorting = 0x012345; + sli->dl[0].sorting_current = 0x012345; + sli->dl[0].update_sched = 1; + sli->dl[0].update_sched_current = 1; + sli->dl[0].sched_name = "schedule_ue_spec"; + + sli->n_ul = 1; + sli->n_ul_current = 1; + sli->tot_pct_ul = 1; + sli->tot_pct_ul_current = 1; + sli->avg_pct_ul = 0.25; + memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); + sli->ul[0].pct = 1.0; + sli->ul[0].pct_current = 1.0; + sli->ul[0].maxmcs = 20; + sli->ul[0].maxmcs_current = 20; + sli->ul[0].sorting = 0x0123; + sli->ul[0].sorting_current = 0x0123; + sli->ul[0].update_sched = 1; + sli->ul[0].update_sched_current = 1; + sli->ul[0].sched_name = "schedule_ulsch_rnti"; } } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index edffc1d5db..e00634bf3a 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -54,17 +54,6 @@ extern RAN_CONTEXT_t RC; #define DEBUG_HEADER_PARSING 1 //#define DEBUG_PACKET_TRACE 1 -extern float slice_percentage[MAX_NUM_SLICES]; -extern float slice_percentage_uplink[MAX_NUM_SLICES]; -extern int slice_position[MAX_NUM_SLICES*2]; -extern uint32_t slice_sorting[MAX_NUM_SLICES]; -extern int slice_accounting[MAX_NUM_SLICES]; -extern int slice_maxmcs[MAX_NUM_SLICES]; -extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; -extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; - -extern int intraslice_share_active; - //#define ICIC 0 /* this function checks that get_eNB_UE_stats returns @@ -113,7 +102,7 @@ store_dlsch_buffer(module_id_t Mod_id, if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_slice_membership(UE_id, slice_id)) + if (!ue_slice_membership(UE_id, slice_id, RC.mac[Mod_id]->slice_info.n_dl)) continue; UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; @@ -196,13 +185,14 @@ assign_rbs_required(module_id_t Mod_id, int UE_id, n, i, j, CC_id, pCCid, tmp; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j; int N_RB_DL; // clear rb allocations across all CC_id for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; pCCid = UE_PCCID(Mod_id, UE_id); //update CQI information across component carriers @@ -210,8 +200,8 @@ assign_rbs_required(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[n][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; -// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], slice_maxmcs[slice_id]); - eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), slice_maxmcs[slice_id]); +// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_id].maxmcs); + eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), sli->dl[slice_id].maxmcs); } @@ -254,7 +244,7 @@ assign_rbs_required(module_id_t Mod_id, N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] = - nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + nb_rbs_allowed_slice(sli->dl[slice_id].pct, N_RB_DL); /* calculating required number of RBs for each UE */ while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { @@ -274,7 +264,7 @@ assign_rbs_required(module_id_t Mod_id, nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats->dlsch_mcs1); - pre_processor_results[slice_id].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; + sli->pre_processor_results[slice_id].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; } } } @@ -435,7 +425,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { int i; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - uint32_t policy = slice_sorting[slice_id]; + uint32_t policy = RC.mac[Mod_idP]->slice_info.dl[slice_id].sorting; uint32_t mask = 0x0000000F; uint16_t criterion; @@ -443,7 +433,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); if (criterion >= CR_NUM) { LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); - slice_sorting[slice_id] = 0x12345; + RC.mac[Mod_idP]->slice_info.dl[slice_id].sorting = 0x12345; break; } UE_list->sorting_criteria[slice_id][i] = criterion; @@ -463,8 +453,8 @@ void decode_slice_positioning(module_id_t Mod_idP, } } - start_frequency = slice_position[slice_id*2]; - end_frequency = slice_position[slice_id*2 + 1]; + start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_id].pos_low; + end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_id].pos_high; for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { slice_allocation_mask[CC_id][RBG] = 1; @@ -488,7 +478,7 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t if (UE_list->active[i] == FALSE) continue; if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id)) continue; + if (!ue_slice_membership(i, slice_id, RC.mac[Mod_idP]->slice_info.n_dl)) continue; list[list_size] = i; list_size++; @@ -592,14 +582,14 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, RC.mac[Mod_id]->slice_info.n_dl)) continue; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - available_rbs = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + available_rbs = nb_rbs_allowed_slice(RC.mac[Mod_id]->slice_info.dl[slice_id].pct, N_RB_DL); if (rbs_retx[CC_id] < available_rbs) ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = available_rbs - rbs_retx[CC_id]; else @@ -630,6 +620,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; @@ -650,7 +641,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -682,7 +673,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Reduces the available RBs according to slicing configuration dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); - switch (slice_accounting[slice_id]) { + switch (RC.mac[Mod_id]->slice_info.dl[slice_id].accounting) { // If greedy scheduling, try to account all the required RBs case POL_GREEDY: @@ -690,7 +681,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -710,7 +701,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { @@ -735,7 +726,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -754,7 +745,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -789,6 +780,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, int N_RBG[NFAPI_CC_MAX]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); @@ -802,7 +794,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -1011,9 +1003,10 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, int UE_id, CC_id; int i; uint8_t transmission_mode; - uint8_t (*slice_allocation_mask)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocation_mask; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; int N_RBG[NFAPI_CC_MAX]; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + uint8_t (*slice_allocation_mask)[N_RBG_MAX] = sli->pre_processor_results[slice_id].slice_allocation_mask; decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); @@ -1027,7 +1020,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) continue; + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -1241,11 +1234,12 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, int min_rb_unit[NFAPI_CC_MAX]; - uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_required; - uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_accounted; - uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_remaining; - uint8_t (*rballoc_sub)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocated_rbgs; - uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = pre_processor_results[slice_id].MIMO_mode_indicator; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_required; + uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_accounted; + uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_remaining; + uint8_t (*rballoc_sub)[N_RBG_MAX] = sli->pre_processor_results[slice_id].slice_allocated_rbgs; + uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_id].MIMO_mode_indicator; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -1263,7 +1257,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, #endif // Initialize scheduling information for all active UEs - memset(&pre_processor_results[slice_id], 0, sizeof(pre_processor_results)); + memset(&sli->pre_processor_results[slice_id], 0, sizeof(sli->pre_processor_results)); // FIXME: After the memset above, some of the resets in reset() are redundant dlsch_scheduler_pre_processor_reset(Mod_id, slice_id, frameP, subframeP, min_rb_unit, @@ -1302,7 +1296,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // SHARING // If there are available RBs left in the slice, allocate them to the highest priority UEs - if (intraslice_share_active) { + if (RC.mac[Mod_id]->slice_info.intraslice_share_active) { dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_id, min_rb_unit, nb_rbs_required, @@ -1411,6 +1405,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, rnti_t rnti; UE_list_t *UE_list; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_sched_ctrl *ue_sched_ctl; uint8_t *vrb_map; COMMON_channels_t *cc; @@ -1440,7 +1435,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_slice_membership(UE_id, slice_id)) + if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; @@ -1674,7 +1669,6 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, unsigned char sched_subframeP, uint16_t *first_rb) { - int16_t i; uint16_t UE_id, n, r; uint8_t CC_id, harq_pid; @@ -1685,6 +1679,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, uint16_t total_ue_count[NFAPI_CC_MAX]; rnti_t rnti = -1; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_TEMPLATE *UE_template = 0; UE_sched_ctrl *ue_sched_ctl; int N_RB_UL = 0; @@ -1714,7 +1709,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][i]; UE_template = &UE_list->UE_template[CC_id][i]; - if (!ue_slice_membership(i, slice_id)) + if (!ue_slice_membership(i, slice_id, sli->n_ul)) continue; if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { total_ue_count[CC_id] += 1; @@ -1735,7 +1730,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) + if (!ue_slice_membership(UE_id, slice_id, sli->n_ul)) continue; LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, @@ -1760,7 +1755,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = - nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], N_RB_UL); + nb_rbs_allowed_slice(sli->ul[slice_id].pct, N_RB_UL); first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], @@ -1792,7 +1787,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id)) + if (!ue_slice_membership(i, slice_id, sli->n_ul)) continue; @@ -1833,7 +1828,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id)) + if (!ue_slice_membership(i, slice_id, sli->n_ul)) continue; UE_id = i; @@ -1892,6 +1887,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, int rb_table_index = 0, tbs, tx_power; eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_TEMPLATE *UE_template; UE_sched_ctrl *ue_sched_ctl; @@ -1909,16 +1905,16 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id)) + if (!ue_slice_membership(i, slice_id, sli->n_ul)) continue; if (UE_list->UE_sched_ctrl[i].phr_received == 1) { /* if we've received the power headroom information the UE, we can go to * maximum mcs */ - mcs = cmin(20, slice_maxmcs_uplink[slice_id]); + mcs = cmin(20, sli->ul[slice_id].maxmcs); } else { /* otherwise, limit to QPSK PUSCH */ - mcs = cmin(10, slice_maxmcs_uplink[slice_id]); + mcs = cmin(10, sli->ul[slice_id].maxmcs); } UE_id = i; @@ -1941,7 +1937,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = - nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], N_RB_UL); + nb_rbs_allowed_slice(sli->ul[slice_id].pct, N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; if (bytes_to_schedule < 0) bytes_to_schedule = 0; From 048c4d29a2c0a321b0f3683fdcfd82bf305ba663 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 6 Apr 2018 12:30:47 +0200 Subject: [PATCH 20/99] add slice association in UE_list, test against it in slice_membership() --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 27 ++++++++++---- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/MAC/mac.h | 3 ++ openair2/LAYER2/MAC/mac_proto.h | 3 +- openair2/LAYER2/MAC/pre_processor.c | 37 +++++++++---------- 6 files changed, 44 insertions(+), 30 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 236b0c05f1..79589a064e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -763,7 +763,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, continue_flag = 1; } - if (!ue_slice_membership(UE_id, slice_idP, RC.mac[module_idP]->slice_info.n_dl)) + if (!ue_dl_slice_membership(module_idP, UE_id, slice_idP)) continue; if (continue_flag != 1) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 4643fe41a1..4773cf9c67 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1961,6 +1961,9 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP sizeof(eNB_UE_STATS)); UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; + /* default slice in case there was something different */ + UE_list->assoc_dl_slice[UE_id] = 0; + UE_list->assoc_ul_slice[UE_id] = 0; UE_list->UE_sched_ctrl[UE_id].ta_update = 31; @@ -4539,14 +4542,24 @@ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs) return (uint16_t) floor(rb_percentage * total_rbs); } -int ue_slice_membership(int UE_id, int slice_id, int n_active_slices) +int ue_dl_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id) { - if ((slice_id < 0) || (slice_id > n_active_slices)) + if ((slice_id < 0) + || (slice_id >= RC.mac[mod_id]->slice_info.n_dl)) { LOG_W(MAC, "out of range slice id %d\n", slice_id); - - - if ((UE_id % n_active_slices) == slice_id) { - return 1; // this ue is a member of this slice + return 0; } - return 0; + return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE + && RC.mac[mod_id]->UE_list.assoc_dl_slice[UE_id] == slice_id; +} + +int ue_ul_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id) +{ + if ((slice_id < 0) + || (slice_id >= RC.mac[mod_id]->slice_info.n_ul)) { + LOG_W(MAC, "out of range slice id %d\n", slice_id); + return 0; + } + return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE + && RC.mac[mod_id]->UE_list.assoc_ul_slice[UE_id] == slice_id; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 5c31a7ef43..5fb69e6a8f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1214,7 +1214,7 @@ schedule_ulsch_rnti(module_id_t module_idP, for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { - if (!ue_slice_membership(UE_id, slice_id, sli->n_ul)) + if (!ue_ul_slice_membership(module_idP, UE_id, slice_id)) continue; // don't schedule if Msg4 is not received yet diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 68d09ae6e8..cb6aa5bf3b 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1104,6 +1104,9 @@ typedef struct { uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; uint16_t first_rb_offset[NFAPI_CC_MAX][MAX_NUM_SLICES]; + slice_id_t assoc_dl_slice[MAX_MOBILES_PER_ENB]; + slice_id_t assoc_ul_slice[MAX_MOBILES_PER_ENB]; + } UE_list_t; /*! \brief deleting control information*/ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 257bae361e..ac48cb170d 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -1262,7 +1262,8 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, /*Slice related functions */ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); -int ue_slice_membership(int UE_id, int slice_id, int n_active_slices); +int ue_dl_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id); +int ue_ul_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id); /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e00634bf3a..b449e5b0c3 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -102,7 +102,7 @@ store_dlsch_buffer(module_id_t Mod_id, if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_slice_membership(UE_id, slice_id, RC.mac[Mod_id]->slice_info.n_dl)) + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; @@ -192,7 +192,7 @@ assign_rbs_required(module_id_t Mod_id, // clear rb allocations across all CC_id for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; pCCid = UE_PCCID(Mod_id, UE_id); //update CQI information across component carriers @@ -478,7 +478,7 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t if (UE_list->active[i] == FALSE) continue; if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id, RC.mac[Mod_idP]->slice_info.n_dl)) continue; + if (!ue_dl_slice_membership(Mod_idP, i, slice_id)) continue; list[list_size] = i; list_size++; @@ -582,7 +582,7 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, RC.mac[Mod_id]->slice_info.n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; @@ -620,7 +620,6 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - slice_info_t *sli = &RC.mac[Mod_id]->slice_info; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; @@ -641,7 +640,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -681,7 +680,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -701,7 +700,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { @@ -726,7 +725,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -745,7 +744,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -780,7 +779,6 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, int N_RBG[NFAPI_CC_MAX]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - slice_info_t *sli = &RC.mac[Mod_id]->slice_info; decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); @@ -794,7 +792,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -1020,7 +1018,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -1405,7 +1403,6 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, rnti_t rnti; UE_list_t *UE_list; - slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_sched_ctrl *ue_sched_ctl; uint8_t *vrb_map; COMMON_channels_t *cc; @@ -1435,7 +1432,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) + if (!ue_dl_slice_membership(module_idP, UE_id, slice_id)) continue; vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; @@ -1709,7 +1706,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][i]; UE_template = &UE_list->UE_template[CC_id][i]; - if (!ue_slice_membership(i, slice_id, sli->n_ul)) + if (!ue_ul_slice_membership(module_idP, i, slice_id)) continue; if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { total_ue_count[CC_id] += 1; @@ -1730,7 +1727,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id, sli->n_ul)) + if (!ue_ul_slice_membership(module_idP, UE_id, slice_id)) continue; LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, @@ -1787,7 +1784,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id, sli->n_ul)) + if (!ue_ul_slice_membership(module_idP, i, slice_id)) continue; @@ -1828,7 +1825,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id, sli->n_ul)) + if (!ue_ul_slice_membership(module_idP, i, slice_id)) continue; UE_id = i; @@ -1905,7 +1902,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id, sli->n_ul)) + if (!ue_ul_slice_membership(module_idP, i, slice_id)) continue; if (UE_list->UE_sched_ctrl[i].phr_received == 1) { From 568bf8ae35d7288acf1d5ba450b79a00b145ae5f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 9 Apr 2018 15:42:42 +0200 Subject: [PATCH 21/99] bugfix: deactive slice_counter slice_counter had a wrong condition, not scheduling in DLSCH if the number of slices is greater than one --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 14 +++++++------- openair2/LAYER2/MAC/mac.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 79589a064e..ad48aba116 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -415,7 +415,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in sli->tot_pct_dl = 0; sli->avg_pct_dl = 1.0 / sli->n_dl; - sli->slice_counter = sli->n_dl; + //sli->slice_counter = sli->n_dl; // reset the slice percentage for inactive slices for (i = sli->n_dl; i < MAX_NUM_SLICES; i++) { @@ -727,13 +727,13 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - RC.mac[module_idP]->slice_info.slice_counter--; + //RC.mac[module_idP]->slice_info.slice_counter--; // Do the multiplexing and actual allocation only when all slices have been pre-processed. - if (RC.mac[module_idP]->slice_info.slice_counter > 0) { - stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); - return; - } + //if (RC.mac[module_idP]->slice_info.slice_counter > 0) { + //stop_meas(&eNB->schedule_dlsch); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + //return; + //} if (RC.mac[module_idP]->slice_info.interslice_share_active) { dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP); diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index cb6aa5bf3b..e16d24b98b 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1230,7 +1230,7 @@ typedef struct { typedef struct { /// counter used to indicate when all slices have pre-allocated UEs - int slice_counter; + //int slice_counter; /// indicates whether remaining RBs after first intra-slice allocation will /// be allocated to UEs of the same slice From 87b8b6e86bb6192a4cf8262d5e041c5e93109607 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 16:37:50 +0200 Subject: [PATCH 22/99] Increase the number of possible slices to 10 --- openair2/LAYER2/MAC/mac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index e16d24b98b..0784c14dc3 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -159,7 +159,7 @@ #define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE) /*!\brief maximum number of slices / groups */ -#define MAX_NUM_SLICES 4 +#define MAX_NUM_SLICES 10 #define U_PLANE_INACTIVITY_VALUE 6000 From 8f2d79709e6d117fe714107e99ab5b077830606f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 16 Apr 2018 16:22:37 +0200 Subject: [PATCH 23/99] MAC: change all slice_id_t to slice index variables --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 67 +++--- .../LAYER2/MAC/eNB_scheduler_primitives.c | 26 ++- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 39 ++-- openair2/LAYER2/MAC/mac.h | 12 +- openair2/LAYER2/MAC/mac_proto.h | 29 +-- openair2/LAYER2/MAC/pre_processor.c | 209 +++++++++--------- 6 files changed, 201 insertions(+), 181 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index ad48aba116..d27ef6c40e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -423,8 +423,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in } for (i = 0; i < sli->n_dl; i++) { if (sli->dl[i].pct < 0) { - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, sli->dl[i].pct); + LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid percentage %f. resetting to zero", + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pct); sli->dl[i].pct = 0; } sli->tot_pct_dl += sli->dl[i].pct; @@ -465,7 +465,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in sli->dl[i].sched_cb = dlsym(NULL, sli->dl[i].sched_name); sli->dl[i].update_sched = 0; sli->dl[i].update_sched_current = 0; - LOG_I(MAC, "update dl scheduler slice %d\n", i); + LOG_I(MAC, "update dl scheduler slice index %d ID %d\n", i, sli->dl[i].id); } if (sli->tot_pct_dl <= 1.0) { // the new total RB share is within the range @@ -487,7 +487,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (sli->dl[i].pct_current != sli->dl[i].pct) { // new slice percentage LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, sli->tot_pct_dl_current, sli->tot_pct_dl, + module_idP, sli->dl[i].id, frameP, subframeP, + sli->tot_pct_dl_current, sli->tot_pct_dl, sli->dl[i].pct_current, sli->dl[i].pct); sli->tot_pct_dl_current = sli->tot_pct_dl; sli->dl[i].pct_current = sli->dl[i].pct; @@ -497,11 +498,12 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (sli->dl[i].maxmcs_current != sli->dl[i].maxmcs) { if ((sli->dl[i].maxmcs >= 0) && (sli->dl[i].maxmcs < 29)) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, sli->dl[i].maxmcs_current, sli->dl[i].maxmcs); + module_idP, sli->dl[i].id, frameP, subframeP, + sli->dl[i].maxmcs_current, sli->dl[i].maxmcs); sli->dl[i].maxmcs_current = sli->dl[i].maxmcs; } else { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n", - module_idP, i, sli->dl[i].maxmcs, sli->dl[i].maxmcs_current); + module_idP, sli->dl[i].id, sli->dl[i].maxmcs, sli->dl[i].maxmcs_current); sli->dl[i].maxmcs = sli->dl[i].maxmcs_current; } } @@ -509,7 +511,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in // check if a new scheduler, and log the console if (sli->dl[i].update_sched_current != sli->dl[i].update_sched) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - module_idP, i, frameP, subframeP, sli->dl[i].sched_name); + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].sched_name); sli->dl[i].update_sched_current = sli->dl[i].update_sched; } @@ -519,7 +521,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (sli->n_dl == sli->n_dl_current) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, sli->tot_pct_dl_current, sli->tot_pct_dl); + module_idP, sli->dl[i].id, sli->tot_pct_dl_current, sli->tot_pct_dl); if (sli->dl[i].pct >= sli->avg_pct_dl) { sli->dl[i].pct -= 0.1; sli->tot_pct_dl -= 0.1; @@ -527,7 +529,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in } else { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, sli->tot_pct_dl_current, sli->tot_pct_dl, + module_idP, sli->dl[i].id, sli->tot_pct_dl_current, sli->tot_pct_dl, sli->n_dl, sli->n_dl_current); sli->n_dl = sli->n_dl_current; sli->dl[i].pct = sli->dl[i].pct_current; @@ -539,7 +541,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in sli->dl[i].pos_low < 0 || sli->dl[i].pos_high > N_RBG_MAX) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n", - module_idP, i, + module_idP, sli->dl[i].id, sli->dl[i].pos_low, sli->dl[i].pos_high, sli->dl[i].pos_low_current, sli->dl[i].pos_high_current); sli->dl[i].pos_low = sli->dl[i].pos_low_current; @@ -547,12 +549,12 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in } else { if (sli->dl[i].pos_low_current != sli->dl[i].pos_low) { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", - module_idP, i, frameP, subframeP, sli->dl[i].pos_low_current, sli->dl[i].pos_low); + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pos_low_current, sli->dl[i].pos_low); sli->dl[i].pos_low_current = sli->dl[i].pos_low; } if (sli->dl[i].pos_high_current != sli->dl[i].pos_high) { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", - module_idP, i, frameP, subframeP, sli->dl[i].pos_high_current, sli->dl[i].pos_high); + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pos_high_current, sli->dl[i].pos_high); sli->dl[i].pos_high_current = sli->dl[i].pos_high; } } @@ -560,7 +562,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in // Check for new sorting policy if (sli->dl[i].sorting_current != sli->dl[i].sorting) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, sli->dl[i].sorting_current, sli->dl[i].sorting); + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].sorting_current, sli->dl[i].sorting); sli->dl[i].sorting_current = sli->dl[i].sorting; } @@ -569,11 +571,11 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (sli->dl[i].isol != 1 && sli->dl[i].isol != 0) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid slice isolation setting (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, sli->dl[i].isol, sli->dl[i].isol_current); + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].isol, sli->dl[i].isol_current); sli->dl[i].isol = sli->dl[i].isol_current; } else { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice isolation setting has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, sli->dl[i].isol_current, sli->dl[i].isol); + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].isol_current, sli->dl[i].isol); sli->dl[i].isol_current = sli->dl[i].isol; } } @@ -581,7 +583,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in // Check for new slice priority if (sli->dl[i].prio_current != sli->dl[i].prio) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%d-->%d)\n", - module_idP, i, frameP, subframeP, sli->dl[i].prio_current, sli->dl[i].prio); + module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].prio_current, sli->dl[i].prio); sli->dl[i].prio_current = sli->dl[i].prio; } @@ -590,11 +592,13 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in if (sli->dl[i].accounting > 1 || sli->dl[i].accounting < 0) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, sli->dl[i].accounting, sli->dl[i].accounting_current); + module_idP, sli->dl[i].id, frameP, subframeP, + sli->dl[i].accounting, sli->dl[i].accounting_current); sli->dl[i].accounting = sli->dl[i].accounting_current; } else { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, sli->dl[i].accounting_current, sli->dl[i].accounting); + module_idP, sli->dl[i].id, frameP, subframeP, + sli->dl[i].accounting_current, sli->dl[i].accounting); sli->dl[i].accounting_current = sli->dl[i].accounting; } } @@ -609,7 +613,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in //------------------------------------------------------------------------------ void -schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, +schedule_ue_spec(module_id_t module_idP, int slice_idxP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { @@ -719,7 +723,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor(module_idP, - slice_idP, + slice_idxP, frameP, subframeP, mbsfn_flag); @@ -763,7 +767,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, continue_flag = 1; } - if (!ue_dl_slice_membership(module_idP, UE_id, slice_idP)) + if (!ue_dl_slice_membership(module_idP, UE_id, slice_idxP)) continue; if (continue_flag != 1) { @@ -838,7 +842,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } else { // this operation is also done in the preprocessor eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, - RC.mac[module_idP]->slice_info.dl[slice_idP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + RC.mac[module_idP]->slice_info.dl[slice_idxP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } // Store stats @@ -1618,7 +1622,8 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub COMMON_channels_t *cc; int N_RBG[NFAPI_CC_MAX]; - int slice_sorted_list[MAX_NUM_SLICES], slice_id; + int slice_sorted_list[MAX_NUM_SLICES]; + int slice_idx; int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX]; int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES]; uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; @@ -1672,9 +1677,9 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub min_rb_unit = get_min_rb_unit(Mod_id, CC_id); for (i = 0; i < sli->n_dl; ++i) { - slice_id = slice_sorted_list[i]; + slice_idx = slice_sorted_list[i]; - if (has_traffic[CC_id][slice_id] == 0) continue; + if (has_traffic[CC_id][slice_idx] == 0) continue; // Build an ad-hoc allocation mask fo the slice for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { @@ -1695,12 +1700,12 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub // Sort UE again // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point) // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it - sort_UEs(Mod_id, (slice_id_t) slice_id, frameP, subframeP); + sort_UEs(Mod_id, slice_idx, frameP, subframeP); - nb_rbs_remaining = sli->pre_processor_results[slice_id].nb_rbs_remaining; - nb_rbs_required = sli->pre_processor_results[slice_id].nb_rbs_required; - rballoc_sub = sli->pre_processor_results[slice_id].slice_allocated_rbgs; - MIMO_mode_indicator = sli->pre_processor_results[slice_id].MIMO_mode_indicator; + nb_rbs_remaining = sli->pre_processor_results[slice_idx].nb_rbs_remaining; + nb_rbs_required = sli->pre_processor_results[slice_idx].nb_rbs_required; + rballoc_sub = sli->pre_processor_results[slice_idx].slice_allocated_rbgs; + MIMO_mode_indicator = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; // Allocation for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { @@ -1764,7 +1769,7 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ // Sort UE again // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it - sort_UEs(Mod_id, (slice_id_t) i, frameP, subframeP); + sort_UEs(Mod_id, (uint8_t)i, frameP, subframeP); for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 4773cf9c67..6bdb63a721 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1962,8 +1962,8 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; /* default slice in case there was something different */ - UE_list->assoc_dl_slice[UE_id] = 0; - UE_list->assoc_ul_slice[UE_id] = 0; + UE_list->assoc_dl_slice_idx[UE_id] = 0; + UE_list->assoc_ul_slice_idx[UE_id] = 0; UE_list->UE_sched_ctrl[UE_id].ta_update = 31; @@ -4542,24 +4542,26 @@ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs) return (uint16_t) floor(rb_percentage * total_rbs); } -int ue_dl_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id) +int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx) { - if ((slice_id < 0) - || (slice_id >= RC.mac[mod_id]->slice_info.n_dl)) { - LOG_W(MAC, "out of range slice id %d\n", slice_id); + if ((slice_idx < 0) + || (slice_idx >= RC.mac[mod_id]->slice_info.n_dl)) { + LOG_W(MAC, "out of range slice index %d (slice ID %d)\n", + slice_idx, RC.mac[mod_id]->slice_info.dl[slice_idx].id); return 0; } return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE - && RC.mac[mod_id]->UE_list.assoc_dl_slice[UE_id] == slice_id; + && RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[UE_id] == slice_idx; } -int ue_ul_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id) +int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx) { - if ((slice_id < 0) - || (slice_id >= RC.mac[mod_id]->slice_info.n_ul)) { - LOG_W(MAC, "out of range slice id %d\n", slice_id); + if ((slice_idx < 0) + || (slice_idx >= RC.mac[mod_id]->slice_info.n_ul)) { + LOG_W(MAC, "out of range slice index %d (slice ID %d)\n", + slice_idx, RC.mac[mod_id]->slice_info.dl[slice_idx].id); return 0; } return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE - && RC.mac[mod_id]->UE_list.assoc_ul_slice[UE_id] == slice_id; + && RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[UE_id] == slice_idx; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 5fb69e6a8f..4197ed6ba3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1049,8 +1049,9 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } for (i = 0; i < sli->n_ul; i++) { if (sli->ul[i].pct < 0 ){ - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, sli->ul[i].pct); + LOG_W(MAC, + "[eNB %d][SLICE %d][UL] frame %d subframe %d: invalid percentage %f. resetting to zero", + module_idP, sli->ul[i].id, frameP, subframeP, sli->ul[i].pct); sli->ul[i].pct = 0; } sli->tot_pct_ul += sli->ul[i].pct; @@ -1088,7 +1089,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, // check if the slice rb share has changed, and log the console if (sli->ul[i].pct_current != sli->ul[i].pct){ LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, sli->tot_pct_ul_current, + module_idP, sli->ul[i].id, frameP, subframeP, sli->tot_pct_ul_current, sli->tot_pct_ul, sli->ul[i].pct_current, sli->ul[i].pct); sli->tot_pct_ul_current = sli->tot_pct_ul; sli->ul[i].pct_current = sli->ul[i].pct; @@ -1098,11 +1099,12 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, if (sli->ul[i].maxmcs_current != sli->ul[i].maxmcs){ if ((sli->ul[i].maxmcs >= 0) && (sli->ul[i].maxmcs <= 16)){ LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, sli->ul[i].maxmcs_current, sli->ul[i].maxmcs); + module_idP, sli->ul[i].id, frameP, subframeP, + sli->ul[i].maxmcs_current, sli->ul[i].maxmcs); sli->ul[i].maxmcs_current = sli->ul[i].maxmcs; } else { LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n", - module_idP, i, sli->ul[i].maxmcs, sli->ul[i].maxmcs_current); + module_idP, sli->ul[i].id, sli->ul[i].maxmcs, sli->ul[i].maxmcs_current); sli->ul[i].maxmcs = sli->ul[i].maxmcs_current; } } @@ -1110,11 +1112,13 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, if (sli->ul[i].first_rb_current != sli->ul[i].first_rb){ if (sli->ul[i].first_rb >= 0){ // FIXME: Max limit is checked in the scheduler LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice first rb has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, sli->ul[i].first_rb_current, sli->ul[i].first_rb); + module_idP, sli->ul[i].id, frameP, subframeP, + sli->ul[i].first_rb_current, sli->ul[i].first_rb); sli->ul[i].first_rb_current = sli->ul[i].first_rb; } else { LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice first rb %d, revert the previous value %d\n", - module_idP, i, sli->ul[i].first_rb, sli->ul[i].first_rb_current); + module_idP, sli->ul[i].id, sli->ul[i].first_rb, + sli->ul[i].first_rb_current); sli->ul[i].first_rb = sli->ul[i].first_rb_current; } } @@ -1122,13 +1126,13 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, // check if a new scheduler, and log the console if (sli->ul[i].update_sched_current != sli->ul[i].update_sched) { LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", - module_idP, i, frameP, subframeP, sli->ul[i].sched_name); + module_idP, sli->ul[i].id, frameP, subframeP, sli->ul[i].sched_name); sli->ul[i].update_sched_current = sli->ul[i].update_sched; } } else { if (sli->n_ul == sli->n_ul_current) { LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, sli->tot_pct_ul_current, sli->tot_pct_ul); + module_idP, sli->ul[i].id, sli->tot_pct_ul_current, sli->tot_pct_ul); if (sli->ul[i].pct > sli->avg_pct_ul) { sli->ul[i].pct -= 0.1; sli->tot_pct_ul -= 0.1; @@ -1136,9 +1140,8 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } else { // here we can correct the values, e.g. reduce proportionally LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, sli->tot_pct_ul_current, - sli->tot_pct_ul, sli->n_ul, - sli->n_ul_current); + module_idP, sli->ul[i].id, sli->tot_pct_ul_current, + sli->tot_pct_ul, sli->n_ul, sli->n_ul_current); sli->n_ul = sli->n_ul_current; sli->ul[i].pct = sli->ul[i].pct_current; } @@ -1153,7 +1156,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, void schedule_ulsch_rnti(module_id_t module_idP, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb) @@ -1197,14 +1200,14 @@ schedule_ulsch_rnti(module_id_t module_idP, for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); - UE_list->first_rb_offset[CC_id][slice_id] = cmin(N_RB_UL, sli->ul[slice_id].first_rb); + UE_list->first_rb_offset[CC_id][slice_idx] = cmin(N_RB_UL, sli->ul[slice_idx].first_rb); } //LOG_D(MAC, "entering ulsch preprocesor\n"); - ulsch_scheduler_pre_processor(module_idP, slice_id, frameP, subframeP, sched_subframeP, first_rb); + ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_subframeP, first_rb); for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { - first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_id]; + first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx]; } //LOG_D(MAC, "exiting ulsch preprocesor\n"); @@ -1214,7 +1217,7 @@ schedule_ulsch_rnti(module_id_t module_idP, for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { - if (!ue_ul_slice_membership(module_idP, UE_id, slice_id)) + if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) continue; // don't schedule if Msg4 is not received yet @@ -1402,7 +1405,7 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_template->oldNDI_UL[harq_pid] = ndi; UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; - UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_id].maxmcs); + UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS if (UE_template->pre_allocated_rb_table_index_ul >= 0) { diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 0784c14dc3..f22cc4081c 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1104,8 +1104,8 @@ typedef struct { uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; uint16_t first_rb_offset[NFAPI_CC_MAX][MAX_NUM_SLICES]; - slice_id_t assoc_dl_slice[MAX_MOBILES_PER_ENB]; - slice_id_t assoc_ul_slice[MAX_MOBILES_PER_ENB]; + int assoc_dl_slice_idx[MAX_MOBILES_PER_ENB]; + int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB]; } UE_list_t; @@ -1144,12 +1144,14 @@ typedef struct { * slice specific scheduler for the DL */ typedef void (*slice_scheduler_dl)(module_id_t mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frame, sub_frame_t subframe, int *mbsfn_flag); typedef struct { + slice_id_t id; + /// RB share for each slice for past and current time float pct; float pct_current; @@ -1192,13 +1194,15 @@ typedef struct { } slice_sched_conf_dl_t; typedef void (*slice_scheduler_ul)(module_id_t mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frame, sub_frame_t subframe, unsigned char sched_subframe, uint16_t *first_rb); typedef struct { + slice_id_t id; + /// RB share for each slice for past and current time float pct; float pct_current; diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index ac48cb170d..4837b84d4f 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -103,12 +103,12 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, /** \brief ULSCH Scheduling per RNTI @param Mod_id Instance ID of eNB -@param slice_id Instance slice for this eNB +@param slice_idx Slice instance index for this eNB @param frame Frame index @param subframe Subframe number on which to act @param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup) */ -void schedule_ulsch_rnti(module_id_t module_idP, slice_id_t slice_idP, frame_t frameP, +void schedule_ulsch_rnti(module_id_t module_idP, int slice_idx, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, uint16_t * first_rb); @@ -131,7 +131,7 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,i void schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag); -void schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, +void schedule_ue_spec(module_id_t module_idP, int slice_idxP, frame_t frameP,sub_frame_t subframe, int *mbsfn_flag); void schedule_ue_spec_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag); @@ -192,6 +192,7 @@ void clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, // eNB functions /* \brief This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done @param Mod_id Instance ID of eNB +@param slice_idxP Slice instance index for the slice in which scheduling happens @param frame Index of frame @param subframe Index of current subframe @param N_RBS Number of resource block groups @@ -199,13 +200,13 @@ void clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, void dlsch_scheduler_pre_processor(module_id_t module_idP, - slice_id_t slice_idP, + int slice_idxP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag); void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], @@ -215,11 +216,11 @@ void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, int *mbsfn_flag); void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, const uint8_t rbs_retx[NFAPI_CC_MAX]); void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], @@ -227,7 +228,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]); void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, int min_rb_unit[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], @@ -236,7 +237,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, int min_rb_unit[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], @@ -713,20 +714,20 @@ void set_ul_DAI(int module_idP, int frameP, int subframeP); -void ulsch_scheduler_pre_processor(module_id_t module_idP, slice_id_t slice_id, int frameP, +void ulsch_scheduler_pre_processor(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb); void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP); void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP); -void assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, +void assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, uint16_t * first_rb); void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE * UE_template); int phy_stats_exist(module_id_t Mod_id, int rnti); -void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP); +void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subframeP); /*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index) \brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures. @@ -1262,8 +1263,8 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, /*Slice related functions */ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); -int ue_dl_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id); -int ue_ul_slice_membership(module_id_t mod_id, int UE_id, slice_id_t slice_id); +int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); +int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index b449e5b0c3..f951b065c6 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -88,7 +88,7 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) // This function stores the downlink buffer for all the logical channels void store_dlsch_buffer(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP) { @@ -102,7 +102,7 @@ store_dlsch_buffer(module_id_t Mod_id, if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; @@ -146,8 +146,8 @@ store_dlsch_buffer(module_id_t Mod_id, if (UE_template->dl_buffer_info[lcid] > 0) LOG_D(MAC, "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, slice_id, frameP, subframeP, UE_id, - lcid, UE_template->dl_pdus_in_buffer[lcid], + Mod_id, RC.mac[Mod_id]->slice_info.dl[slice_idx].id, frameP, + subframeP, UE_id, lcid, UE_template->dl_pdus_in_buffer[lcid], UE_template->dl_buffer_info[lcid], UE_template->dl_buffer_head_sdu_creation_time[lcid], UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid], @@ -174,7 +174,7 @@ int cqi2mcs(int cqi) { // This function returns the estimated number of RBs required by each UE for downlink scheduling void assign_rbs_required(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframe, int min_rb_unit[NFAPI_CC_MAX], @@ -192,7 +192,7 @@ assign_rbs_required(module_id_t Mod_id, // clear rb allocations across all CC_id for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; pCCid = UE_PCCID(Mod_id, UE_id); //update CQI information across component carriers @@ -200,8 +200,8 @@ assign_rbs_required(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[n][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; -// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_id].maxmcs); - eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), sli->dl[slice_id].maxmcs); +// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_idx].maxmcs); + eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), sli->dl[slice_idx].maxmcs); } @@ -243,16 +243,16 @@ assign_rbs_required(module_id_t Mod_id, N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] = - nb_rbs_allowed_slice(sli->dl[slice_id].pct, N_RB_DL); + UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx] = + nb_rbs_allowed_slice(sli->dl[slice_idx].pct, N_RB_DL); /* calculating required number of RBs for each UE */ while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; - if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); - nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; + if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]) { + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]); + nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]; break; } TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]); @@ -264,7 +264,7 @@ assign_rbs_required(module_id_t Mod_id, nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats->dlsch_mcs1); - sli->pre_processor_results[slice_id].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; + sli->pre_processor_results[slice_idx].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; } } } @@ -332,7 +332,7 @@ struct sort_ue_dl_params { int Mod_idP; int frameP; int subframeP; - int slice_id; + int slice_idx; }; static int ue_dl_compare(const void *_a, const void *_b, void *_params) @@ -341,7 +341,7 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; int i; - int slice_id = params->slice_id; + int slice_idx = params->slice_idx; int UE_id1 = *(const int *) _a; int UE_id2 = *(const int *) _b; @@ -360,7 +360,7 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) long lcgid2 = min_lcgidpriority(params->Mod_idP, UE_id2); for (i = 0; i < CR_NUM; ++i) { - switch (UE_list->sorting_criteria[slice_id][i]) { + switch (UE_list->sorting_criteria[slice_idx][i]) { case CR_ROUND : if (round1 > round2) @@ -421,28 +421,31 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) return 0; } -void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { +void decode_sorting_policy(module_id_t Mod_idP, int slice_idx) { int i; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - uint32_t policy = RC.mac[Mod_idP]->slice_info.dl[slice_id].sorting; + uint32_t policy = RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting; uint32_t mask = 0x0000000F; uint16_t criterion; for (i = 0; i < CR_NUM; ++i) { criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); if (criterion >= CR_NUM) { - LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); - RC.mac[Mod_idP]->slice_info.dl[slice_id].sorting = 0x12345; + LOG_W(MAC, + "Invalid criterion in slice index %d ID %d policy, revert to default policy \n", + slice_idx, RC.mac[Mod_idP]->slice_info.dl[slice_idx].id); + RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting = 0x12345; break; } - UE_list->sorting_criteria[slice_id][i] = criterion; + UE_list->sorting_criteria[slice_idx][i] = criterion; } } void decode_slice_positioning(module_id_t Mod_idP, - slice_id_t slice_id, - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) { + int slice_idx, + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) +{ uint8_t CC_id; int RBG, start_frequency, end_frequency; @@ -453,8 +456,8 @@ void decode_slice_positioning(module_id_t Mod_idP, } } - start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_id].pos_low; - end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_id].pos_high; + start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_low; + end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_high; for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { slice_allocation_mask[CC_id][RBG] = 1; @@ -464,12 +467,12 @@ void decode_slice_positioning(module_id_t Mod_idP, // This fuction sorts the UE in order their dlsch buffer and CQI -void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP) +void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subframeP) { int i; int list[MAX_MOBILES_PER_ENB]; int list_size = 0; - struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_id}; + struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_idx}; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; @@ -478,13 +481,13 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t if (UE_list->active[i] == FALSE) continue; if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_idP, i, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_idP, i, slice_idx)) continue; list[list_size] = i; list_size++; } - decode_sorting_policy(Mod_idP, slice_id); + decode_sorting_policy(Mod_idP, slice_idx); qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); @@ -571,8 +574,9 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t } void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, - slice_id_t slice_id, - const uint8_t rbs_retx[NFAPI_CC_MAX]) { + int slice_idx, + const uint8_t rbs_retx[NFAPI_CC_MAX]) +{ int UE_id, CC_id, N_RB_DL, i; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -582,24 +586,24 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - available_rbs = nb_rbs_allowed_slice(RC.mac[Mod_id]->slice_info.dl[slice_id].pct, N_RB_DL); + available_rbs = nb_rbs_allowed_slice(RC.mac[Mod_id]->slice_info.dl[slice_idx].pct, N_RB_DL); if (rbs_retx[CC_id] < available_rbs) - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = available_rbs - rbs_retx[CC_id]; + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx] = available_rbs - rbs_retx[CC_id]; else - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = 0; + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx] = 0; } } } void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], @@ -640,7 +644,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -670,9 +674,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // PARTITIONING // Reduces the available RBs according to slicing configuration - dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); + dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_idx, rbs_retx); - switch (RC.mac[Mod_id]->slice_info.dl[slice_id].accounting) { + switch (RC.mac[Mod_id]->slice_info.dl[slice_idx].accounting) { // If greedy scheduling, try to account all the required RBs case POL_GREEDY: @@ -680,7 +684,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -700,13 +704,13 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - available_rbs = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]; + available_rbs = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; if (ue_count_newtx[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; @@ -725,7 +729,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -744,7 +748,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -763,7 +767,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, } void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, int min_rb_unit[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], @@ -780,7 +784,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); + decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask); for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; @@ -792,7 +796,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -990,23 +994,23 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, } void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, int min_rb_unit[NFAPI_CC_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { - + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) +{ int UE_id, CC_id; int i; uint8_t transmission_mode; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; int N_RBG[NFAPI_CC_MAX]; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; - uint8_t (*slice_allocation_mask)[N_RBG_MAX] = sli->pre_processor_results[slice_id].slice_allocation_mask; + uint8_t (*slice_allocation_mask)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].slice_allocation_mask; - decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); + decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask); for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; @@ -1018,7 +1022,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_id, UE_id, slice_id)) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; @@ -1221,7 +1225,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done void dlsch_scheduler_pre_processor(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) @@ -1233,11 +1237,11 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, int min_rb_unit[NFAPI_CC_MAX]; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; - uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_required; - uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_accounted; - uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_remaining; - uint8_t (*rballoc_sub)[N_RBG_MAX] = sli->pre_processor_results[slice_id].slice_allocated_rbgs; - uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_id].MIMO_mode_indicator; + uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_required; + uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_accounted; + uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_remaining; + uint8_t (*rballoc_sub)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].slice_allocated_rbgs; + uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -1255,9 +1259,9 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, #endif // Initialize scheduling information for all active UEs - memset(&sli->pre_processor_results[slice_id], 0, sizeof(sli->pre_processor_results)); + memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results)); // FIXME: After the memset above, some of the resets in reset() are redundant - dlsch_scheduler_pre_processor_reset(Mod_id, slice_id, frameP, subframeP, + dlsch_scheduler_pre_processor_reset(Mod_id, slice_idx, frameP, subframeP, min_rb_unit, nb_rbs_required, rballoc_sub, @@ -1266,25 +1270,25 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // STATUS // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); + store_dlsch_buffer(Mod_id, slice_idx, frameP, subframeP); // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, slice_id, frameP, subframeP, + assign_rbs_required(Mod_id, slice_idx, frameP, subframeP, min_rb_unit, nb_rbs_required); // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs(Mod_id, slice_id, frameP, subframeP); + sort_UEs(Mod_id, slice_idx, frameP, subframeP); // ACCOUNTING // This procedure decides the number of RBs to allocate - dlsch_scheduler_pre_processor_accounting(Mod_id, slice_id, frameP, subframeP, + dlsch_scheduler_pre_processor_accounting(Mod_id, slice_idx, frameP, subframeP, min_rb_unit, nb_rbs_required, nb_rbs_accounted); // POSITIONING // This procedure does the main allocation of the RBs - dlsch_scheduler_pre_processor_positioning(Mod_id, slice_id, + dlsch_scheduler_pre_processor_positioning(Mod_id, slice_idx, min_rb_unit, nb_rbs_required, nb_rbs_accounted, @@ -1295,7 +1299,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // SHARING // If there are available RBs left in the slice, allocate them to the highest priority UEs if (RC.mac[Mod_id]->slice_info.intraslice_share_active) { - dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_id, + dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_idx, min_rb_unit, nb_rbs_required, nb_rbs_accounted, @@ -1369,7 +1373,8 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", - Mod_id, slice_id, UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]); + Mod_id, RC.mac[Mod_id]->slice_info.dl[slice_idx].id, UE_id, + ue_sched_ctl->pre_nb_available_rbs[CC_id]); } } } @@ -1379,7 +1384,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, int min_rb_unit[NFAPI_CC_MAX], @@ -1432,7 +1437,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, if (UE_list->active[UE_id] != TRUE) continue; - if (!ue_dl_slice_membership(module_idP, UE_id, slice_id)) + if (!ue_dl_slice_membership(module_idP, UE_id, slice_idx)) continue; vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; @@ -1660,7 +1665,7 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, /// ULSCH PRE_PROCESSOR void ulsch_scheduler_pre_processor(module_id_t module_idP, - slice_id_t slice_id, + int slice_idx, int frameP, sub_frame_t subframeP, unsigned char sched_subframeP, @@ -1684,7 +1689,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - assign_max_mcs_min_rb(module_idP, slice_id, frameP, subframeP, first_rb); + assign_max_mcs_min_rb(module_idP, slice_idx, frameP, subframeP, first_rb); LOG_D(MAC, "In ulsch_preprocessor: sort ue \n"); // sort ues @@ -1706,9 +1711,9 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][i]; UE_template = &UE_list->UE_template[CC_id][i]; - if (!ue_ul_slice_membership(module_idP, i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; - if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { + if (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) { total_ue_count[CC_id] += 1; } } @@ -1727,7 +1732,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_ul_slice_membership(module_idP, UE_id, slice_id)) + if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) continue; LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, @@ -1751,11 +1756,11 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = - nb_rbs_allowed_slice(sli->ul[slice_id].pct, N_RB_UL); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = + nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); - first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; - available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); if (total_ue_count[CC_id] == 0) { @@ -1784,7 +1789,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_ul_slice_membership(module_idP, i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; @@ -1803,7 +1808,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; } else { nb_allocated_rbs[CC_id][UE_id] = - cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_id], + cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_idx], average_rbs_per_user[CC_id]); } @@ -1825,7 +1830,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_ul_slice_membership(module_idP, i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; UE_id = i; @@ -1836,8 +1841,8 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); - first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; - available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); total_remaining_rbs[CC_id] = available_rbs - total_allocated_rbs[CC_id]; @@ -1846,17 +1851,17 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, } if (r == 0) { - while ((UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) - && (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_id]) + while ((UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) + && (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_idx]) && (total_remaining_rbs[CC_id] > 0)) { nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id] + 1, - UE_template->pre_allocated_nb_rb_ul[slice_id]); + UE_template->pre_allocated_nb_rb_ul[slice_idx]); total_remaining_rbs[CC_id]--; total_allocated_rbs[CC_id]++; } } else { - UE_template->pre_allocated_nb_rb_ul[slice_id] = + UE_template->pre_allocated_nb_rb_ul[slice_idx] = nb_allocated_rbs[CC_id][UE_id]; LOG_D(MAC, "******************UL Scheduling Information for UE%d CC_id %d ************************\n", @@ -1864,7 +1869,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, LOG_D(MAC, "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", module_idP, UE_id, CC_id, - UE_template->pre_allocated_nb_rb_ul[slice_id]); + UE_template->pre_allocated_nb_rb_ul[slice_idx]); } } } @@ -1872,7 +1877,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, } void -assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, +assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, uint16_t * first_rb) { @@ -1902,16 +1907,16 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_ul_slice_membership(module_idP, i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; if (UE_list->UE_sched_ctrl[i].phr_received == 1) { /* if we've received the power headroom information the UE, we can go to * maximum mcs */ - mcs = cmin(20, sli->ul[slice_id].maxmcs); + mcs = cmin(20, sli->ul[slice_idx].maxmcs); } else { /* otherwise, limit to QPSK PUSCH */ - mcs = cmin(10, sli->ul[slice_id].maxmcs); + mcs = cmin(10, sli->ul[slice_idx].maxmcs); } UE_id = i; @@ -1933,8 +1938,8 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = - nb_rbs_allowed_slice(sli->ul[slice_id].pct, N_RB_UL); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = + nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; if (bytes_to_schedule < 0) bytes_to_schedule = 0; @@ -1957,8 +1962,8 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs } - first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; - available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); while ((tbs < bits_to_schedule) @@ -1979,13 +1984,13 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, } UE_template->pre_allocated_rb_table_index_ul = rb_table_index; - UE_template->pre_allocated_nb_rb_ul[slice_id] = rb_table[rb_table_index]; + UE_template->pre_allocated_nb_rb_ul[slice_idx] = rb_table[rb_table_index]; LOG_D(MAC, "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", module_idP, frameP, subframeP, UE_id, CC_id, UE_template->pre_assigned_mcs_ul, UE_template->pre_allocated_rb_table_index_ul, - UE_template->pre_allocated_nb_rb_ul[slice_id], + UE_template->pre_allocated_nb_rb_ul[slice_idx], UE_template->phr_info, tx_power); } else { /* if UE has pending scheduling request then pre-allocate 3 RBs */ @@ -1994,11 +1999,11 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, /* use QPSK mcs */ UE_template->pre_assigned_mcs_ul = 10; UE_template->pre_allocated_rb_table_index_ul = 2; - UE_template->pre_allocated_nb_rb_ul[slice_id] = 3; + UE_template->pre_allocated_nb_rb_ul[slice_idx] = 3; } else { UE_template->pre_assigned_mcs_ul = 0; UE_template->pre_allocated_rb_table_index_ul = -1; - UE_template->pre_allocated_nb_rb_ul[slice_id] = 0; + UE_template->pre_allocated_nb_rb_ul[slice_idx] = 0; } } } From 1d23a64cedb75aaacebfc2cc66fc14eeafca149f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 18 Apr 2018 19:16:58 +0200 Subject: [PATCH 24/99] bugfix: memset using the right size --- openair2/LAYER2/MAC/pre_processor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index f951b065c6..36e5cfa4f1 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1259,7 +1259,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, #endif // Initialize scheduling information for all active UEs - memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results)); + memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results[slice_idx])); // FIXME: After the memset above, some of the resets in reset() are redundant dlsch_scheduler_pre_processor_reset(Mod_id, slice_idx, frameP, subframeP, min_rb_unit, From 59fc7832fab7ce55e438150cee942f624be4c221 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 18 Apr 2018 19:17:40 +0200 Subject: [PATCH 25/99] bugfixes: set max UL MCS to 20, improve sched loading message --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 3 ++- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index d27ef6c40e..0d5dd38b5c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -465,7 +465,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in sli->dl[i].sched_cb = dlsym(NULL, sli->dl[i].sched_name); sli->dl[i].update_sched = 0; sli->dl[i].update_sched_current = 0; - LOG_I(MAC, "update dl scheduler slice index %d ID %d\n", i, sli->dl[i].id); + LOG_I(MAC, "update dl scheduler (%s) slice index %d ID %d\n", + sli->dl[i].sched_name, i, sli->dl[i].id); } if (sli->tot_pct_dl <= 1.0) { // the new total RB share is within the range diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 4197ed6ba3..684a74f0f7 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1068,7 +1068,8 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, //sli->tot_pct_ul_current += sli->ul[i].pct; //if (sli->tot_pct_ul_current > 1) //sli->tot_pct_ul_current = 1; - LOG_I(MAC,"update ul scheduler slice %d\n", i); + LOG_I(MAC,"update ul scheduler (%s) slice index %d ID %d\n", + sli->ul[i].sched_name, i, sli->ul[i].id); } // the new total RB share is within the range if (sli->tot_pct_ul <= 1.0){ @@ -1097,7 +1098,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, // check if the slice max MCS, and log the console if (sli->ul[i].maxmcs_current != sli->ul[i].maxmcs){ - if ((sli->ul[i].maxmcs >= 0) && (sli->ul[i].maxmcs <= 16)){ + if ((sli->ul[i].maxmcs >= 0) && (sli->ul[i].maxmcs <= 20)){ LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", module_idP, sli->ul[i].id, frameP, subframeP, sli->ul[i].maxmcs_current, sli->ul[i].maxmcs); From b29e20d4dd0d72646c4bc0d1b6d2ad7a53bb14ba Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Apr 2018 14:32:44 +0200 Subject: [PATCH 26/99] MAC sched slicing: sort only relevant slices --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 0d5dd38b5c..34f8fe0b85 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -2353,9 +2353,10 @@ static int slice_priority_compare(const void *_a, const void *_b, void *_c) void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]) { int i; - for (i = 0; i < MAX_NUM_SLICES; ++i) { + for (i = 0; i < RC.mac[Mod_id]->slice_info.n_dl; ++i) { slice_list[i] = i; } - qsort_r(slice_list, MAX_NUM_SLICES, sizeof(int), slice_priority_compare, &Mod_id); + qsort_r(slice_list, RC.mac[Mod_id]->slice_info.n_dl, sizeof(int), + slice_priority_compare, &Mod_id); } From de4ebe09144488197f65f4a10ea94e5b281638ae Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Apr 2018 16:47:33 +0200 Subject: [PATCH 27/99] remove warnings (comment concerned lines) --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 4 ++-- openair2/LAYER2/MAC/pre_processor.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 34f8fe0b85..ccc5a944a7 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1763,7 +1763,7 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ int UE_id, CC_id, i; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; - UE_sched_ctrl *ue_sched_ctl; + //UE_sched_ctrl *ue_sched_ctl; for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (i = 0; i < sli->n_dl; ++i) { @@ -1773,7 +1773,7 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ sort_UEs(Mod_id, (uint8_t)i, frameP, subframeP); for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + //ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; // TODO: Do something here // ue_sched_ctl->pre_nb_available_rbs[CC_id]; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 36e5cfa4f1..8334219371 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -621,7 +621,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int total_ue_count[NFAPI_CC_MAX]; int ue_count_newtx[NFAPI_CC_MAX]; int ue_count_retx[NFAPI_CC_MAX]; - uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + //uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -634,9 +634,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ue_count_retx[CC_id] = 0; rbs_retx[CC_id] = 0; average_rbs_per_user[CC_id] = 0; - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - ue_retx_flag[CC_id][UE_id] = 0; - } + //for (UE_id = 0; UE_id < NFAPI_CC_MAX; ++UE_id) { + // ue_retx_flag[CC_id][UE_id] = 0; + //} } // Find total UE count, and account the RBs required for retransmissions @@ -665,7 +665,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; rbs_retx[CC_id] += nb_rbs_required[CC_id][UE_id]; ue_count_retx[CC_id]++; - ue_retx_flag[CC_id][UE_id] = 1; + //ue_retx_flag[CC_id][UE_id] = 1; } else { ue_count_newtx[CC_id]++; } @@ -777,11 +777,11 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, { int UE_id, CC_id; int i; +#ifdef TM5 uint8_t transmission_mode; - +#endif uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; int N_RBG[NFAPI_CC_MAX]; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask); @@ -801,7 +801,9 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; nb_rbs_remaining[CC_id][UE_id] = nb_rbs_accounted[CC_id][UE_id]; +#ifdef TM5 transmission_mode = get_tmode(Mod_id, CC_id, UE_id); +#endif if (nb_rbs_required[CC_id][UE_id] > 0) LOG_D(MAC, @@ -1004,7 +1006,9 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, { int UE_id, CC_id; int i; +#ifdef TM5 uint8_t transmission_mode; +#endif UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; int N_RBG[NFAPI_CC_MAX]; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; @@ -1030,7 +1034,9 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, nb_rbs_required[CC_id][UE_id] - nb_rbs_accounted[CC_id][UE_id] + nb_rbs_remaining[CC_id][UE_id]; if (nb_rbs_remaining[CC_id][UE_id] < 0) abort(); +#ifdef TM5 transmission_mode = get_tmode(Mod_id, CC_id, UE_id); +#endif if (nb_rbs_required[CC_id][UE_id] > 0) LOG_D(MAC, From 9d75b5c3b79d3d0bd4a23b80a6cdab9fad686c69 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 16:03:27 +0200 Subject: [PATCH 28/99] Add FlexRAN RAN API for slice configuration adds support for: * create/remove slices * change UE-slice association * read/write slice parameters * find slice index via ID --- openair2/ENB_APP/flexran_agent_ran_api.c | 448 +++++++++++++++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 152 ++++++++ 2 files changed, 600 insertions(+) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index e39d676061..9b6ecae593 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1393,3 +1393,451 @@ float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0; return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; } + +int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return -1; + int slice_idx = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id]; + if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl) + return RC.mac[mod_id]->slice_info.dl[slice_idx].id; + return 0; +} + +void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return; + if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; + if (!flexran_dl_slice_exists(mod_id, slice_idx)) return; + RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id] = slice_idx; +} + +int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return -1; + int slice_idx = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id]; + if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul) + return RC.mac[mod_id]->slice_info.ul[slice_idx].id; + return 0; +} + +void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return; + if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; + if (!flexran_ul_slice_exists(mod_id, slice_idx)) return; + RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id] = slice_idx; +} + +int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl; +} + +int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx) +{ + if (!mac_is_present(mod_id)) return -1; + if (!flexran_dl_slice_exists(mod_id, slice_default_values_idx)) return -1; + int newidx = RC.mac[mod_id]->slice_info.n_dl; + if (newidx >= MAX_NUM_SLICES) return -1; + + ++RC.mac[mod_id]->slice_info.n_dl; + flexran_set_dl_slice_id(mod_id, newidx, slice_id); + flexran_set_dl_slice_percentage(mod_id, newidx, + flexran_get_dl_slice_percentage(mod_id, slice_default_values_idx)); + flexran_set_dl_slice_isolation(mod_id, newidx, + flexran_get_dl_slice_isolation(mod_id, slice_default_values_idx)); + flexran_set_dl_slice_priority(mod_id, newidx, + flexran_get_dl_slice_priority(mod_id, slice_default_values_idx)); + flexran_set_dl_slice_position_low(mod_id, newidx, + flexran_get_dl_slice_position_low(mod_id, slice_default_values_idx)); + flexran_set_dl_slice_position_high(mod_id, newidx, + flexran_get_dl_slice_position_high(mod_id, slice_default_values_idx)); + flexran_set_dl_slice_maxmcs(mod_id, newidx, + flexran_get_dl_slice_maxmcs(mod_id, slice_default_values_idx)); + Protocol__FlexDlSorting *sorting = NULL; + int n = flexran_get_dl_slice_sorting(mod_id, slice_default_values_idx, &sorting); + flexran_set_dl_slice_sorting(mod_id, newidx, sorting, n); + free(sorting); + flexran_set_dl_slice_accounting_policy(mod_id, newidx, + flexran_get_dl_slice_accounting_policy(mod_id, slice_default_values_idx)); + flexran_set_dl_slice_scheduler_name(mod_id, newidx, + flexran_get_dl_slice_scheduler_name(mod_id, slice_default_values_idx)); + return newidx; +} + +int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + int n = sli->n_dl; + for (int i = 0; i < n; i++) { + if (sli->dl[i].id == slice_id) return i; + } + return -1; +} + +int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + if (sli->n_dl <= 1) return -1; + + --sli->n_dl; + /* move last element to the position of the removed one */ + if (slice_idx != sli->n_dl) + memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl])); + + /* all UEs that have been in the old slice are put into slice index 0 */ + int *assoc_list = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx; + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { + if (assoc_list[i] == slice_idx) + assoc_list[i] = 0; + } + return sli->n_dl; +} + +int flexran_get_num_dl_slices(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.n_dl; +} + +int flexran_get_intraslice_sharing_active(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.intraslice_share_active; +} +void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.intraslice_share_active = intraslice_active; +} + +int flexran_get_interslice_sharing_active(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.interslice_share_active; +} +void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.interslice_share_active = interslice_active; +} + +slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].id; +} +void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].id = slice_id; +} + +int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].pct * 100.0f; +} +void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].pct = percentage / 100.0f; +} + +int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].isol; +} +void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].isol = is_isolated; +} + +int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].prio; +} +void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].prio = priority; +} + +int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low; +} +void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low = poslow; +} + +int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high; +} +void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high = poshigh; +} + +int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs; +} +void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs = maxmcs; +} + +int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) +{ + if (!mac_is_present(mod_id)) return -1; + if (!(*sorting_list)) { + *sorting_list = calloc(CR_NUM, sizeof(Protocol__FlexDlSorting)); + if (!(*sorting_list)) return -1; + } + uint32_t policy = RC.mac[mod_id]->slice_info.dl[slice_idx].sorting; + for (int i = 0; i < CR_NUM; i++) { + switch (policy >> 4 * (CR_NUM - 1 - i) & 0xF) { + case CR_ROUND: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; + break; + case CR_SRB12: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_SRB12; + break; + case CR_HOL: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_HOL; + break; + case CR_LC: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LC; + break; + case CR_CQI: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_CQI; + break; + case CR_LCP: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LCP; + break; + default: + /* this should not happen, but a "default" */ + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; + break; + } + } + return CR_NUM; +} +void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) +{ + if (!mac_is_present(mod_id)) return; + uint32_t policy = 0; + for (int i = 0; i < n && i < CR_NUM; i++) { + switch (sorting_list[i]) { + case PROTOCOL__FLEX_DL_SORTING__CR_ROUND: + policy = policy << 4 | CR_ROUND; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_SRB12: + policy = policy << 4 | CR_SRB12; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_HOL: + policy = policy << 4 | CR_HOL; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_LC: + policy = policy << 4 | CR_LC; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_CQI: + policy = policy << 4 | CR_CQI; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_LCP: + policy = policy << 4 | CR_LCP; + break; + default: /* suppresses warnings */ + policy = policy << 4 | CR_ROUND; + break; + } + } + /* fill up with 0 == CR_ROUND */ + if (CR_NUM > n) policy = policy << 4 * (CR_NUM - n); + RC.mac[mod_id]->slice_info.dl[slice_idx].sorting = policy; +} + +Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; + switch (RC.mac[mod_id]->slice_info.dl[slice_idx].accounting) { + case POL_FAIR: + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; + case POL_GREEDY: + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY; + default: + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; + } +} +void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) +{ + if (!mac_is_present(mod_id)) return; + switch (accounting) { + case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR: + RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; + return; + case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY: + RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_GREEDY; + return; + default: + RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; + return; + } +} + +char *flexran_get_dl_slice_scheduler_name(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name; +} +void flexran_set_dl_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = name; + RC.mac[mod_id]->slice_info.dl[slice_idx].update_sched = 1; +} + +int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx) +{ + if (!mac_is_present(mod_id)) return -1; + if (!flexran_ul_slice_exists(mod_id, slice_default_values_idx)) return -1; + int newidx = RC.mac[mod_id]->slice_info.n_ul; + if (newidx >= MAX_NUM_SLICES) return -1; + + ++RC.mac[mod_id]->slice_info.n_ul; + flexran_set_ul_slice_id(mod_id, newidx, slice_id); + flexran_set_ul_slice_percentage(mod_id, newidx, + flexran_get_ul_slice_percentage(mod_id, slice_default_values_idx)); + /*flexran_set_ul_slice_isolation(mod_id, newidx, + flexran_get_ul_slice_isolation(mod_id, slice_default_values_idx)); + flexran_set_ul_slice_priority(mod_id, newidx, + flexran_get_ul_slice_priority(mod_id, slice_default_values_idx));*/ + flexran_set_ul_slice_first_rb(mod_id, newidx, + flexran_get_ul_slice_first_rb(mod_id, slice_default_values_idx)); + flexran_set_ul_slice_maxmcs(mod_id, newidx, + flexran_get_ul_slice_maxmcs(mod_id, slice_default_values_idx)); + /*Protocol__FlexUlSorting *sorting = NULL; + int n = flexran_get_ul_slice_sorting(mod_id, slice_default_values_idx, &sorting); + flexran_set_ul_slice_sorting(mod_id, newidx, sorting, n); + free(sorting);*/ + /*flexran_set_ul_slice_accounting_policy(mod_id, newidx, + flexran_get_ul_slice_accounting_policy(mod_id, slice_default_values_idx));*/ + flexran_set_ul_slice_scheduler_name(mod_id, newidx, + flexran_get_ul_slice_scheduler_name(mod_id, slice_default_values_idx)); + return newidx; +} + +int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + int n = sli->n_ul; + for (int i = 0; i < n; i++) { + if (sli->ul[i].id == slice_id) return i; + } + return -1; +} + +int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + if (sli->n_ul <= 1) return -1; + + --sli->n_ul; + /* move last element to the position of the removed one */ + if (slice_idx != sli->n_ul) + memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul])); + + /* all UEs that have been in the old slice are put into slice index 0 */ + int *assoc_list = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx; + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { + if (assoc_list[i] == slice_idx) + assoc_list[i] = 0; + } + return sli->n_ul; +} + +int flexran_get_num_ul_slices(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.n_ul; +} + +int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul; +} + +slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].id; +} +void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].id = slice_id; +} + +int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].pct * 100.0f; +} +void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].pct = percentage / 100.0f; +} + +int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb; +} + +void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb = first_rb; +} + +int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs; +} +void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs; +} + +char *flexran_get_ul_slice_scheduler_name(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name; +} +void flexran_set_ul_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = name; + RC.mac[mod_id]->slice_info.ul[slice_idx].update_sched = 1; +} diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index dacca55ab7..18cd353f71 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -504,3 +504,155 @@ int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); */ /*Get MNC PLMN identity neighbouring Cell*/ /* currently not implemented int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */ + +/************************** Slice configuration **************************/ + +/* Get the DL slice ID for a UE */ +int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id); + +/* Set the DL slice index(!) for a UE */ +void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); + +/* Get the UL slice ID for a UE */ +int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id); + +/* Set the UL slice index(!) for a UE */ +void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); + +/* Whether intraslice sharing is active, return boolean */ +int flexran_get_intraslice_sharing_active(mid_t mod_id); +/* Set whether intraslice sharing is active */ +void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active); + +/* Whether intraslice sharing is active, return boolean */ +int flexran_get_interslice_sharing_active(mid_t mod_id); +/* Set whether intraslice sharing is active */ +void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active); + +/* Get the number of slices in DL */ +int flexran_get_num_dl_slices(mid_t mod_id); + +/* Query slice existence in DL. Return is boolean value */ +int flexran_dl_slice_exists(mid_t mod_id, int slice_idx); + +/* Create slice in DL with values from another slice, returns the new slice index */ +int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx); +/* Finds slice in DL with given slice_id and returns slice index */ +int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in DL, returns new number of slices or -1 on error */ +int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); + +/* Get the ID of a slice in DL */ +slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx); +/* Set the ID of a slice in DL */ +void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); + +/* Get the RB share a slice in DL, value 0-100 */ +int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx); +/* Set the RB share a slice in DL, value 0-100 */ +void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage); + +/* Whether a slice in DL is isolated */ +int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx); +/* Set whether a slice in DL is isolated */ +void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated); + +/* Get the priority of a slice in DL */ +int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx); +/* Get the priority of a slice in DL */ +void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority); + +/* Get the lower end of the frequency range for the slice positioning in DL */ +int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx); +/* Set the lower end of the frequency range for the slice positioning in DL */ +void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow); + +/* Get the higher end of the frequency range for the slice positioning in DL */ +int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx); +/* Set the higher end of the frequency range for the slice positioning in DL */ +void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh); + +/* Get the maximum MCS for slice in DL */ +int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx); +/* Set the maximum MCS for slice in DL */ +void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); + +/* Get the sorting order of a slice in DL, return value is number of elements + * in sorting_list */ +int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list); +/* Set the sorting order of a slice in DL */ +void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n); + +/* Get the accounting policy for a slice in DL */ +Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx); +/* Set the accounting policy for a slice in DL */ +void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting); + +/* Get the scheduler name for a slice in DL */ +char *flexran_get_dl_slice_scheduler_name(mid_t mod_id, int slice_idx); +/* Set the scheduler name for a slice in DL */ +void flexran_set_dl_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name); + +/* Get the number of slices in UL */ +int flexran_get_num_ul_slices(mid_t mod_id); + +/* Query slice existence in UL. Return is boolean value */ +int flexran_ul_slice_exists(mid_t mod_id, int slice_idx); + +/* Create slice in UL with values from another slice, returns the new slice index */ +int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx); +/* Finds slice in UL with given slice_id and returns slice index */ +int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in UL */ +int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); + +/* Get the ID of a slice in UL */ +slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx); +/* Set the ID of a slice in UL */ +void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); + +/* Get the RB share a slice in UL, value 0-100 */ +int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx); +/* Set the RB share a slice in UL, value 0-100 */ +void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage); + +/* TODO Whether a slice in UL is isolated */ +/*int flexran_get_ul_slice_isolation(mid_t mod_id, int slice_idx);*/ +/* TODO Set whether a slice in UL is isolated */ +/*void flexran_set_ul_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);*/ + +/* TODO Get the priority of a slice in UL */ +/*int flexran_get_ul_slice_priority(mid_t mod_id, int slice_idx);*/ +/* TODO Set the priority of a slice in UL */ +/*void flexran_set_ul_slice_priority(mid_t mod_id, int slice_idx, int priority);*/ + +/* Get the first RB for allocation in a slice in UL */ +int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx); +/* Set the first RB for allocation in a slice in UL */ +void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb); + +/* TODO Get the number of RB for the allocation in a slice in UL */ +/*int flexran_get_ul_slice_length_rb(mid_t mod_id, int slice_idx);*/ +/* TODO Set the of number of RB for the allocation in a slice in UL */ +/*void flexran_set_ul_slice_length_rb(mid_t mod_id, int slice_idx, int poshigh);*/ + +/* Get the maximum MCS for slice in UL */ +int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx); +/* Set the maximum MCS for slice in UL */ +void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); + +/* TODO Get the sorting order of a slice in UL, return value is number of elements + * in sorting_list */ +/*int flexran_get_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting **sorting_list);*/ +/* TODO Set the sorting order of a slice in UL */ +/*void flexran_set_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting *sorting_list, int n);*/ + +/* TODO Get the accounting policy for a slice in UL */ +/*Protocol__UlAccountingPolicy flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx);*/ +/* TODO Set the accounting policy for a slice in UL */ +/*void flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__UlAccountingPolicy accountin);*/ + +/* Get the scheduler name for a slice in UL */ +char *flexran_get_ul_slice_scheduler_name(mid_t mod_id, int slice_idx); +/* Set the scheduler name for a slice in UL */ +void flexran_set_ul_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name); From fcaf237182b34efb436ee2d8b364e59dc608648b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 16:59:22 +0200 Subject: [PATCH 29/99] FlexRAN: Handle slice configuration Incoming slice configuration changes are buffered in an intermediate structure. The MAC scheduler periodically polls the agent about changes. If there has been a slice configuration change, apply it. --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 143 +++++ .../CONTROL_MODULES/MAC/flexran_agent_mac.h | 10 + .../MAC/flexran_agent_mac_internal.c | 523 ++++++++++++++++++ .../MAC/flexran_agent_mac_internal.h | 33 ++ openair2/LAYER2/MAC/eNB_scheduler.c | 4 + 5 files changed, 713 insertions(+) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 549c7eaa22..0c33026a38 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -52,6 +52,16 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; +/* the slice config as kept in the underlying system */ +Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB]; +/* a structure that keeps updates which will be reflected in slice_config later */ +Protocol__FlexSliceConfig *sc_update[NUM_MAX_ENB]; +/* indicates whether sc_update contains new data */ +int perform_slice_config_update_count = 1; +/* queue of incoming new UE<>slice association commands */ +Protocol__FlexUeConfig *ue_slice_assoc_update[NUM_MAX_UE]; +int n_ue_slice_assoc_updates = 0; + int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, @@ -1372,8 +1382,141 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { return 0; } +void flexran_create_config_structures(mid_t mod_id) +{ + int i; + int n_dl = flexran_get_num_dl_slices(mod_id); + int m_ul = flexran_get_num_ul_slices(mod_id); + slice_config[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); + sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); + if (!slice_config[mod_id] || !sc_update[mod_id]) return; + for (i = 0; i < n_dl; i++) { + flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); + } + for (i = 0; i < m_ul; i++) { + flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); + } +} +void flexran_check_and_remove_slices(mid_t mod_id) +{ + int i; + Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl; + size_t n_dl = sc_update[mod_id]->n_dl; + for (i = 0; i < n_dl; i++) { + /* remove slices whose percentage is zero */ + if (dl[i]->percentage > 0) continue; + if (flexran_remove_dl_slice(mod_id, i) < 1) { + LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", + mod_id, i, dl[i]->id); + continue; + } + LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", + mod_id, i, dl[i]->id); + /* don't update slice_config, it will be read in below */ + /* we need to memcpy the higher slice to the position we just deleted */ + memcpy(dl[i], dl[n_dl-1], sizeof(*dl[n_dl-1])); + --sc_update[mod_id]->n_dl; + } + Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul; + size_t n_ul = sc_update[mod_id]->n_ul; + for (i = 0; i < n_ul; i++) { + if (ul[i]->percentage > 0) continue; + if (flexran_remove_ul_slice(mod_id, i) < 1) { + LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", + mod_id, i, ul[i]->id); + continue; + } + LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", + mod_id, i, ul[i]->id); + /* see DL remarks */ + memcpy(ul[i], ul[n_ul-1], sizeof(*ul[n_ul-1])); + --sc_update[mod_id]->n_ul; + } +} +void flexran_agent_slice_update(mid_t mod_id) +{ + int i; + int changes = 0; + if (perform_slice_config_update_count <= 0) return; + perform_slice_config_update_count--; + if (!slice_config[mod_id]) { + /* if the configuration does not exist for agent, create from eNB structure + * and exit */ + flexran_create_config_structures(mod_id); + return; + } + + /********* read existing config *********/ + /* simply update slice_config all the time and write new config + * (apply_new_slice_dl_config() only updates if changes are necessary) */ + slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); + slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); + for (i = 0; i < slice_config[mod_id]->n_dl; i++) { + flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + } + for (i = 0; i < slice_config[mod_id]->n_ul; i++) { + flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + } + + /* in case we tried to add a slice and it failed (e.g. due to high sum + * percentage being too high), revert to the correct number of slices. + * Also, do not write if we try the last time */ + if (perform_slice_config_update_count == 1) { + if (slice_config[mod_id]->n_dl != sc_update[mod_id]->n_dl) { + sc_update[mod_id]->n_dl = slice_config[mod_id]->n_dl; + LOG_W(FLEXRAN_AGENT, "[%d] reverting to original number of %ld DL slices\n", + mod_id, sc_update[mod_id]->n_dl); + } + if (slice_config[mod_id]->n_ul != sc_update[mod_id]->n_ul) { + sc_update[mod_id]->n_ul = slice_config[mod_id]->n_ul; + LOG_W(FLEXRAN_AGENT, "[%d] reverting to original number of %ld UL slices\n", + mod_id, sc_update[mod_id]->n_ul); + } + return; + } + + /********* write new config *********/ + /* check for removal (sc_update[X]->dl[Y].percentage == 0) + * and update sc_update & slice_config accordingly */ + flexran_check_and_remove_slices(mod_id); + + /* create new DL and UL slices if necessary */ + for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) { + flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id, 0); + slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); + flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + } + for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) { + flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id, 0); + slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); + flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + } + for (i = 0; i < slice_config[mod_id]->n_dl; i++) { + changes += apply_new_slice_dl_config(mod_id, + slice_config[mod_id]->dl[i], + sc_update[mod_id]->dl[i]); + } + for (i = 0; i < slice_config[mod_id]->n_ul; i++) { + changes += apply_new_slice_ul_config(mod_id, + slice_config[mod_id]->ul[i], + sc_update[mod_id]->ul[i]); + } + if (n_ue_slice_assoc_updates > 0) { + changes += apply_ue_slice_assoc_update(mod_id); + } + if (changes > 0) + LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes); + +} + +Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) +{ + return slice_config[mod_id]; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 03e7def95e..0d686a53ee 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -87,4 +87,14 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface); /*Unregister technology specific callbacks*/ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface*xface); +/*************************************** + * FlexRAN agent - slice configuration * + ***************************************/ + +/* Inform controller about possibility to update slice configuration */ +void flexran_agent_slice_update(mid_t mod_id); + +/* return a pointer to the current config */ +Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id); + #endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 2acee0686f..435e8da064 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -32,6 +32,13 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" +/* from flexran_agent_mac.c */ +extern Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB]; +extern Protocol__FlexSliceConfig *sc_update[NUM_MAX_ENB]; +extern int perform_slice_config_update_count; +extern Protocol__FlexUeConfig *ue_slice_assoc_update[NUM_MAX_UE]; +extern int n_ue_slice_assoc_updates; + Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message, Protocol__FlexranMessage *old_message) { @@ -899,3 +906,519 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { return -1; } + +Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) +{ + int i; + Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig)); + if (!fsc) return NULL; + protocol__flex_slice_config__init(fsc); + + /* say there are n_dl slices but reserve memory for up to MAX_NUM_SLICES so + * we don't need to reserve again later */ + fsc->n_dl = n_dl; + fsc->dl = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexDlSlice *)); + if (!fsc->dl) fsc->n_dl = 0; + for (i = 0; i < MAX_NUM_SLICES; i++) { + fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice)); + if (!fsc->dl[i]) continue; + protocol__flex_dl_slice__init(fsc->dl[i]); + } + + /* as above */ + fsc->n_ul = m_ul; + fsc->ul = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexUlSlice *)); + if (!fsc->ul) fsc->n_ul = 0; + for (i = 0; i < MAX_NUM_SLICES; i++) { + fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice)); + if (!fsc->ul[i]) continue; + protocol__flex_ul_slice__init(fsc->ul[i]); + } + return fsc; +} + +void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice) +{ + dl_slice->id = flexran_get_dl_slice_id(mod_id, slice_idx); + dl_slice->has_id = 1; + /* read label from corresponding sc_update entry or give default */ + dl_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; + dl_slice->has_label = 1; + for (int i = 0; i < sc_update[mod_id]->n_dl; i++) { + if (sc_update[mod_id]->dl[i]->id == dl_slice->id + && sc_update[mod_id]->dl[i]->has_label) { + dl_slice->label = sc_update[mod_id]->dl[i]->label; + break; + } + } + dl_slice->percentage = flexran_get_dl_slice_percentage(mod_id, slice_idx); + dl_slice->has_percentage = 1; + dl_slice->isolation = flexran_get_dl_slice_isolation(mod_id, slice_idx); + dl_slice->has_isolation = 1; + dl_slice->priority = flexran_get_dl_slice_priority(mod_id, slice_idx); + dl_slice->has_priority = 1; + dl_slice->position_low = flexran_get_dl_slice_position_low(mod_id, slice_idx); + dl_slice->has_position_low = 1; + dl_slice->position_high = flexran_get_dl_slice_position_high(mod_id, slice_idx); + dl_slice->has_position_high = 1; + dl_slice->maxmcs = flexran_get_dl_slice_maxmcs(mod_id, slice_idx); + dl_slice->has_maxmcs = 1; + dl_slice->n_sorting = flexran_get_dl_slice_sorting(mod_id, slice_idx, &dl_slice->sorting); + if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL; + dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx); + dl_slice->has_accounting = 1; + dl_slice->scheduler_name = flexran_get_dl_slice_scheduler_name(mod_id, slice_idx); +} + +void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice) +{ + ul_slice->id = flexran_get_ul_slice_id(mod_id, slice_idx); + ul_slice->has_id = 1; + /* read label from corresponding sc_update entry or give default */ + ul_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; + ul_slice->has_label = 1; + for (int i = 0; i < sc_update[mod_id]->n_ul; i++) { + if (sc_update[mod_id]->ul[i]->id == ul_slice->id + && sc_update[mod_id]->ul[i]->has_label) { + ul_slice->label = sc_update[mod_id]->ul[i]->label; + break; + } + } + ul_slice->percentage = flexran_get_ul_slice_percentage(mod_id, slice_idx); + ul_slice->has_percentage = 1; + /*ul_slice->isolation = flexran_get_ul_slice_isolation(mod_id, slice_idx);*/ + ul_slice->has_isolation = 0; + /*ul_slice->priority = flexran_get_ul_slice_priority(mod_id, slice_idx);*/ + ul_slice->has_priority = 0; + ul_slice->first_rb = flexran_get_ul_slice_first_rb(mod_id, slice_idx); + ul_slice->has_first_rb = 1; + /*ul_slice-> = flexran_get_ul_slice_length_rb(mod_id, slice_idx); + ul_slice->has_length_rb = 0;*/ + ul_slice->maxmcs = flexran_get_ul_slice_maxmcs(mod_id, slice_idx); + ul_slice->has_maxmcs = 1; + ul_slice->n_sorting = 0; + /*if (ul_slice->sorting) { + free(ul_slice->sorting); + ul_slice->sorting = NULL; + } + ul_slice->n_sorting = flexran_get_ul_slice_sorting(mod_id, slice_idx, &ul_slice->sorting); + if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/ + /*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/ + ul_slice->has_accounting = 0; + ul_slice->scheduler_name = flexran_get_ul_slice_scheduler_name(mod_id, slice_idx); +} + +void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) +{ + if (update->has_label && update->label != exist->label) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update label: %d -> %d\n", + update->id, exist->label, update->label); + exist->label = update->label; + } + if (update->has_percentage && update->percentage != exist->percentage) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update percentage: %d -> %d\n", + update->id, exist->percentage, update->percentage); + exist->percentage = update->percentage; + } + if (update->has_isolation && update->isolation != exist->isolation) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update isolation: %d -> %d\n", + update->id, exist->isolation, update->isolation); + exist->isolation = update->isolation; + } + if (update->has_priority && update->priority != exist->priority) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update priority: %d -> %d\n", + update->id, exist->priority, update->priority); + exist->priority = update->priority; + } + if (update->has_position_low && update->position_low != exist->position_low) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_low: %d -> %d\n", + update->id, exist->position_low, update->position_low); + exist->position_low = update->position_low; + } + if (update->has_position_high && update->position_high != exist->position_high) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_high: %d -> %d\n", + update->id, exist->position_high, update->position_high); + exist->position_high = update->position_high; + } + if (update->has_maxmcs && update->maxmcs != exist->maxmcs) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update maxmcs: %d -> %d\n", + update->id, exist->maxmcs, update->maxmcs); + exist->maxmcs = update->maxmcs; + } + int sorting_update = 0; + int n = min(exist->n_sorting, update->n_sorting); + /* check whether something has changed. If update->n_sorting is 0, + * sorting_update will remain false, so no update will be done */ + int i = 0; + while(i < n && !sorting_update) { + sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]); + i++; + } + if (sorting_update) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update sorting array\n", update->id); + if (exist->n_sorting != update->n_sorting) + LOG_W(FLEXRAN_AGENT, "[slice %d] only writing %d elements\n", + update->id, n); + for (int i = 0; i < n; i++) + exist->sorting[i] = update->sorting[i]; + } + if (update->has_accounting && update->accounting != exist->accounting) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update accounting: %d -> %d\n", + update->id, exist->accounting, update->accounting); + exist->accounting = update->accounting; + } + if (update->scheduler_name + && strcmp(update->scheduler_name, exist->scheduler_name) != 0) { + LOG_W(FLEXRAN_AGENT, "[DL slice %d] ignoring new scheduler name \"%s\"!\n", + update->id, update->scheduler_name); + } +} + +void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update) +{ + if (update->has_label && update->label != exist->label) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update label: %d -> %d\n", + update->id, exist->label, update->label); + exist->label = update->label; + } + if (update->has_percentage && update->percentage != exist->percentage) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update percentage: %d -> %d\n", + update->id, exist->percentage, update->percentage); + exist->percentage = update->percentage; + } + if (update->has_isolation && update->isolation != exist->isolation) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update isolation: %d -> %d\n", + update->id, exist->isolation, update->isolation); + exist->isolation = update->isolation; + } + if (update->has_priority && update->priority != exist->priority) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update priority: %d -> %d\n", + update->id, exist->priority, update->priority); + exist->priority = update->priority; + } + if (update->has_first_rb && update->first_rb != exist->first_rb) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update first_rb: %d -> %d\n", + update->id, exist->first_rb, update->first_rb); + exist->first_rb = update ->first_rb; + } + /*if (update->has_length_rb && update->lenght_rb != exist->lenght_rb) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update lenght_rb: %d -> %d\n", + update->id, exist->lenght_rb, update->lenght_rb); + exist->lenght_rb = update->lenght_rb; + }*/ + if (update->has_maxmcs && update->maxmcs != exist->maxmcs) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update maxmcs: %d -> %d\n", + update->id, exist->maxmcs, update->maxmcs); + exist->maxmcs = update->maxmcs; + } + int sorting_update = 0; + int n = min(exist->n_sorting, update->n_sorting); + /* check whether something has changed. If update-> n_sorting is 0, + * sorting_update will remain false, so no update will be done */ + int i = 0; + while (i < n && !sorting_update) { + sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]); + i++; + } + if (sorting_update) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update sorting array\n", update->id); + if (exist->n_sorting != update->n_sorting) + LOG_W(FLEXRAN_AGENT, "[UL slice %d] only writing %d elements\n", + update->id, n); + for (i = 0; i < n; i++) + exist->sorting[i] = update->sorting[i]; + } + if (update->has_accounting && update->accounting != exist->accounting) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update accounting: %d -> %d\n", + update->id, exist->accounting, update->accounting); + exist->accounting = update->accounting; + } + if (update->scheduler_name + && strcmp(update->scheduler_name, exist->scheduler_name) != 0) { + LOG_W(FLEXRAN_AGENT, "[UL slice %d] ignoring new scheduler name \"%s\"!\n", + update->id, update->scheduler_name); + } +} + +void prepare_update_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *dls) +{ + if (!dls->has_id) { + LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id); + return; + } + /* a percentage of zero will be interpreted as removal command */ + if (sc_update[mod_id]->n_dl >= MAX_NUM_SLICES + && (!dls->has_percentage || dls->percentage > 0)) { + LOG_E(FLEXRAN_AGENT, "[%d] Cannot create more than %ld slices in DL\n", + mod_id, sc_update[mod_id]->n_dl); + return; + } + if (sc_update[mod_id]->n_dl == 1 && dls->has_percentage && dls->percentage == 0) { + LOG_E(FLEXRAN_AGENT, "[%d] Cannot delete last slice ID %d in DL\n", + mod_id, sc_update[mod_id]->dl[0]->id); + return; + } + + Protocol__FlexDlSlice *to = NULL; + for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) { + if (dls->id == sc_update[mod_id]->dl[i]->id) { + to = sc_update[mod_id]->dl[i]; + break; + } + } + + /* create new slice -> read contents from existing slice config index 0 */ + if (!to) { + LOG_I(FLEXRAN_AGENT, + "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n", + mod_id, dls->id); + to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; + sc_update[mod_id]->n_dl++; + memcpy(to, slice_config[mod_id]->dl[0], sizeof(*to)); + to->id = dls->id; + } + + overwrite_slice_config_dl(to, dls); +} + +void prepare_update_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *uls) +{ + if (!uls->has_id) { + LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id); + return; + } + /* a percentage of zero will be interpreted as removal command */ + if (sc_update[mod_id]->n_ul >= MAX_NUM_SLICES + && (!uls->has_percentage || uls->percentage > 0)) { + LOG_E(FLEXRAN_AGENT, "[%d] Cannot create more than %ld slices in UL\n", + mod_id, sc_update[mod_id]->n_ul); + return; + } + if (sc_update[mod_id]->n_ul == 1 && uls->has_percentage && uls->percentage == 0) { + LOG_E(FLEXRAN_AGENT, "[%d] Cannot delete last slice ID %d in UL\n", + mod_id, sc_update[mod_id]->ul[0]->id); + return; + } + + Protocol__FlexUlSlice *to = NULL; + for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) { + if (uls->id == sc_update[mod_id]->ul[i]->id) { + to = sc_update[mod_id]->ul[i]; + break; + } + } + + /* create new slice -> read contents from existing slice config index 0 */ + if (!to) { + LOG_I(FLEXRAN_AGENT, + "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n", + mod_id, uls->id); + to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; + sc_update[mod_id]->n_ul++; + memcpy(to, slice_config[mod_id]->ul[0], sizeof(*to)); + to->id = uls->id; + } + + overwrite_slice_config_ul(to, uls); +} + +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice) +{ + if (!sc_update[mod_id]) { + LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n"); + return; + } + if (slice->n_dl == 0) + LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); + for (int i = 0; i < slice->n_dl; i++) + prepare_update_slice_config_dl(mod_id, slice->dl[i]); + + if (slice->n_ul == 0) + LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id); + for (int i = 0; i < slice->n_ul; i++) + prepare_update_slice_config_ul(mod_id, slice->ul[i]); + + /* perform the slice configuration reads a couple of times. If there are + * inconsistencies (i.e. the MAC refuses a configuration), we will have a + * couple of warnings because the current configuration and the one in + * sc_update will be diverged */ + perform_slice_config_update_count = 3; +} + +int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc) +{ + /* not setting the old configuration is intentional, as it will be picked up + * later when reading the configuration. There is thus a direct feedback + * whether it has been set. */ + int changes = 0; + int n; + int slice_idx = flexran_find_dl_slice(mod_id, newc->id); + if (slice_idx < 0) { + LOG_W(FLEXRAN_AGENT, "cannot find index for slice ID %d\n", newc->id); + return 0; + } + if (oldc->percentage != newc->percentage) { + flexran_set_dl_slice_percentage(mod_id, slice_idx, newc->percentage); + changes++; + } + if (oldc->isolation != newc->isolation) { + flexran_set_dl_slice_isolation(mod_id, slice_idx, newc->isolation); + changes++; + } + if (oldc->priority != newc->priority) { + flexran_set_dl_slice_priority(mod_id, slice_idx, newc->priority); + changes++; + } + if (oldc->position_low != newc->position_low) { + flexran_set_dl_slice_position_low(mod_id, slice_idx, newc->position_low); + changes++; + } + if (oldc->position_high != newc->position_high) { + flexran_set_dl_slice_position_high(mod_id, slice_idx, newc->position_high); + changes++; + } + if (oldc->maxmcs != newc->maxmcs) { + flexran_set_dl_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); + changes++; + } + n = min(oldc->n_sorting, newc->n_sorting); + for (int i = 0; i < n; i++) { + if (oldc->sorting[i] != newc->sorting[i]) { + flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, n); + changes++; + break; + } + } + if (oldc->accounting != newc->accounting) { + flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); + changes++; + } + if (strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the DL scheduler is not supported, reverting\n", + mod_id, newc->id); + newc->scheduler_name = oldc->scheduler_name; + } + return changes; +} + +int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc) +{ + /* not setting the old configuration is intentional, as it will be picked up + * later when reading the configuration. There is thus a direct feedback + * whether it has been set. */ + int changes = 0; + int n; + int slice_idx = flexran_find_ul_slice(mod_id, newc->id); + if (slice_idx < 0) { + LOG_W(FLEXRAN_AGENT, "cannot find index for slice ID %d\n", newc->id); + return 0; + } + if (oldc->percentage != newc->percentage) { + flexran_set_ul_slice_percentage(mod_id, slice_idx, newc->percentage); + changes++; + } + if (oldc->isolation != newc->isolation) { + /*flexran_set_ul_slice_isolation(mod_id, slice_idx, newc->isolation); + *changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting isolation is not supported\n", + mod_id, slice_idx); + } + if (oldc->priority != newc->priority) { + /*flexran_set_ul_slice_priority(mod_id, slice_idx, newc->priority); + *changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the priority is not supported\n", + mod_id, slice_idx); + } + if (oldc->first_rb != newc->first_rb) { + flexran_set_ul_slice_first_rb(mod_id, slice_idx, newc->first_rb); + changes++; + } + /*if (oldc->length_rb != newc->length_rb) { + flexran_set_ul_slice_length_rb(mod_id, slice_idx, newc->length_rb); + changes++; + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting length_rb is not supported\n", + mod_id, slice_idx); + }*/ + if (oldc->maxmcs != newc->maxmcs) { + flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); + changes++; + } + n = min(oldc->n_sorting, newc->n_sorting); + for (int i = 0; i < n; i++) { + if (oldc->sorting[i] != newc->sorting[i]) { + /*flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); + changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", + mod_id, slice_idx); + break; + } + } + if (oldc->accounting != newc->accounting) { + /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting); + *changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", + mod_id, slice_idx); + } + if (strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the UL scheduler is not supported, reverting\n", + mod_id, slice_idx); + newc->scheduler_name = oldc->scheduler_name; + } + return changes; +} + +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) +{ + if (n_ue_slice_assoc_updates == NUM_MAX_UE) { + LOG_E(FLEXRAN_AGENT, + "[%d] can not handle flex_ue_config message, buffer is full; try again later\n", + mod_id); + return; + } + if (!ue_config->has_rnti) { + LOG_E(FLEXRAN_AGENT, + "[%d] cannot update UE to slice association, no RNTI in flex_ue_config message\n", + mod_id); + return; + } + if (ue_config->has_dl_slice_id) + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to DL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->dl_slice_id); + if (ue_config->has_ul_slice_id) + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to UL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->ul_slice_id); + ue_slice_assoc_update[n_ue_slice_assoc_updates++] = ue_config; + perform_slice_config_update_count = 2; +} + +int apply_ue_slice_assoc_update(mid_t mod_id) +{ + int i; + int changes = 0; + /* TODO should lock structure */ + for (i = 0; i < n_ue_slice_assoc_updates; i++) { + int ue_id = find_UE_id(mod_id, ue_slice_assoc_update[i]->rnti); + if (ue_slice_assoc_update[i]->has_dl_slice_id) { + int slice_idx = flexran_find_dl_slice(mod_id, ue_slice_assoc_update[i]->dl_slice_id); + if (flexran_dl_slice_exists(mod_id, slice_idx)) { + flexran_set_ue_dl_slice_idx(mod_id, ue_id, slice_idx); + changes++; + } else { + LOG_W(FLEXRAN_AGENT, "[%d] DL slice %d does not exist, refusing change\n", + mod_id, ue_slice_assoc_update[i]->dl_slice_id); + } + } + if (ue_slice_assoc_update[i]->has_ul_slice_id) { + int slice_idx = flexran_find_ul_slice(mod_id, ue_slice_assoc_update[i]->ul_slice_id); + if (flexran_ul_slice_exists(mod_id, slice_idx)) { + flexran_set_ue_ul_slice_idx(mod_id, ue_id, slice_idx); + changes++; + } else { + LOG_W(FLEXRAN_AGENT, "[%d] UL slice %d does not exist, refusing change\n", + mod_id, ue_slice_assoc_update[i]->ul_slice_id); + } + } + } + n_ue_slice_assoc_updates = 0; + return changes; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index f69e2cde40..2f8f3f8258 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -107,4 +107,37 @@ int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser); int load_dl_scheduler_function(mid_t mod_id, const char *function_name); +/*** Functions for handling a slice config ***/ + +/* allocate memory for a Protocol__FlexSliceConfig structure with n_dl DL slice + * configs and m_ul UL slice configs */ +Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul); + +/* read the DL slice config via the RAN into a given Protocol__FlexDlSlice + * struct */ +void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice); + +/* read the UL slice config via the RAN into a given Protocol__FlexUlSlice + * struct */ +void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice); + +/* reads content of slice over the sc_update structure, so that it can be + * applied later by performing a diff between slice_config and sc_update */ +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice); + +/* apply new configuration of slice in DL if there are changes between the + * parameters. Returns the number of changed parameters. */ +int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc); + +/* apply new configuration of slice in UL if there are changes between the + * parameters. Returns the number of changed parameters. */ +int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc); + +/* inserts a new ue_config into the structure keeping ue to slice association + * updates and marks so it can be applied */ +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); + +/* apply a new association between a UE and a slice (both DL and UL) */ +int apply_ue_slice_assoc_update(mid_t mod_id); + #endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/ diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index a2988f26d8..4dbf3cf36f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -703,6 +703,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2); } + if (mac_agent_registered[module_idP] && subframeP == 9) { + flexran_agent_slice_update(module_idP); + } + stop_meas(&RC.mac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME From 92a3b07bca708adc4e3fd9c0520123f6e96592ce Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 27 Mar 2018 18:28:14 +0200 Subject: [PATCH 30/99] FlexRAN: send slice ID to which UE belongs + reformat - flexran_agent_ue_config_reply() and flexran_agent_ue_state_change() send slice_id --- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 248 +++++++++--------- 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index b4bf029373..34833ca898 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -76,147 +76,147 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch config->has_rnti = 1; config->rnti = rnti; } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED - || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { - int i = find_UE_id(mod_id, rnti); - config->has_rnti = 1; - config->rnti = rnti; - if(flexran_get_time_alignment_timer(mod_id,i) != -1) { - config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); - config->has_time_alignment_timer = 1; - } - if(flexran_get_meas_gap_config(mod_id,i) != -1){ - config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); - config->has_meas_gap_config_pattern = 1; - } - if(config->has_meas_gap_config_pattern == 1 && - config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); - config->has_meas_gap_config_sf_offset = 1; - } - //TODO: Set the SPS configuration (Optional) - //Not supported for now, so we do not set it + || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { + int i = find_UE_id(mod_id, rnti); + config->has_rnti = 1; + config->rnti = rnti; + config->imsi = flexran_get_ue_imsi(mod_id, i); + config->has_imsi = 1; + config->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, i); + config->has_dl_slice_id = 1; + config->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, i); + config->has_ul_slice_id = 1; + if(flexran_get_time_alignment_timer(mod_id,i) != -1) { + config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); + config->has_time_alignment_timer = 1; + } + if(flexran_get_meas_gap_config(mod_id,i) != -1){ + config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); + config->has_meas_gap_config_pattern = 1; + } + if(config->has_meas_gap_config_pattern == 1 && + config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { + config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); + config->has_meas_gap_config_sf_offset = 1; + } + //TODO: Set the SPS configuration (Optional) + //Not supported for now, so we do not set it - //TODO: Set the SR configuration (Optional) - //We do not set it for now + //TODO: Set the SR configuration (Optional) + //We do not set it for now - //TODO: Set the CQI configuration (Optional) - //We do not set it for now - - if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { - config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); - config->has_transmission_mode = 1; - } + //TODO: Set the CQI configuration (Optional) + //We do not set it for now - config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); - config->has_ue_aggregated_max_bitrate_ul = 1; + if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { + config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); + config->has_transmission_mode = 1; + } - config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); - config->has_ue_aggregated_max_bitrate_dl = 1; + config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); + config->has_ue_aggregated_max_bitrate_ul = 1; - //TODO: Set the UE capabilities - Protocol__FlexUeCapabilities *c_capabilities; - c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); - protocol__flex_ue_capabilities__init(c_capabilities); - //TODO: Set half duplex (FDD operation) - c_capabilities->has_half_duplex = 0; - c_capabilities->half_duplex = 1;//flexran_get_half_duplex(i); - //TODO: Set intra-frame hopping flag - c_capabilities->has_intra_sf_hopping = 0; - c_capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); - //TODO: Set support for type 2 hopping with n_sb > 1 - c_capabilities->has_type2_sb_1 = 0; - c_capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); - //TODO: Set ue category - c_capabilities->has_ue_category = 0; - c_capabilities->ue_category = 1;//flexran_get_ue_category(i); - //TODO: Set UE support for resource allocation type 1 - c_capabilities->has_res_alloc_type1 = 0; - c_capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); - //Set the capabilites to the message - config->capabilities = c_capabilities; - - if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { - config->has_ue_transmission_antenna = 1; - config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); - } + config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); + config->has_ue_aggregated_max_bitrate_dl = 1; - if(flexran_get_tti_bundling(mod_id,i) != -1) { - config->has_tti_bundling = 1; - config->tti_bundling = flexran_get_tti_bundling(mod_id,i); - } + Protocol__FlexUeCapabilities *c_capabilities; + c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); + protocol__flex_ue_capabilities__init(c_capabilities); + c_capabilities->has_half_duplex = 1; + c_capabilities->half_duplex = flexran_get_half_duplex(mod_id, i); + c_capabilities->has_intra_sf_hopping = 1; + c_capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i); + c_capabilities->has_type2_sb_1 = 1; + c_capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i); + c_capabilities->has_ue_category = 1; + c_capabilities->ue_category = flexran_get_ue_category(mod_id, i); + c_capabilities->has_res_alloc_type1 = 1; + c_capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i); + //Set the capabilites to the message + config->capabilities = c_capabilities; - if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ - config->has_max_harq_tx = 1; - config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); - } + if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { + config->has_ue_transmission_antenna = 1; + config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); + } - if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { - config->has_beta_offset_ack_index = 1; - config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); - } + if(flexran_get_tti_bundling(mod_id,i) != -1) { + config->has_tti_bundling = 1; + config->tti_bundling = flexran_get_tti_bundling(mod_id,i); + } - if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { - config->has_beta_offset_ri_index = 1; - config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); - } + if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ + config->has_max_harq_tx = 1; + config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); + } - if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { - config->has_beta_offset_cqi_index = 1; - config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); - } + if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { + config->has_beta_offset_ack_index = 1; + config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); + } - /* assume primary carrier */ - if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) { - config->has_ack_nack_simultaneous_trans = 1; - config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0); - } + if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { + config->has_beta_offset_ri_index = 1; + config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); + } - if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { - config->has_simultaneous_ack_nack_cqi = 1; - config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); - } + if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { + config->has_beta_offset_cqi_index = 1; + config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); + } - if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { - config->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); - if (mode > 4) { - config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; - } else { - config->aperiodic_cqi_rep_mode = mode; - } - } + /* assume primary carrier */ + if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) { + config->has_ack_nack_simultaneous_trans = 1; + config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0); + } - if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { - config->has_tdd_ack_nack_feedback = 1; - config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); - } + if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { + config->has_simultaneous_ack_nack_cqi = 1; + config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); + } - if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { - config->has_ack_nack_repetition_factor = 1; - config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); - } + if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { + config->has_aperiodic_cqi_rep_mode = 1; + int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); + if (mode > 4) { + config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; + } else { + config->aperiodic_cqi_rep_mode = mode; + } + } - if(flexran_get_extended_bsr_size(mod_id, i) != -1) { - config->has_extended_bsr_size = 1; - config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); - } + if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { + config->has_tdd_ack_nack_feedback = 1; + config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); + } - config->has_pcell_carrier_index = 1; - config->pcell_carrier_index = UE_PCCID(mod_id, i); - //TODO: Set carrier aggregation support (boolean) - config->has_ca_support = 0; - config->ca_support = 0; - if(config->has_ca_support){ - //TODO: Set cross carrier scheduling support (boolean) - config->has_cross_carrier_sched_support = 1; - config->cross_carrier_sched_support = 0; - //TODO: Set secondary cells configuration - // We do not set it for now. No carrier aggregation support - - //TODO: Set deactivation timer for secondary cell - config->has_scell_deactivation_timer = 0; - config->scell_deactivation_timer = 0; - } + if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { + config->has_ack_nack_repetition_factor = 1; + config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); + } + + if(flexran_get_extended_bsr_size(mod_id, i) != -1) { + config->has_extended_bsr_size = 1; + config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); + } + + config->has_pcell_carrier_index = 1; + config->pcell_carrier_index = UE_PCCID(mod_id, i); + //TODO: Set carrier aggregation support (boolean) + config->has_ca_support = 0; + config->ca_support = 0; + if(config->has_ca_support){ + //TODO: Set cross carrier scheduling support (boolean) + config->has_cross_carrier_sched_support = 1; + config->cross_carrier_sched_support = 0; + //TODO: Set secondary cells configuration + // We do not set it for now. No carrier aggregation support + + //TODO: Set deactivation timer for secondary cell + config->has_scell_deactivation_timer = 0; + config->scell_deactivation_timer = 0; + } } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) { // TODO: Not supported for now. Leave blank } From d93d73fe9b38e880cc76bd6b9040b679aa89ca4a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 15:55:10 +0200 Subject: [PATCH 31/99] FlexRAN: Send the Slice Configuration in enb_config_reply --- openair2/ENB_APP/flexran_agent_common.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index db1943c945..37deec5d49 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -37,6 +37,7 @@ #include "flexran_agent_ran_api.h" //#include "PHY/extern.h" #include "common/utils/LOG/log.h" +#include "flexran_agent_mac_internal.h" //#include "SCHED/defs.h" #include "RRC/LTE/rrc_extern.h" @@ -290,6 +291,8 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { free(reply->cell_config[i]); } free(reply->cell_config); + /* don't free the slice_config, it is maintained internally during + * the liftetime of the agent */ free(reply); free(msg); @@ -1030,6 +1033,10 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i]->carrier_index = i; cell_conf[i]->has_carrier_index = 1; + + /* get a pointer to the config which is maintained in the agent throughout + * its lifetime */ + cell_conf[i]->slice_config = flexran_agent_get_slice_config(mod_id); } enb_config_reply_msg->cell_config=cell_conf; } From 3d8586a5bf4b835d5c5f8aa30fdd4ae0b53199fa Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 16:57:34 +0200 Subject: [PATCH 32/99] FlexRAN: Send Slice ID to which UE belongs in UE config reply --- openair2/ENB_APP/flexran_agent_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 37deec5d49..f1556deef2 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -594,6 +594,10 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config[i]->has_rnti = 1; ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, i); ue_config[i]->has_imsi = 1; + ue_config[i]->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, i); + ue_config[i]->has_dl_slice_id = 1; + ue_config[i]->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, i); + ue_config[i]->has_ul_slice_id = 1; //TODO: Set the DRX configuration (optional) //Not supported for now, so we do not set it From 3a78d85f5ee621a860be73ad5a03ac2ff1e2a401 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 16:58:23 +0200 Subject: [PATCH 33/99] FlexRAN: Handle enb_config_reply reconfiguration message --- openair2/ENB_APP/flexran_agent_common.c | 20 ++++++++++++++++++++ openair2/ENB_APP/flexran_agent_common.h | 7 +++++++ openair2/ENB_APP/flexran_agent_handler.c | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index f1556deef2..1cbf411c65 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1101,5 +1101,25 @@ int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg){ return 0; } +int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) +{ + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg; + if (enb_config->n_cell_config == 0) { + LOG_W(FLEXRAN_AGENT, + "received enb_config_reply message does not contain a cell_config\n"); + *msg = NULL; + return 0; + } + if (enb_config->n_cell_config > 1) + LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n"); + if (enb_config->cell_config[0]->slice_config) + prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); + + /* could test for cell configs here and maybe reconfigure/soft-restart */ + + *msg = NULL; + return 0; +} diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index 057c5b9489..2738a2f3d3 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -167,4 +167,11 @@ void flexran_agent_send_update_stats(mid_t mod_id); err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ; err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id); +/* Handle a received eNB config reply message as an "order" to reconfigure. It + * does not come as a reconfiguration message as this is a "structured" + * ProtoBuf message (as opposed to "unstructured" YAML). There is no destructor + * since we do not reply to this message (yet). Instead, the controller has to + * issue another eNB config request message. */ +int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg); + #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 66123fd71c..b3025bf769 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -46,7 +46,7 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = { {0, 0, 0}, /*PROTOCOK__FLEXRAN_MESSAGE__MSG_SF_TRIGGER_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG*/ {flexran_agent_enb_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG*/ - {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG*/ + {flexran_agent_handle_enb_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG*/ {flexran_agent_ue_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REQUEST_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG*/ {flexran_agent_lc_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REQUEST_MSG*/ From 7b8c5cea524d5b9d113f17e1aa8893c08a1f596a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 17:03:23 +0200 Subject: [PATCH 34/99] FlexRAN: handle incoming UE-slice association message --- openair2/ENB_APP/flexran_agent_common.c | 13 +++++++++++++ openair2/ENB_APP/flexran_agent_common.h | 8 ++++++++ openair2/ENB_APP/flexran_agent_handler.c | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 1cbf411c65..d08517edea 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1123,3 +1123,16 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot *msg = NULL; return 0; } + +int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) +{ + int i; + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg; + + for (i = 0; i < ue_config_reply->n_ue_config; i++) + prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]); + + *msg = NULL; + return 0; +} diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index 2738a2f3d3..5d78e382d4 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -174,4 +174,12 @@ err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id); * issue another eNB config request message. */ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg); +/* Handle a received UE config reply message as an "order" to reconfigure the + * association of a UE to a slice. It does not come as a reconfiguration + * message as this is a "structured" ProtoBuf message (as opposed to + * "unstructured" YAML). There is no destructor since we do not reply to this + * message (yet). Instead, the controller has to issue another eNB config + * request message. */ +int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg); + #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index b3025bf769..fa3270696a 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -48,7 +48,7 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = { {flexran_agent_enb_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG*/ {flexran_agent_handle_enb_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG*/ {flexran_agent_ue_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REQUEST_MSG*/ - {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG*/ + {flexran_agent_handle_ue_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG*/ {flexran_agent_lc_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REQUEST_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG*/ {flexran_agent_mac_handle_dl_mac_config, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_DL_MAC_CONFIG_MSG*/ From 5ceba4a2a6f1bc8711518722c4e7b4d5b39b3fe9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Apr 2018 17:52:57 +0200 Subject: [PATCH 35/99] FlexRAN: lock sc_update with mutex Prevent sc_update from being changed by an incoming slice reconfiguration change while writing data to the scheduler --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 7 +++++++ .../CONTROL_MODULES/MAC/flexran_agent_mac_internal.c | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 0c33026a38..0985539f8c 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -61,6 +61,8 @@ int perform_slice_config_update_count = 1; /* queue of incoming new UE<>slice association commands */ Protocol__FlexUeConfig *ue_slice_assoc_update[NUM_MAX_UE]; int n_ue_slice_assoc_updates = 0; +/* mutex for sc_update: do not receive new config and write it at the same time */ +pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER; int flexran_agent_mac_stats_reply(mid_t mod_id, @@ -1446,10 +1448,13 @@ void flexran_agent_slice_update(mid_t mod_id) if (perform_slice_config_update_count <= 0) return; perform_slice_config_update_count--; + pthread_mutex_lock(&sc_update_mtx); + if (!slice_config[mod_id]) { /* if the configuration does not exist for agent, create from eNB structure * and exit */ flexran_create_config_structures(mod_id); + pthread_mutex_unlock(&sc_update_mtx); return; } @@ -1479,6 +1484,7 @@ void flexran_agent_slice_update(mid_t mod_id) LOG_W(FLEXRAN_AGENT, "[%d] reverting to original number of %ld UL slices\n", mod_id, sc_update[mod_id]->n_ul); } + pthread_mutex_unlock(&sc_update_mtx); return; } @@ -1514,6 +1520,7 @@ void flexran_agent_slice_update(mid_t mod_id) if (changes > 0) LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes); + pthread_mutex_unlock(&sc_update_mtx); } Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 435e8da064..dea1aa05b9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -38,6 +38,7 @@ extern Protocol__FlexSliceConfig *sc_update[NUM_MAX_ENB]; extern int perform_slice_config_update_count; extern Protocol__FlexUeConfig *ue_slice_assoc_update[NUM_MAX_UE]; extern int n_ue_slice_assoc_updates; +extern pthread_mutex_t sc_update_mtx; Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message, Protocol__FlexranMessage *old_message) { @@ -1228,6 +1229,9 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice) LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n"); return; } + + pthread_mutex_lock(&sc_update_mtx); + if (slice->n_dl == 0) LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); for (int i = 0; i < slice->n_dl; i++) @@ -1238,6 +1242,8 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice) for (int i = 0; i < slice->n_ul; i++) prepare_update_slice_config_ul(mod_id, slice->ul[i]); + pthread_mutex_unlock(&sc_update_mtx); + /* perform the slice configuration reads a couple of times. If there are * inconsistencies (i.e. the MAC refuses a configuration), we will have a * couple of warnings because the current configuration and the one in @@ -1395,7 +1401,6 @@ int apply_ue_slice_assoc_update(mid_t mod_id) { int i; int changes = 0; - /* TODO should lock structure */ for (i = 0; i < n_ue_slice_assoc_updates; i++) { int ue_id = find_UE_id(mod_id, ue_slice_assoc_update[i]->rnti); if (ue_slice_assoc_update[i]->has_dl_slice_id) { From 44d1eb80158554e0deec544324496e303d72247f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 25 Apr 2018 18:52:12 +0200 Subject: [PATCH 36/99] preprocessor reset: avoid unnecessary iterations --- openair2/LAYER2/MAC/pre_processor.c | 168 ++++++++++++++-------------- 1 file changed, 83 insertions(+), 85 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 8334219371..69afa7f705 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1446,14 +1446,6 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, if (!ue_dl_slice_membership(module_idP, UE_id, slice_idx)) continue; - vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; - N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); - -#ifdef SF0_LIMIT - sf0_lower = -1; - sf0_upper = -1; -#endif - LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); // initialize harq_pid and round if (ue_sched_ctl->ta_timer) @@ -1522,91 +1514,97 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; ue_sched_ctl->dl_pow_off[CC_id] = 2; - switch (N_RB_DL) { - case 6: - RBGsize = 1; - RBGsize_last = 1; - break; - case 15: - RBGsize = 2; - RBGsize_last = 1; - break; - case 25: - RBGsize = 2; - RBGsize_last = 1; - break; - case 50: - RBGsize = 3; - RBGsize_last = 2; - break; - case 75: - RBGsize = 4; - RBGsize_last = 3; - break; - case 100: - RBGsize = 4; - RBGsize_last = 4; - break; - default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } - -#ifdef SF0_LIMIT - switch (N_RBG[CC_id]) { - case 6: - sf0_lower = 0; - sf0_upper = 5; - break; - case 8: - sf0_lower = 2; - sf0_upper = 5; - break; - case 13: - sf0_lower = 4; - sf0_upper = 7; - break; - case 17: - sf0_lower = 7; - sf0_upper = 9; - break; - case 25: - sf0_lower = 11; - sf0_upper = 13; - break; - default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } -#endif - - // Initialize Subbands according to VRB map for (i = 0; i < N_RBG[CC_id]; i++) { - int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; + } + } + + N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); #ifdef SF0_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) - /* TODO: make it proper - allocate those RBs, do not "protect" them, but - * compute number of available REs and limit MCS according to the - * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) - */ - if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) - rballoc_sub[CC_id][i] = 1; + switch (N_RBG[CC_id]) { + case 6: + sf0_lower = 0; + sf0_upper = 5; + break; + case 8: + sf0_lower = 2; + sf0_upper = 5; + break; + case 13: + sf0_lower = 4; + sf0_upper = 7; + break; + case 17: + sf0_lower = 7; + sf0_upper = 9; + break; + case 25: + sf0_lower = 11; + sf0_upper = 13; + break; + default: + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < rb_size; j++) { - if (vrb_map[j + (i*RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", frameP, subframeP, j + (i*RBGsize)); - break; - } + switch (N_RB_DL) { + case 6: + RBGsize = 1; + RBGsize_last = 1; + break; + case 15: + RBGsize = 2; + RBGsize_last = 1; + break; + case 25: + RBGsize = 2; + RBGsize_last = 1; + break; + case 50: + RBGsize = 3; + RBGsize_last = 2; + break; + case 75: + RBGsize = 4; + RBGsize_last = 3; + break; + case 100: + RBGsize = 4; + RBGsize_last = 4; + break; + default: + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } + + vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; + // Initialize Subbands according to VRB map + for (i = 0; i < N_RBG[CC_id]; i++) { + int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize; + rballoc_sub[CC_id][i] = 0; + + +#ifdef SF0_LIMIT + // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) + /* TODO: make it proper - allocate those RBs, do not "protect" them, but + * compute number of available REs and limit MCS according to the + * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) + */ + if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) + rballoc_sub[CC_id][i] = 1; +#endif + + // for SI-RNTI,RA-RNTI and P-RNTI allocations + for (j = 0; j < rb_size; j++) { + if (vrb_map[j + (i*RBGsize)] != 0) { + rballoc_sub[CC_id][i] = 1; + LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", frameP, subframeP, j + (i*RBGsize)); + break; } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; } + LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", + frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + MIMO_mode_indicator[CC_id][i] = 2; } } } From 8039cd40f59b930a0995628ecf5d2e154ce6053f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 25 Apr 2018 19:08:44 +0200 Subject: [PATCH 37/99] share the allocation array rballoc_sub between slices --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 17 ++++++++++------- openair2/LAYER2/MAC/mac.h | 4 +++- openair2/LAYER2/MAC/mac_proto.h | 6 ++++-- openair2/LAYER2/MAC/pre_processor.c | 5 ++--- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index ccc5a944a7..7cc8f93939 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -412,6 +412,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in int i = 0; slice_info_t *sli = &RC.mac[module_idP]->slice_info; + memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub)); sli->tot_pct_dl = 0; sli->avg_pct_dl = 1.0 / sli->n_dl; @@ -727,7 +728,8 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, slice_idxP, frameP, subframeP, - mbsfn_flag); + mbsfn_flag, + eNB->slice_info.rballoc_sub); stop_meas(&eNB->schedule_dlsch_preprocessor); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); @@ -741,7 +743,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, //} if (RC.mac[module_idP]->slice_info.interslice_share_active) { - dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP); + dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP, eNB->slice_info.rballoc_sub); } for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { @@ -843,7 +845,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } else { // this operation is also done in the preprocessor eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, - RC.mac[module_idP]->slice_info.dl[slice_idxP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + eNB->slice_info.dl[slice_idxP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } // Store stats @@ -1608,7 +1610,10 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } //------------------------------------------------------------------------------ -void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP) +void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) //------------------------------------------------------------------------------ { // FIXME: I'm prototyping the algorithm, so there may be arrays and variables that carry redundant information here and in pre_processor_results struct. @@ -1631,7 +1636,6 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB]; uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB]; - uint8_t (*rballoc_sub)[N_RBG_MAX]; uint8_t (*MIMO_mode_indicator)[N_RBG_MAX]; // Initialize the free RBGs map @@ -1646,7 +1650,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub for (i = 0; i < sli->n_dl; ++i) { owned = sli->pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; if (owned) { - used = sli->pre_processor_results[i].slice_allocated_rbgs[CC_id][rbg]; + used = rballoc_sub[CC_id][rbg]; free_rbgs_map[CC_id][rbg] = used ? -1 : i; break; } @@ -1705,7 +1709,6 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub nb_rbs_remaining = sli->pre_processor_results[slice_idx].nb_rbs_remaining; nb_rbs_required = sli->pre_processor_results[slice_idx].nb_rbs_required; - rballoc_sub = sli->pre_processor_results[slice_idx].slice_allocated_rbgs; MIMO_mode_indicator = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; // Allocation diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index f22cc4081c..5507f643f0 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1131,7 +1131,6 @@ typedef struct { uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; - uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX]; uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID]; @@ -1264,6 +1263,9 @@ typedef struct { slice_sched_conf_ul_t ul[MAX_NUM_SLICES]; pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; + + /// common rb allocation list between slices + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; } slice_info_t; /*! \brief eNB common channels */ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 4837b84d4f..1400d862d6 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -203,7 +203,8 @@ void dlsch_scheduler_pre_processor(module_id_t module_idP, int slice_idxP, frame_t frameP, sub_frame_t subframe, - int *mbsfn_flag); + int *mbsfn_flag, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]); void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, int slice_idx, @@ -249,7 +250,8 @@ void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]); void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, - sub_frame_t subframeP); + sub_frame_t subframeP, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]); void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 69afa7f705..05d5845058 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1234,7 +1234,8 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframeP, - int *mbsfn_flag) + int *mbsfn_flag, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) { int UE_id; uint8_t CC_id; @@ -1246,7 +1247,6 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_required; uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_accounted; uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_remaining; - uint8_t (*rballoc_sub)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].slice_allocated_rbgs; uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; @@ -1581,7 +1581,6 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, // Initialize Subbands according to VRB map for (i = 0; i < N_RBG[CC_id]; i++) { int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize; - rballoc_sub[CC_id][i] = 0; #ifdef SF0_LIMIT From 11e45be9c50bc89cf5d26b6ed2db90e66a4cbce7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 17 May 2018 10:27:09 +0200 Subject: [PATCH 38/99] fix: resort UE_list after slice multiplexing - slice multiplexing resorts UE_list for its purposes with restoring the original order - in order to keep the order in UE_list, resort to original order after multiplexing - ideally, this would happen in the multiplexing but currently, the slice_idx is not passed to multiplexing (it does not care), so this cannot be done ATM --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 7cc8f93939..350a7ea9f7 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -744,6 +744,9 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (RC.mac[module_idP]->slice_info.interslice_share_active) { dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP, eNB->slice_info.rballoc_sub); + /* the interslice multiplexing re-sorts the UE_list for the slices it tries + * to multiplex, so we need to sort it for the current slice again */ + sort_UEs(module_idP, slice_idxP, frameP, subframeP); } for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { From 088b1d5a8d78f573e5584338924adb4b8efec772 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 17 May 2018 10:47:10 +0200 Subject: [PATCH 39/99] refine MAC Debug output - uncomment "Couldn't find RNTI for UE X" in UE_RNTI() and rb_alloc in pre_processor_reset() as they only inflate the debug output with little benefited - "doing ue_schedule_spec" is now displayed for individual UEs (and individual CCs) - show messages when not scheduling UE in ue_schedule_spec() due to invalid slice or if not in RRC_CONNECTED --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 12 ++++++++++-- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 2 +- openair2/LAYER2/MAC/pre_processor.c | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 350a7ea9f7..bc929b7534 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -758,6 +758,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, continue; for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", CC_id, UE_id); continue_flag = 0; // reset the flag to allow allocation for the remaining UEs rnti = UE_RNTI(module_idP, UE_id); eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; @@ -773,8 +774,13 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, continue_flag = 1; } - if (!ue_dl_slice_membership(module_idP, UE_id, slice_idxP)) + if (!ue_dl_slice_membership(module_idP, UE_id, slice_idxP)) { + LOG_D(MAC, "UE%d is not part of slice %d ID %d\n", + UE_id, slice_idxP, RC.mac[module_idP]->slice_info.dl[slice_idxP].id); + /* prevent execution of add_ue_dlsch_info(), it is done by the other + * slice */ continue; + } if (continue_flag != 1) { switch (get_tmode(module_idP, CC_id, UE_id)) { @@ -832,8 +838,10 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) { + LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id); continue; + } header_length_total = 0; sdu_length_total = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 6bdb63a721..57cc7f5370 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1851,7 +1851,7 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) return (rnti); } - LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); + //LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); //display_backtrace(); return (NOT_A_RNTI); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 05d5845058..a2c88674c8 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1601,8 +1601,8 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, break; } } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + //LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", + //frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); MIMO_mode_indicator[CC_id][i] = 2; } } From 6b3dd8716b4ec73ed6a33e4e8c87dcbec0db6fb6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 17 May 2018 14:49:50 +0200 Subject: [PATCH 40/99] FlexRAN: set values of removed slices to 0 --- openair2/ENB_APP/flexran_agent_ran_api.c | 2 ++ openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 4 ---- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 9b6ecae593..bea680c48c 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1487,6 +1487,7 @@ int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) /* move last element to the position of the removed one */ if (slice_idx != sli->n_dl) memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl])); + memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl])); /* all UEs that have been in the old slice are put into slice index 0 */ int *assoc_list = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx; @@ -1763,6 +1764,7 @@ int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) /* move last element to the position of the removed one */ if (slice_idx != sli->n_ul) memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul])); + memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul])); /* all UEs that have been in the old slice are put into slice index 0 */ int *assoc_list = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index bc929b7534..c4c1cd1ca5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -418,10 +418,6 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in sli->avg_pct_dl = 1.0 / sli->n_dl; //sli->slice_counter = sli->n_dl; - // reset the slice percentage for inactive slices - for (i = sli->n_dl; i < MAX_NUM_SLICES; i++) { - sli->dl[i].pct = 0; - } for (i = 0; i < sli->n_dl; i++) { if (sli->dl[i].pct < 0) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid percentage %f. resetting to zero", diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 684a74f0f7..68cd5de8bd 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1043,10 +1043,6 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, sli->tot_pct_ul = 0; sli->avg_pct_ul = 1.0 / sli->n_ul; - // reset the slice percentage for inactive slices - for (i = sli->n_ul; i< MAX_NUM_SLICES; i++) { - sli->ul[i].pct = 0; - } for (i = 0; i < sli->n_ul; i++) { if (sli->ul[i].pct < 0 ){ LOG_W(MAC, From 21f66094724f78b4f79727a92080508ad5e11303 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 18 May 2018 18:18:53 +0200 Subject: [PATCH 41/99] FlexRAN: move slice param verification to agent - until now, on every iteration, the scheduler checked for changed parameter (and verified some) - this functionality moves to the FlexRAN Agent, which verifies all parameters * individually, e.g. Max MCS <= 28 for DL * group-based, e.g. the sum of slice percentages is <= 100 - slice configuration changes are only applied if all verifications pass - it is assumed in the scheduler, that configuration passed from outside is correct and can be used "as-is" fix accounting setting --- cmake_targets/CMakeLists.txt | 1 + .../MAC/flexran_agent_mac_internal.c | 253 ++++++++----- .../flexran_agent_mac_slice_verification.c | 340 ++++++++++++++++++ .../flexran_agent_mac_slice_verification.h | 37 ++ openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 186 ---------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 105 ------ openair2/LAYER2/MAC/mac.h | 40 +-- openair2/LAYER2/MAC/main.c | 20 -- 8 files changed, 555 insertions(+), 427 deletions(-) create mode 100644 openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c create mode 100644 openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 39a24564dd..a083cac1c3 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -870,6 +870,7 @@ add_library(FLEXRAN_AGENT ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c ) set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) #include_directories(${OPENAIR2_DIR}/ENB_APP) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index dea1aa05b9..d75712d430 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -31,6 +31,7 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" +#include "flexran_agent_mac_slice_verification.h" /* from flexran_agent_mac.c */ extern Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB]; @@ -1141,107 +1142,203 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli } } -void prepare_update_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *dls) +void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s) { - if (!dls->has_id) { - LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id); - return; + /* TODO fill the slice depending on the chosen label */ + /* for now, we fill it up with the information from slice 0 */ + /* assume there is an ID (will be checked later) */ + if (!s->has_label) { + s->has_label = 1; + s->label = sc_update[mod_id]->dl[0]->label; } - /* a percentage of zero will be interpreted as removal command */ - if (sc_update[mod_id]->n_dl >= MAX_NUM_SLICES - && (!dls->has_percentage || dls->percentage > 0)) { - LOG_E(FLEXRAN_AGENT, "[%d] Cannot create more than %ld slices in DL\n", - mod_id, sc_update[mod_id]->n_dl); - return; + if (!s->has_percentage) { + s->has_percentage = 1; + s->percentage = sc_update[mod_id]->dl[0]->percentage; } - if (sc_update[mod_id]->n_dl == 1 && dls->has_percentage && dls->percentage == 0) { - LOG_E(FLEXRAN_AGENT, "[%d] Cannot delete last slice ID %d in DL\n", - mod_id, sc_update[mod_id]->dl[0]->id); - return; + if (!s->has_isolation) { + s->has_isolation = 1; + s->isolation = sc_update[mod_id]->dl[0]->isolation; } + if (!s->has_priority) { + s->has_priority = 1; + s->priority = sc_update[mod_id]->dl[0]->priority; + } + if (!s->has_position_low) { + s->has_position_low = 1; + s->position_low = sc_update[mod_id]->dl[0]->position_low; + } + if (!s->has_position_high) { + s->has_position_high = 1; + s->position_high = sc_update[mod_id]->dl[0]->position_high; + } + if (!s->has_maxmcs) { + s->has_maxmcs = 1; + s->maxmcs = sc_update[mod_id]->dl[0]->maxmcs; + } + if (s->n_sorting == 0) { + s->n_sorting = sc_update[0]->dl[0]->n_sorting; + /* TODO Dangerous? */ + s->sorting = sc_update[0]->dl[0]->sorting; + } + if (!s->has_accounting) { + /* TODO Dangerous? */ + s->accounting = sc_update[0]->dl[0]->accounting; + } + /* scheduler name not set, cannot be changed for the moment */ +} - Protocol__FlexDlSlice *to = NULL; +Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id) +{ for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) { - if (dls->id == sc_update[mod_id]->dl[i]->id) { - to = sc_update[mod_id]->dl[i]; - break; + if (id == sc_update[mod_id]->dl[i]->id) { + return sc_update[mod_id]->dl[i]; } } - - /* create new slice -> read contents from existing slice config index 0 */ - if (!to) { - LOG_I(FLEXRAN_AGENT, - "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n", - mod_id, dls->id); - to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; - sc_update[mod_id]->n_dl++; - memcpy(to, slice_config[mod_id]->dl[0], sizeof(*to)); - to->id = dls->id; - } - - overwrite_slice_config_dl(to, dls); + return NULL; } -void prepare_update_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *uls) +Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id) { - if (!uls->has_id) { - LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id); - return; - } - /* a percentage of zero will be interpreted as removal command */ - if (sc_update[mod_id]->n_ul >= MAX_NUM_SLICES - && (!uls->has_percentage || uls->percentage > 0)) { - LOG_E(FLEXRAN_AGENT, "[%d] Cannot create more than %ld slices in UL\n", - mod_id, sc_update[mod_id]->n_ul); - return; - } - if (sc_update[mod_id]->n_ul == 1 && uls->has_percentage && uls->percentage == 0) { - LOG_E(FLEXRAN_AGENT, "[%d] Cannot delete last slice ID %d in UL\n", - mod_id, sc_update[mod_id]->ul[0]->id); - return; - } + LOG_I(FLEXRAN_AGENT, + "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n", + mod_id, id); + Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; + sc_update[mod_id]->n_dl++; + AssertFatal(sc_update[mod_id]->n_dl <= MAX_NUM_SLICES, + "cannot create more than MAX_NUM_SLICES\n"); + to->id = id; + return to; +} - Protocol__FlexUlSlice *to = NULL; +void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s) +{ + /* TODO fill the slice depending on the chosen label */ + /* for now, we fill it up with the information from slice 0 */ + /* assume there is an ID (will be checked later) */ + if (!s->has_label) { + s->has_label = 1; + s->label = sc_update[mod_id]->ul[0]->label; + } + if (!s->has_percentage) { + s->has_percentage = 1; + s->percentage = sc_update[mod_id]->ul[0]->percentage; + } + if (!s->has_isolation) { + s->has_isolation = 1; + s->isolation = sc_update[mod_id]->ul[0]->isolation; + } + if (!s->has_priority) { + s->has_priority = 1; + s->priority = sc_update[mod_id]->ul[0]->priority; + } + if (!s->has_first_rb) { + s->has_first_rb = 1; + s->first_rb = sc_update[mod_id]->ul[0]->first_rb; + } + if (!s->has_maxmcs) { + s->has_maxmcs = 1; + s->maxmcs = sc_update[mod_id]->ul[0]->maxmcs; + } + if (s->n_sorting == 0) { + s->n_sorting = sc_update[0]->ul[0]->n_sorting; + /* TODO Dangerous? */ + s->sorting = sc_update[0]->ul[0]->sorting; + } + if (!s->has_accounting) { + /* TODO Dangerous? */ + s->accounting = sc_update[0]->ul[0]->accounting; + } + /* scheduler name not set, cannot be changed for the moment */ +} + +Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id) +{ for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) { - if (uls->id == sc_update[mod_id]->ul[i]->id) { - to = sc_update[mod_id]->ul[i]; - break; + if (id == sc_update[mod_id]->ul[i]->id) { + return sc_update[mod_id]->ul[i]; } } - - /* create new slice -> read contents from existing slice config index 0 */ - if (!to) { - LOG_I(FLEXRAN_AGENT, - "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n", - mod_id, uls->id); - to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; - sc_update[mod_id]->n_ul++; - memcpy(to, slice_config[mod_id]->ul[0], sizeof(*to)); - to->id = uls->id; - } - - overwrite_slice_config_ul(to, uls); + return NULL; } -void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice) +Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id) { + LOG_I(FLEXRAN_AGENT, + "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n", + mod_id, id); + Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; + sc_update[mod_id]->n_ul++; + AssertFatal(sc_update[mod_id]->n_ul <= MAX_NUM_SLICES, + "cannot create more than MAX_NUM_SLICES\n"); + to->id = id; + return to; +} + +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) +{ + int verified = 1; if (!sc_update[mod_id]) { LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n"); return; } pthread_mutex_lock(&sc_update_mtx); - - if (slice->n_dl == 0) + if (sup->n_dl == 0) { LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); - for (int i = 0; i < slice->n_dl; i++) - prepare_update_slice_config_dl(mod_id, slice->dl[i]); + } else { + /* verify slice parameters */ + for (int i = 0; i < sup->n_dl; i++) { + fill_dl_slice(mod_id, sup->dl[i]); + verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]); + if (!verified) break; + } - if (slice->n_ul == 0) + /* verify group-based parameters (e.g. sum percentage should not exceed + * 100%). Can be used to perform admission control */ + verified = verified && flexran_verify_group_dl_slices(mod_id, + sc_update[mod_id]->dl, sc_update[mod_id]->n_dl, sup->dl, sup->n_dl); + + if (verified) { + for (int i = 0; i < sup->n_dl; i++) { + /* if all verifications were successful, get existing slice for ID or + * create new one and overwrite with the update */ + Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); + if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id); + overwrite_slice_config_dl(dls, sup->dl[i]); + } + } else { + LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id); + } + } + + verified = 1; + if (sup->n_ul == 0) { LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id); - for (int i = 0; i < slice->n_ul; i++) - prepare_update_slice_config_ul(mod_id, slice->ul[i]); + } else { + /* verify slice parameters */ + for (int i = 0; i < sup->n_ul; i++) { + fill_ul_slice(mod_id, sup->ul[i]); + verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]); + if (!verified) break; + } + /* verify group-based parameters (e.g. sum percentage should not exceed + * 100%). Can be used to perform admission control */ + verified = verified && flexran_verify_group_ul_slices(mod_id, + sc_update[mod_id]->ul, sc_update[mod_id]->n_ul, sup->ul, sup->n_ul); + + if (verified) { + for (int i = 0; i < sup->n_ul; i++) { + /* if all verifications were successful, get existing slice for ID or + * create new one and overwrite with the update */ + Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); + if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id); + overwrite_slice_config_ul(uls, sup->ul[i]); + } + } else { + LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id); + } + } pthread_mutex_unlock(&sc_update_mtx); /* perform the slice configuration reads a couple of times. If there are @@ -1299,11 +1396,6 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); changes++; } - if (strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the DL scheduler is not supported, reverting\n", - mod_id, newc->id); - newc->scheduler_name = oldc->scheduler_name; - } return changes; } @@ -1365,11 +1457,6 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", mod_id, slice_idx); } - if (strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the UL scheduler is not supported, reverting\n", - mod_id, slice_idx); - newc->scheduler_name = oldc->scheduler_name; - } return changes; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c new file mode 100644 index 0000000000..addc8d2e75 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -0,0 +1,340 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_mac_slice_verification.c + * \brief MAC Agent slice verification helper functions + * \author Robert Schmidt + * \date 2018 + * \version 0.1 + */ + + +#include "flexran_agent_mac_slice_verification.h" + +/* overlap check for UL slices, helper type */ +struct sregion_s { + int start; + int length; +}; + +/* forward declaration of locally-used verification functions */ +int flexran_dl_slice_verify_pct(int pct); +int flexran_dl_slice_verify_priority(int prio); +int flexran_dl_slice_verify_position(int pos_low, int pos_high); +int flexran_dl_slice_verify_maxmcs(int maxmcs); +int flexran_ul_slice_verify_pct(int pct); +int flexran_ul_slice_verify_priority(int prio); +int flexran_ul_slice_verify_first_rb(int first_rb); +int flexran_ul_slice_verify_maxmcs(int maxmcs); +int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n); + +int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls) +{ + /* check mandatory parameters */ + if (!dls->has_id) { + LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id); + return 0; + } + + /* verify parameters individualy */ + /* label is enum */ + if (!flexran_dl_slice_verify_pct(dls->percentage)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice percentage (%d)\n", mod_id, dls->percentage); + return 0; + } + /* isolation is a protobuf bool */ + if (!flexran_dl_slice_verify_priority(dls->priority)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice priority (%d)\n", mod_id, dls->priority); + return 0; + } + if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice position low (%d) and/or high (%d)\n", + mod_id, dls->position_low, dls->position_high); + return 0; + } + if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice max mcs %d\n", mod_id, dls->maxmcs); + return 0; + } + if (dls->n_sorting == 0) { + LOG_E(FLEXRAN_AGENT, "[%d] no sorting in DL slice", mod_id); + return 0; + } + if (!dls->sorting) { + LOG_E(FLEXRAN_AGENT, "[%d] no sorting found in DL slice\n", mod_id); + return 0; + } + /* sorting is an enum */ + /* accounting is an enum */ + if (dls->scheduler_name) { + LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler is not allowed\n", mod_id); + return 0; + } + + return 1; +} + +int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, + int n_ex, Protocol__FlexDlSlice **update, int n_up) +{ + int i, j, n; + int pct, pct_orig; + /* for every update, array points to existing slice, or NULL if update + * creates new slice */ + Protocol__FlexDlSlice *s[n_up]; + for (i = 0; i < n_up; i++) { + s[i] = NULL; + for (j = 0; j < n_ex; j++) { + if (existing[j]->id == update[i]->id) + s[i] = existing[j]; + } + } + + /* check that number of created and number of added slices in total matches + * [1,10] */ + n = n_ex; + for (i = 0; i < n_up; i++) { + /* new slice */ + if (!s[i]) n += 1; + /* slice will be deleted */ + else if (s[i]->percentage == 0) n -= 1; + /* else "only" an update */ + } + + if (n < 1 || n > MAX_NUM_SLICES) { + LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting slices (%d -> %d)\n", mod_id, n_ex, n); + return 0; + } + + /* check that the sum of all slices percentages (including removed/added + * slices) matches [1,100] */ + pct = 0; + for (i = 0; i < n_ex; i++) { + pct += existing[i]->percentage; + } + pct_orig = pct; + for (i = 0; i < n_up; i++) { + /* if there is an existing slice, subtract its percentage and add the + * update's percentage */ + if (s[i]) + pct -= s[i]->percentage; + pct += update[i]->percentage; + } + if (pct < 1 || pct > 100) { + LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", mod_id, pct_orig, pct); + return 0; + } + + return 1; +} + +int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) +{ + /* check mandatory parameters */ + if (!uls->has_id) { + LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id); + return 0; + } + + /* verify parameters individually */ + /* label is enum */ + if (!flexran_ul_slice_verify_pct(uls->percentage)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice percentage (%d)\n", mod_id, uls->percentage); + return 0; + } + /* isolation is a protobuf bool */ + if (!flexran_ul_slice_verify_priority(uls->priority)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice percentage (%d)\n", mod_id, uls->priority); + return 0; + } + if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice first RB (%d)\n", mod_id, uls->first_rb); + return 0; + } + if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) { + LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice max mcs (%d)\n", mod_id, uls->maxmcs); + return 0; + } + if (uls->n_sorting == 0) { + LOG_E(FLEXRAN_AGENT, "[%d] no sorting in UL slice\n", mod_id); + return 0; + } + if (!uls->sorting) { + LOG_E(FLEXRAN_AGENT, "[%d] no sorting found in UL slice\n", mod_id); + return 0; + } + /* sorting is an enum */ + /* accounting is an enum */ + if (uls->scheduler_name) { + LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler is not allowed\n", mod_id); + return 0; + } + + return 1; +} + +int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, + int n_ex, Protocol__FlexUlSlice **update, int n_up) +{ + int i, j, n; + int pct, pct_orig; + /* for every update, array "s" points to existing slice, or NULL if update + * creates new slice; array "offs" gives the offset of this slice */ + Protocol__FlexUlSlice *s[n_up]; + int offs[n_up]; + for (i = 0; i < n_up; i++) { + s[i] = NULL; + offs[i] = 0; + for (j = 0; j < n_ex; j++) { + if (existing[j]->id == update[i]->id) { + s[i] = existing[j]; + offs[i] = j; + } + } + } + + /* check that number of created and number of added slices in total matches + * [1,10] */ + n = n_ex; + for (i = 0; i < n_up; i++) { + /* new slice */ + if (!s[i]) n += 1; + /* slice will be deleted */ + else if (s[i]->percentage == 0) n -= 1; + /* else "only" an update */ + } + + if (n < 1 || n > MAX_NUM_SLICES) { + LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting slices (%d -> %d)\n", mod_id, n_ex, n); + return 0; + } + + /* check that the sum of all slices percentages (including removed/added + * slices) matches [1,100] */ + pct = 0; + for (i = 0; i < n_ex; i++) { + pct += existing[i]->percentage; + } + pct_orig = pct; + for (i = 0; i < n_up; i++) { + /* if there is an existing slice, subtract its percentage and add the + * update's percentage */ + if (s[i]) + pct -= s[i]->percentage; + pct += update[i]->percentage; + } + if (pct < 1 || pct > 100) { + LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", mod_id, pct_orig, pct); + return 0; + } + + /* check that there is no overlap in slices resulting as the combination of + * first_rb and percentage */ + struct sregion_s sregion[n]; + const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ + int k = n_ex; + for (i = 0; i < n_ex; i++) { + sregion[i].start = existing[i]->first_rb; + sregion[i].length = existing[i]->percentage * N_RB / 100; + } + for (i = 0; i < n_up; i++) { + ptrdiff_t d = s[i] ? offs[i] : k++; + AssertFatal(d >= 0 && d < k, "illegal pointer offset (%ld, k=%d)\n", d, k); + sregion[d].start = update[i]->first_rb; + sregion[d].length = update[i]->percentage * N_RB / 100; + } + AssertFatal(k == n, "illegal number of slices while calculating overlap\n"); + if (!check_ul_slice_overlap(mod_id, sregion, k)) { + LOG_E(FLEXRAN_AGENT, "[%d] UL slices are overlapping\n", mod_id); + return 0; + } + + return 1; +} + +int flexran_dl_slice_verify_pct(int pct) +{ + return pct >= 0 && pct <= 100; +} + +int flexran_dl_slice_verify_priority(int prio) +{ + return prio >= 0; +} + +int flexran_dl_slice_verify_position(int pos_low, int pos_high) +{ + return pos_low < pos_high && pos_low >= 0 && pos_high <= N_RBG_MAX; +} + +int flexran_dl_slice_verify_maxmcs(int maxmcs) +{ + return maxmcs >= 0 && maxmcs <= 28; +} + +int flexran_ul_slice_verify_pct(int pct) +{ + return pct >= 0 && pct <= 100; +} + +int flexran_ul_slice_verify_priority(int prio) +{ + return prio >= 0; +} + +int flexran_ul_slice_verify_first_rb(int first_rb) +{ + return first_rb >= 0 && first_rb < 100; +} + +int flexran_ul_slice_verify_maxmcs(int maxmcs) +{ + return maxmcs >= 0 && maxmcs <= 20; +} + +int sregion_compare(const void *_a, const void *_b) +{ + const struct sregion_s *a = (const struct sregion_s *)_a; + const struct sregion_s *b = (const struct sregion_s *)_b; + const int res = a->start - b->start; + if (res < 0) return -1; + else if (res == 0) return 0; + else return 1; +} + +int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n) +{ + int i; + int overlap, op, u; + const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ + qsort(sr, n, sizeof(sr[0]), sregion_compare); + for (i = 0; i < n; i++) { + u = i == n-1 ? N_RB : sr[i+1].start; + AssertFatal(sr[i].start <= u, "unsorted slice list\n"); + overlap = sr[i].start + sr[i].length - u; + if (overlap <= 0) continue; + op = overlap * 100 / sr[i].length; + LOG_W(FLEXRAN_AGENT, "[%d] slice overlap of %d%% detected\n", mod_id, op); + if (op >= 10) /* more than 10% overlap -> refuse */ + return 0; + } + return 1; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h new file mode 100644 index 0000000000..a8f4030d36 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h @@ -0,0 +1,37 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_mac_slice_verification.h + * \brief MAC Agent slice verification helper functions + * \author Robert Schmidt + * \date 2018 + * \version 0.1 + */ + +#include "flexran_agent_common_internal.h" +#include "flexran_agent_mac_internal.h" + +int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls); +int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, + int n_ex, Protocol__FlexDlSlice **update, int n_up); +int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls); +int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, + int n_ex, Protocol__FlexUlSlice **update, int n_up); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index c4c1cd1ca5..7a58cff2e5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -414,193 +414,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in slice_info_t *sli = &RC.mac[module_idP]->slice_info; memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub)); - sli->tot_pct_dl = 0; - sli->avg_pct_dl = 1.0 / sli->n_dl; - //sli->slice_counter = sli->n_dl; - for (i = 0; i < sli->n_dl; i++) { - if (sli->dl[i].pct < 0) { - LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid percentage %f. resetting to zero", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pct); - sli->dl[i].pct = 0; - } - sli->tot_pct_dl += sli->dl[i].pct; - } - - // Check for *intra*slice share activation - if (sli->intraslice_share_active_current != sli->intraslice_share_active) { - if (sli->intraslice_share_active != 1 && sli->intraslice_share_active != 0) { - LOG_W(MAC, - "[eNB %d][DL] frame %d subframe %d: invalid intraslice sharing status (%d), revert to its previous value (%d)\n", - module_idP, frameP, subframeP, sli->intraslice_share_active, sli->intraslice_share_active_current); - sli->intraslice_share_active = sli->intraslice_share_active_current; - } else { - LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: intraslice sharing status has changed (%x-->%x)\n", - module_idP, frameP, subframeP, sli->intraslice_share_active_current, sli->intraslice_share_active); - sli->intraslice_share_active_current = sli->intraslice_share_active; - } - } - - // Check for *inter*slice share activation - if (sli->interslice_share_active_current != sli->interslice_share_active) { - if (sli->interslice_share_active != 1 && sli->interslice_share_active != 0) { - LOG_W(MAC, - "[eNB %d][DL] frame %d subframe %d: invalid interslice sharing status (%d), revert to its previous value (%d)\n", - module_idP, frameP, subframeP, sli->interslice_share_active, sli->interslice_share_active_current); - sli->interslice_share_active = sli->interslice_share_active_current; - } else { - LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: interslice sharing status has changed (%x-->%x)\n", - module_idP, frameP, subframeP, sli->interslice_share_active_current, sli->interslice_share_active); - sli->interslice_share_active_current = sli->interslice_share_active; - } - } - - for (i = 0; i < sli->n_dl; i++) { - - // Load any updated functions - if (sli->dl[i].update_sched > 0) { - sli->dl[i].sched_cb = dlsym(NULL, sli->dl[i].sched_name); - sli->dl[i].update_sched = 0; - sli->dl[i].update_sched_current = 0; - LOG_I(MAC, "update dl scheduler (%s) slice index %d ID %d\n", - sli->dl[i].sched_name, i, sli->dl[i].id); - } - - if (sli->tot_pct_dl <= 1.0) { // the new total RB share is within the range - - // check if the number of slices has changed, and log - if (sli->n_dl_current != sli->n_dl) { - if ((sli->n_dl > 0) && (sli->n_dl <= MAX_NUM_SLICES)) { - LOG_I(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, sli->n_dl_current, sli->n_dl); - sli->n_dl_current = sli->n_dl; - } else { - LOG_W(MAC, "invalid number of DL slices %d, revert to the previous value %d\n", - sli->n_dl, sli->n_dl_current); - sli->n_dl = sli->n_dl_current; - } - } - - // check if the slice rb share has changed, and log the console - if (sli->dl[i].pct_current != sli->dl[i].pct) { // new slice percentage - LOG_I(MAC, - "[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, sli->dl[i].id, frameP, subframeP, - sli->tot_pct_dl_current, sli->tot_pct_dl, - sli->dl[i].pct_current, sli->dl[i].pct); - sli->tot_pct_dl_current = sli->tot_pct_dl; - sli->dl[i].pct_current = sli->dl[i].pct; - } - - // check if the slice max MCS, and log the console - if (sli->dl[i].maxmcs_current != sli->dl[i].maxmcs) { - if ((sli->dl[i].maxmcs >= 0) && (sli->dl[i].maxmcs < 29)) { - LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, sli->dl[i].id, frameP, subframeP, - sli->dl[i].maxmcs_current, sli->dl[i].maxmcs); - sli->dl[i].maxmcs_current = sli->dl[i].maxmcs; - } else { - LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n", - module_idP, sli->dl[i].id, sli->dl[i].maxmcs, sli->dl[i].maxmcs_current); - sli->dl[i].maxmcs = sli->dl[i].maxmcs_current; - } - } - - // check if a new scheduler, and log the console - if (sli->dl[i].update_sched_current != sli->dl[i].update_sched) { - LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].sched_name); - sli->dl[i].update_sched_current = sli->dl[i].update_sched; - } - - } else { - // here we can correct the values, e.g. reduce proportionally - - if (sli->n_dl == sli->n_dl_current) { - LOG_W(MAC, - "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, sli->dl[i].id, sli->tot_pct_dl_current, sli->tot_pct_dl); - if (sli->dl[i].pct >= sli->avg_pct_dl) { - sli->dl[i].pct -= 0.1; - sli->tot_pct_dl -= 0.1; - } - } else { - LOG_W(MAC, - "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, sli->dl[i].id, sli->tot_pct_dl_current, sli->tot_pct_dl, - sli->n_dl, sli->n_dl_current); - sli->n_dl = sli->n_dl_current; - sli->dl[i].pct = sli->dl[i].pct_current; - } - } - - // Check for new slice positions - if (sli->dl[i].pos_low > sli->dl[i].pos_high || - sli->dl[i].pos_low < 0 || - sli->dl[i].pos_high > N_RBG_MAX) { - LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n", - module_idP, sli->dl[i].id, - sli->dl[i].pos_low, sli->dl[i].pos_high, - sli->dl[i].pos_low_current, sli->dl[i].pos_high_current); - sli->dl[i].pos_low = sli->dl[i].pos_low_current; - sli->dl[i].pos_high = sli->dl[i].pos_high_current; - } else { - if (sli->dl[i].pos_low_current != sli->dl[i].pos_low) { - LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pos_low_current, sli->dl[i].pos_low); - sli->dl[i].pos_low_current = sli->dl[i].pos_low; - } - if (sli->dl[i].pos_high_current != sli->dl[i].pos_high) { - LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pos_high_current, sli->dl[i].pos_high); - sli->dl[i].pos_high_current = sli->dl[i].pos_high; - } - } - - // Check for new sorting policy - if (sli->dl[i].sorting_current != sli->dl[i].sorting) { - LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].sorting_current, sli->dl[i].sorting); - sli->dl[i].sorting_current = sli->dl[i].sorting; - } - - // Check for new slice isolation - if (sli->dl[i].isol_current != sli->dl[i].isol) { - if (sli->dl[i].isol != 1 && sli->dl[i].isol != 0) { - LOG_W(MAC, - "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid slice isolation setting (%d), revert to its previous value (%d)\n", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].isol, sli->dl[i].isol_current); - sli->dl[i].isol = sli->dl[i].isol_current; - } else { - LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice isolation setting has changed (%x-->%x)\n", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].isol_current, sli->dl[i].isol); - sli->dl[i].isol_current = sli->dl[i].isol; - } - } - - // Check for new slice priority - if (sli->dl[i].prio_current != sli->dl[i].prio) { - LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%d-->%d)\n", - module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].prio_current, sli->dl[i].prio); - sli->dl[i].prio_current = sli->dl[i].prio; - } - - // Check for new accounting policy - if (sli->dl[i].accounting_current != sli->dl[i].accounting) { - if (sli->dl[i].accounting > 1 || sli->dl[i].accounting < 0) { - LOG_W(MAC, - "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", - module_idP, sli->dl[i].id, frameP, subframeP, - sli->dl[i].accounting, sli->dl[i].accounting_current); - sli->dl[i].accounting = sli->dl[i].accounting_current; - } else { - LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, sli->dl[i].id, frameP, subframeP, - sli->dl[i].accounting_current, sli->dl[i].accounting); - sli->dl[i].accounting_current = sli->dl[i].accounting; - } - } - // Run each enabled slice-specific schedulers one by one sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 68cd5de8bd..4618d363f9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1038,112 +1038,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } } - // perform slice-specifc operations - - sli->tot_pct_ul = 0; - sli->avg_pct_ul = 1.0 / sli->n_ul; - for (i = 0; i < sli->n_ul; i++) { - if (sli->ul[i].pct < 0 ){ - LOG_W(MAC, - "[eNB %d][SLICE %d][UL] frame %d subframe %d: invalid percentage %f. resetting to zero", - module_idP, sli->ul[i].id, frameP, subframeP, sli->ul[i].pct); - sli->ul[i].pct = 0; - } - sli->tot_pct_ul += sli->ul[i].pct; - } - - for (i = 0; i < sli->n_ul; i++) { - - // Load any updated functions - if (sli->ul[i].update_sched > 0 ) { - sli->ul[i].sched_cb = dlsym(NULL, sli->ul[i].sched_name); - sli->ul[i].update_sched = 0; - sli->ul[i].update_sched_current = 0; - //sli->ul[i].pct_current = sli->ul[i].pct; - //sli->tot_pct_ul_current += sli->ul[i].pct; - //if (sli->tot_pct_ul_current > 1) - //sli->tot_pct_ul_current = 1; - LOG_I(MAC,"update ul scheduler (%s) slice index %d ID %d\n", - sli->ul[i].sched_name, i, sli->ul[i].id); - } - // the new total RB share is within the range - if (sli->tot_pct_ul <= 1.0){ - - // check if the number of slices has changed, and log - if (sli->n_ul_current != sli->n_ul ){ - if ((sli->n_ul > 0) && (sli->n_ul <= MAX_NUM_SLICES)) { - LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, sli->n_ul_current, sli->n_ul); - sli->n_ul_current = sli->n_ul; - } else { - LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n", - sli->n_ul, sli->n_ul_current); - sli->n_ul = sli->n_ul_current; - } - } - - // check if the slice rb share has changed, and log the console - if (sli->ul[i].pct_current != sli->ul[i].pct){ - LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, sli->ul[i].id, frameP, subframeP, sli->tot_pct_ul_current, - sli->tot_pct_ul, sli->ul[i].pct_current, sli->ul[i].pct); - sli->tot_pct_ul_current = sli->tot_pct_ul; - sli->ul[i].pct_current = sli->ul[i].pct; - } - - // check if the slice max MCS, and log the console - if (sli->ul[i].maxmcs_current != sli->ul[i].maxmcs){ - if ((sli->ul[i].maxmcs >= 0) && (sli->ul[i].maxmcs <= 20)){ - LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, sli->ul[i].id, frameP, subframeP, - sli->ul[i].maxmcs_current, sli->ul[i].maxmcs); - sli->ul[i].maxmcs_current = sli->ul[i].maxmcs; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n", - module_idP, sli->ul[i].id, sli->ul[i].maxmcs, sli->ul[i].maxmcs_current); - sli->ul[i].maxmcs = sli->ul[i].maxmcs_current; - } - } - - if (sli->ul[i].first_rb_current != sli->ul[i].first_rb){ - if (sli->ul[i].first_rb >= 0){ // FIXME: Max limit is checked in the scheduler - LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice first rb has changed: %d-->%d\n", - module_idP, sli->ul[i].id, frameP, subframeP, - sli->ul[i].first_rb_current, sli->ul[i].first_rb); - sli->ul[i].first_rb_current = sli->ul[i].first_rb; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice first rb %d, revert the previous value %d\n", - module_idP, sli->ul[i].id, sli->ul[i].first_rb, - sli->ul[i].first_rb_current); - sli->ul[i].first_rb = sli->ul[i].first_rb_current; - } - } - - // check if a new scheduler, and log the console - if (sli->ul[i].update_sched_current != sli->ul[i].update_sched) { - LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", - module_idP, sli->ul[i].id, frameP, subframeP, sli->ul[i].sched_name); - sli->ul[i].update_sched_current = sli->ul[i].update_sched; - } - } else { - if (sli->n_ul == sli->n_ul_current) { - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, sli->ul[i].id, sli->tot_pct_ul_current, sli->tot_pct_ul); - if (sli->ul[i].pct > sli->avg_pct_ul) { - sli->ul[i].pct -= 0.1; - sli->tot_pct_ul -= 0.1; - } - } else { - // here we can correct the values, e.g. reduce proportionally - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, sli->ul[i].id, sli->tot_pct_ul_current, - sli->tot_pct_ul, sli->n_ul, sli->n_ul_current); - sli->n_ul = sli->n_ul_current; - sli->ul[i].pct = sli->ul[i].pct_current; - } - } - // Run each enabled slice-specific schedulers one by one sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb); } diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 5507f643f0..6148b63363 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1151,38 +1151,29 @@ typedef void (*slice_scheduler_dl)(module_id_t mod_id, typedef struct { slice_id_t id; - /// RB share for each slice for past and current time + /// RB share for each slice float pct; - float pct_current; - /// whether this slice is isolated from the others for past and current time + /// whether this slice is isolated from the others int isol; - int isol_current; int prio; - int prio_current; /// Frequency ranges for slice positioning int pos_low; int pos_high; - int pos_low_current; - int pos_high_current; - // max mcs for each slice for past and current time + // max mcs for each slice int maxmcs; - int maxmcs_current; /// criteria for sorting policies of the slices uint32_t sorting; - uint32_t sorting_current; /// Accounting policy (just greedy(1) or fair(0) setting for now) int accounting; - int accounting_current; /// Whether the scheduler callback should be updated int update_sched; - int update_sched_current; /// name of available scheduler char *sched_name; @@ -1202,25 +1193,20 @@ typedef void (*slice_scheduler_ul)(module_id_t mod_id, typedef struct { slice_id_t id; - /// RB share for each slice for past and current time + /// RB share for each slice float pct; - float pct_current; - // MAX MCS for each slice for past and current time + // MAX MCS for each slice int maxmcs; - int maxmcs_current; /// criteria for sorting policies of the slices uint32_t sorting; - uint32_t sorting_current; /// starting RB (RB offset) of UL scheduling int first_rb; - int first_rb_current; /// Slice scheduler callback update needed int update_sched; - int update_sched_current; /// name of available scheduler char *sched_name; @@ -1238,28 +1224,16 @@ typedef struct { /// indicates whether remaining RBs after first intra-slice allocation will /// be allocated to UEs of the same slice int intraslice_share_active; - int intraslice_share_active_current; /// indicates whether remaining RBs after slice allocation will be /// allocated to UEs of another slice. Isolated slices will be ignored int interslice_share_active; - int interslice_share_active_current; - /// number of active slices for past and current time in DL + /// number of active DL slices int n_dl; - int n_dl_current; - /// RB share stats for DL - float tot_pct_dl; - float tot_pct_dl_current; - float avg_pct_dl; slice_sched_conf_dl_t dl[MAX_NUM_SLICES]; - /// number of active slices for past and current time in UL + /// number of active UL slices int n_ul; - int n_ul_current; - /// RB share stats for UL - float tot_pct_ul; - float tot_pct_ul_current; - float avg_pct_ul; slice_sched_conf_ul_t ul[MAX_NUM_SLICES]; pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 4c3e22acb7..e34e0e1dd0 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -138,44 +138,24 @@ void mac_top_init_eNB(void) sli = &mac->slice_info; sli->intraslice_share_active = 1; - sli->intraslice_share_active_current = 1; sli->interslice_share_active = 1; - sli->interslice_share_active_current = 1; sli->n_dl = 1; - sli->n_dl_current = 1; - sli->tot_pct_dl = 1; - sli->tot_pct_dl_current = 1; - sli->avg_pct_dl = 0.25; memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); sli->dl[0].pct = 1.0; - sli->dl[0].pct_current = 1.0; sli->dl[0].prio = 10; - sli->dl[0].prio_current = 10; sli->dl[0].pos_high = N_RBG_MAX; - sli->dl[0].pos_high_current = N_RBG_MAX; sli->dl[0].maxmcs = 28; - sli->dl[0].maxmcs_current = 28; sli->dl[0].sorting = 0x012345; - sli->dl[0].sorting_current = 0x012345; sli->dl[0].update_sched = 1; - sli->dl[0].update_sched_current = 1; sli->dl[0].sched_name = "schedule_ue_spec"; sli->n_ul = 1; - sli->n_ul_current = 1; - sli->tot_pct_ul = 1; - sli->tot_pct_ul_current = 1; - sli->avg_pct_ul = 0.25; memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); sli->ul[0].pct = 1.0; - sli->ul[0].pct_current = 1.0; sli->ul[0].maxmcs = 20; - sli->ul[0].maxmcs_current = 20; sli->ul[0].sorting = 0x0123; - sli->ul[0].sorting_current = 0x0123; sli->ul[0].update_sched = 1; - sli->ul[0].update_sched_current = 1; sli->ul[0].sched_name = "schedule_ulsch_rnti"; } From 0778481f7577a64f20780821b0f1b3ba860e949d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 19 May 2018 18:24:25 +0200 Subject: [PATCH 42/99] FlexRAN RAN API: extend scheduler set&get functions - setter & getter have been renamed - setter sets scheduler name and links to the corresponding function - it also returns whether it succeeded (whether the scheduler callback is non-null) - it performs a strdup on the scheduler name - the remove function free the scheduler function name --- openair2/ENB_APP/flexran_agent_ran_api.c | 25 ++++++++++++++---------- openair2/ENB_APP/flexran_agent_ran_api.h | 8 ++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index bea680c48c..4ab5858dda 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -26,6 +26,7 @@ * \version 0.1 */ +#include #include "flexran_agent_ran_api.h" static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) @@ -1483,6 +1484,7 @@ int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) slice_info_t *sli = &RC.mac[mod_id]->slice_info; if (sli->n_dl <= 1) return -1; + if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name); --sli->n_dl; /* move last element to the position of the removed one */ if (slice_idx != sli->n_dl) @@ -1701,16 +1703,17 @@ void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protoco } } -char *flexran_get_dl_slice_scheduler_name(mid_t mod_id, int slice_idx) +char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return NULL; return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name; } -void flexran_set_dl_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name) +int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { - if (!mac_is_present(mod_id)) return; - RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = name; - RC.mac[mod_id]->slice_info.dl[slice_idx].update_sched = 1; + if (!mac_is_present(mod_id)) return 0; + RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name); + RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name); + return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL; } int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx) @@ -1760,6 +1763,7 @@ int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) slice_info_t *sli = &RC.mac[mod_id]->slice_info; if (sli->n_ul <= 1) return -1; + if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name); --sli->n_ul; /* move last element to the position of the removed one */ if (slice_idx != sli->n_ul) @@ -1832,14 +1836,15 @@ void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs; } -char *flexran_get_ul_slice_scheduler_name(mid_t mod_id, int slice_idx) +char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return NULL; return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name; } -void flexran_set_ul_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name) +int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { - if (!mac_is_present(mod_id)) return; - RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = name; - RC.mac[mod_id]->slice_info.ul[slice_idx].update_sched = 1; + if (!mac_is_present(mod_id)) return 0; + RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name); + RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name); + return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL; } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 18cd353f71..a959c4fd50 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -589,9 +589,9 @@ Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mo void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting); /* Get the scheduler name for a slice in DL */ -char *flexran_get_dl_slice_scheduler_name(mid_t mod_id, int slice_idx); +char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx); /* Set the scheduler name for a slice in DL */ -void flexran_set_dl_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name); +int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name); /* Get the number of slices in UL */ int flexran_get_num_ul_slices(mid_t mod_id); @@ -653,6 +653,6 @@ void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); /*void flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__UlAccountingPolicy accountin);*/ /* Get the scheduler name for a slice in UL */ -char *flexran_get_ul_slice_scheduler_name(mid_t mod_id, int slice_idx); +char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx); /* Set the scheduler name for a slice in UL */ -void flexran_set_ul_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name); +int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name); From 766e8a5bbe3eeb0e49814bf95d3025ce69058ff3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 19 May 2018 18:27:20 +0200 Subject: [PATCH 43/99] link to scheduler function in mac init fct --- openair2/LAYER2/MAC/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index e34e0e1dd0..fcbcf60567 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -29,6 +29,7 @@ */ +#include #include "mac.h" #include "mac_proto.h" #include "mac_extern.h" @@ -149,6 +150,8 @@ void mac_top_init_eNB(void) sli->dl[0].sorting = 0x012345; sli->dl[0].update_sched = 1; sli->dl[0].sched_name = "schedule_ue_spec"; + sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); + AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); sli->n_ul = 1; memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); @@ -157,6 +160,8 @@ void mac_top_init_eNB(void) sli->ul[0].sorting = 0x0123; sli->ul[0].update_sched = 1; sli->ul[0].sched_name = "schedule_ulsch_rnti"; + sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); + AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); } } From 328a464e375506e13f0d98b10ba326ebc6355fbe Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 19 May 2018 18:27:50 +0200 Subject: [PATCH 44/99] remove update_sched slice param variables - whether a scheduler callback has to be changed is now handled by the agent --- openair2/LAYER2/MAC/mac.h | 6 ------ openair2/LAYER2/MAC/main.c | 2 -- 2 files changed, 8 deletions(-) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 6148b63363..ed6171dceb 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1172,9 +1172,6 @@ typedef struct { /// Accounting policy (just greedy(1) or fair(0) setting for now) int accounting; - /// Whether the scheduler callback should be updated - int update_sched; - /// name of available scheduler char *sched_name; @@ -1205,9 +1202,6 @@ typedef struct { /// starting RB (RB offset) of UL scheduling int first_rb; - /// Slice scheduler callback update needed - int update_sched; - /// name of available scheduler char *sched_name; diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index fcbcf60567..8d3d88aaaa 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -148,7 +148,6 @@ void mac_top_init_eNB(void) sli->dl[0].pos_high = N_RBG_MAX; sli->dl[0].maxmcs = 28; sli->dl[0].sorting = 0x012345; - sli->dl[0].update_sched = 1; sli->dl[0].sched_name = "schedule_ue_spec"; sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); @@ -158,7 +157,6 @@ void mac_top_init_eNB(void) sli->ul[0].pct = 1.0; sli->ul[0].maxmcs = 20; sli->ul[0].sorting = 0x0123; - sli->ul[0].update_sched = 1; sli->ul[0].sched_name = "schedule_ulsch_rnti"; sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); From d8c2943f60488b08bf6d91156f5c6509ff490bc2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 19 May 2018 18:28:48 +0200 Subject: [PATCH 45/99] FlexRAN RAN API: slice creation does not set default vals --- openair2/ENB_APP/flexran_agent_ran_api.c | 46 ++---------------------- openair2/ENB_APP/flexran_agent_ran_api.h | 8 ++--- 2 files changed, 6 insertions(+), 48 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 4ab5858dda..dc74652874 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1435,35 +1435,13 @@ int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl; } -int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx) +int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - if (!flexran_dl_slice_exists(mod_id, slice_default_values_idx)) return -1; int newidx = RC.mac[mod_id]->slice_info.n_dl; if (newidx >= MAX_NUM_SLICES) return -1; - ++RC.mac[mod_id]->slice_info.n_dl; flexran_set_dl_slice_id(mod_id, newidx, slice_id); - flexran_set_dl_slice_percentage(mod_id, newidx, - flexran_get_dl_slice_percentage(mod_id, slice_default_values_idx)); - flexran_set_dl_slice_isolation(mod_id, newidx, - flexran_get_dl_slice_isolation(mod_id, slice_default_values_idx)); - flexran_set_dl_slice_priority(mod_id, newidx, - flexran_get_dl_slice_priority(mod_id, slice_default_values_idx)); - flexran_set_dl_slice_position_low(mod_id, newidx, - flexran_get_dl_slice_position_low(mod_id, slice_default_values_idx)); - flexran_set_dl_slice_position_high(mod_id, newidx, - flexran_get_dl_slice_position_high(mod_id, slice_default_values_idx)); - flexran_set_dl_slice_maxmcs(mod_id, newidx, - flexran_get_dl_slice_maxmcs(mod_id, slice_default_values_idx)); - Protocol__FlexDlSorting *sorting = NULL; - int n = flexran_get_dl_slice_sorting(mod_id, slice_default_values_idx, &sorting); - flexran_set_dl_slice_sorting(mod_id, newidx, sorting, n); - free(sorting); - flexran_set_dl_slice_accounting_policy(mod_id, newidx, - flexran_get_dl_slice_accounting_policy(mod_id, slice_default_values_idx)); - flexran_set_dl_slice_scheduler_name(mod_id, newidx, - flexran_get_dl_slice_scheduler_name(mod_id, slice_default_values_idx)); return newidx; } @@ -1716,33 +1694,13 @@ int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL; } -int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx) +int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - if (!flexran_ul_slice_exists(mod_id, slice_default_values_idx)) return -1; int newidx = RC.mac[mod_id]->slice_info.n_ul; if (newidx >= MAX_NUM_SLICES) return -1; - ++RC.mac[mod_id]->slice_info.n_ul; flexran_set_ul_slice_id(mod_id, newidx, slice_id); - flexran_set_ul_slice_percentage(mod_id, newidx, - flexran_get_ul_slice_percentage(mod_id, slice_default_values_idx)); - /*flexran_set_ul_slice_isolation(mod_id, newidx, - flexran_get_ul_slice_isolation(mod_id, slice_default_values_idx)); - flexran_set_ul_slice_priority(mod_id, newidx, - flexran_get_ul_slice_priority(mod_id, slice_default_values_idx));*/ - flexran_set_ul_slice_first_rb(mod_id, newidx, - flexran_get_ul_slice_first_rb(mod_id, slice_default_values_idx)); - flexran_set_ul_slice_maxmcs(mod_id, newidx, - flexran_get_ul_slice_maxmcs(mod_id, slice_default_values_idx)); - /*Protocol__FlexUlSorting *sorting = NULL; - int n = flexran_get_ul_slice_sorting(mod_id, slice_default_values_idx, &sorting); - flexran_set_ul_slice_sorting(mod_id, newidx, sorting, n); - free(sorting);*/ - /*flexran_set_ul_slice_accounting_policy(mod_id, newidx, - flexran_get_ul_slice_accounting_policy(mod_id, slice_default_values_idx));*/ - flexran_set_ul_slice_scheduler_name(mod_id, newidx, - flexran_get_ul_slice_scheduler_name(mod_id, slice_default_values_idx)); return newidx; } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index a959c4fd50..d64d5806e6 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -535,8 +535,8 @@ int flexran_get_num_dl_slices(mid_t mod_id); /* Query slice existence in DL. Return is boolean value */ int flexran_dl_slice_exists(mid_t mod_id, int slice_idx); -/* Create slice in DL with values from another slice, returns the new slice index */ -int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx); +/* Create slice in DL, returns the new slice index */ +int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); /* Finds slice in DL with given slice_id and returns slice index */ int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); /* Remove slice in DL, returns new number of slices or -1 on error */ @@ -599,8 +599,8 @@ int flexran_get_num_ul_slices(mid_t mod_id); /* Query slice existence in UL. Return is boolean value */ int flexran_ul_slice_exists(mid_t mod_id, int slice_idx); -/* Create slice in UL with values from another slice, returns the new slice index */ -int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx); +/* Create slice in UL, returns the new slice index */ +int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); /* Finds slice in UL with given slice_id and returns slice index */ int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); /* Remove slice in UL */ From 8804319322372b0b1d33a4e05aaa3ef8b3ac5ffe Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 20 May 2018 17:16:38 +0200 Subject: [PATCH 46/99] FlexRAN MAC: before verifying slice params, set default vals - in order to facilitate the steps as verification and parameter setting, slices are "filled up" with default values: * if it is an update, with the values of the concerned slice * if it is a new one, with the parameters of slice 0 - because of this, it can be assumed that all slices have all parameters --- .../MAC/flexran_agent_mac_internal.c | 110 +++++++++++------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index d75712d430..a1a905d4a5 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1012,37 +1012,37 @@ void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__F void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) { - if (update->has_label && update->label != exist->label) { + if (update->label != exist->label) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update label: %d -> %d\n", update->id, exist->label, update->label); exist->label = update->label; } - if (update->has_percentage && update->percentage != exist->percentage) { + if (update->percentage != exist->percentage) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update percentage: %d -> %d\n", update->id, exist->percentage, update->percentage); exist->percentage = update->percentage; } - if (update->has_isolation && update->isolation != exist->isolation) { + if (update->isolation != exist->isolation) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update isolation: %d -> %d\n", update->id, exist->isolation, update->isolation); exist->isolation = update->isolation; } - if (update->has_priority && update->priority != exist->priority) { + if (update->priority != exist->priority) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update priority: %d -> %d\n", update->id, exist->priority, update->priority); exist->priority = update->priority; } - if (update->has_position_low && update->position_low != exist->position_low) { + if (update->position_low != exist->position_low) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_low: %d -> %d\n", update->id, exist->position_low, update->position_low); exist->position_low = update->position_low; } - if (update->has_position_high && update->position_high != exist->position_high) { + if (update->position_high != exist->position_high) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_high: %d -> %d\n", update->id, exist->position_high, update->position_high); exist->position_high = update->position_high; } - if (update->has_maxmcs && update->maxmcs != exist->maxmcs) { + if (update->maxmcs != exist->maxmcs) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update maxmcs: %d -> %d\n", update->id, exist->maxmcs, update->maxmcs); exist->maxmcs = update->maxmcs; @@ -1064,7 +1064,7 @@ void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSli for (int i = 0; i < n; i++) exist->sorting[i] = update->sorting[i]; } - if (update->has_accounting && update->accounting != exist->accounting) { + if (update->accounting != exist->accounting) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update accounting: %d -> %d\n", update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; @@ -1078,37 +1078,37 @@ void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSli void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update) { - if (update->has_label && update->label != exist->label) { + if (update->label != exist->label) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update label: %d -> %d\n", update->id, exist->label, update->label); exist->label = update->label; } - if (update->has_percentage && update->percentage != exist->percentage) { + if (update->percentage != exist->percentage) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update percentage: %d -> %d\n", update->id, exist->percentage, update->percentage); exist->percentage = update->percentage; } - if (update->has_isolation && update->isolation != exist->isolation) { + if (update->isolation != exist->isolation) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update isolation: %d -> %d\n", update->id, exist->isolation, update->isolation); exist->isolation = update->isolation; } - if (update->has_priority && update->priority != exist->priority) { + if (update->priority != exist->priority) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update priority: %d -> %d\n", update->id, exist->priority, update->priority); exist->priority = update->priority; } - if (update->has_first_rb && update->first_rb != exist->first_rb) { + if (update->first_rb != exist->first_rb) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update first_rb: %d -> %d\n", update->id, exist->first_rb, update->first_rb); exist->first_rb = update ->first_rb; } - /*if (update->has_length_rb && update->lenght_rb != exist->lenght_rb) { + /*if (update->lenght_rb != exist->lenght_rb) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update lenght_rb: %d -> %d\n", update->id, exist->lenght_rb, update->lenght_rb); exist->lenght_rb = update->lenght_rb; }*/ - if (update->has_maxmcs && update->maxmcs != exist->maxmcs) { + if (update->maxmcs != exist->maxmcs) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update maxmcs: %d -> %d\n", update->id, exist->maxmcs, update->maxmcs); exist->maxmcs = update->maxmcs; @@ -1130,7 +1130,7 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli for (i = 0; i < n; i++) exist->sorting[i] = update->sorting[i]; } - if (update->has_accounting && update->accounting != exist->accounting) { + if (update->accounting != exist->accounting) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update accounting: %d -> %d\n", update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; @@ -1142,49 +1142,52 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli } } -void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s) +void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s, Protocol__FlexDlSlice *from) { + /* function fills slice with information from another slice or with default + * values (currently slice 0) if from is NULL */ /* TODO fill the slice depending on the chosen label */ - /* for now, we fill it up with the information from slice 0 */ - /* assume there is an ID (will be checked later) */ if (!s->has_label) { s->has_label = 1; - s->label = sc_update[mod_id]->dl[0]->label; + s->label = from ? from->label : sc_update[mod_id]->dl[0]->label; } if (!s->has_percentage) { s->has_percentage = 1; - s->percentage = sc_update[mod_id]->dl[0]->percentage; + s->percentage = from ? from->percentage : sc_update[mod_id]->dl[0]->percentage; } if (!s->has_isolation) { s->has_isolation = 1; - s->isolation = sc_update[mod_id]->dl[0]->isolation; + s->isolation = from ? from->isolation : sc_update[mod_id]->dl[0]->isolation; } if (!s->has_priority) { s->has_priority = 1; - s->priority = sc_update[mod_id]->dl[0]->priority; + s->priority = from ? from->priority : sc_update[mod_id]->dl[0]->priority; } if (!s->has_position_low) { s->has_position_low = 1; - s->position_low = sc_update[mod_id]->dl[0]->position_low; + s->position_low = from ? from->position_low : sc_update[mod_id]->dl[0]->position_low; } if (!s->has_position_high) { s->has_position_high = 1; - s->position_high = sc_update[mod_id]->dl[0]->position_high; + s->position_high = from ? from->position_high : sc_update[mod_id]->dl[0]->position_high; } if (!s->has_maxmcs) { s->has_maxmcs = 1; - s->maxmcs = sc_update[mod_id]->dl[0]->maxmcs; + s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->dl[0]->maxmcs; } if (s->n_sorting == 0) { - s->n_sorting = sc_update[0]->dl[0]->n_sorting; + s->n_sorting = from ? from->n_sorting : sc_update[mod_id]->dl[0]->n_sorting; /* TODO Dangerous? */ - s->sorting = sc_update[0]->dl[0]->sorting; + s->sorting = from ? from->sorting : sc_update[mod_id]->dl[0]->sorting; } if (!s->has_accounting) { /* TODO Dangerous? */ - s->accounting = sc_update[0]->dl[0]->accounting; + s->accounting = from ? from->accounting : sc_update[mod_id]->dl[0]->accounting; + } + if (!s->scheduler_name) { + /* TODO Dangerous? */ + s->scheduler_name = from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name; } - /* scheduler name not set, cannot be changed for the moment */ } Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id) @@ -1210,45 +1213,48 @@ Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id) return to; } -void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s) +void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s, Protocol__FlexUlSlice *from) { + /* function fills slice with information from another slice or with default + * values (currently slice 0) if from is NULL */ /* TODO fill the slice depending on the chosen label */ - /* for now, we fill it up with the information from slice 0 */ - /* assume there is an ID (will be checked later) */ if (!s->has_label) { s->has_label = 1; - s->label = sc_update[mod_id]->ul[0]->label; + s->label = from ? from->label : sc_update[mod_id]->ul[0]->label; } if (!s->has_percentage) { s->has_percentage = 1; - s->percentage = sc_update[mod_id]->ul[0]->percentage; + s->percentage = from ? from->percentage : sc_update[mod_id]->ul[0]->percentage; } if (!s->has_isolation) { s->has_isolation = 1; - s->isolation = sc_update[mod_id]->ul[0]->isolation; + s->isolation = from ? from->isolation : sc_update[mod_id]->ul[0]->isolation; } if (!s->has_priority) { s->has_priority = 1; - s->priority = sc_update[mod_id]->ul[0]->priority; + s->priority = from ? from->priority : sc_update[mod_id]->ul[0]->priority; } if (!s->has_first_rb) { s->has_first_rb = 1; - s->first_rb = sc_update[mod_id]->ul[0]->first_rb; + s->first_rb = from ? from->first_rb : sc_update[mod_id]->ul[0]->first_rb; } if (!s->has_maxmcs) { s->has_maxmcs = 1; - s->maxmcs = sc_update[mod_id]->ul[0]->maxmcs; + s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->ul[0]->maxmcs; } if (s->n_sorting == 0) { - s->n_sorting = sc_update[0]->ul[0]->n_sorting; + s->n_sorting = from ? from->n_sorting : sc_update[0]->ul[0]->n_sorting; /* TODO Dangerous? */ - s->sorting = sc_update[0]->ul[0]->sorting; + s->sorting = from ? from->sorting : sc_update[0]->ul[0]->sorting; } if (!s->has_accounting) { /* TODO Dangerous? */ - s->accounting = sc_update[0]->ul[0]->accounting; + s->accounting = from ? from->accounting : sc_update[0]->ul[0]->accounting; + } + if (!s->scheduler_name) { + /* TODO Dangerous? */ + s->scheduler_name = from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name; } - /* scheduler name not set, cannot be changed for the moment */ } Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id) @@ -1288,7 +1294,14 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) } else { /* verify slice parameters */ for (int i = 0; i < sup->n_dl; i++) { - fill_dl_slice(mod_id, sup->dl[i]); + if (!sup->dl[i]->has_id) { + verified = 0; + break; + } + Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); + /* fill up so that the slice is complete. This way, we don't need to + * worry about it later */ + fill_dl_slice(mod_id, sup->dl[i], dls); verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]); if (!verified) break; } @@ -1317,7 +1330,14 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) } else { /* verify slice parameters */ for (int i = 0; i < sup->n_ul; i++) { - fill_ul_slice(mod_id, sup->ul[i]); + if (!sup->ul[i]->has_id) { + verified = 0; + break; + } + Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); + /* fill up so that the slice is complete. This way, we don't need to + * worry about it later */ + fill_ul_slice(mod_id, sup->ul[i], uls); verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]); if (!verified) break; } From 6e5a2f45ced70f7ecbc6027048da9ac8ed0d4b97 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 20 May 2018 17:12:15 +0200 Subject: [PATCH 47/99] FlexRAN: set deleted slice configuration to zero --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 0985539f8c..1e091feba5 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1421,6 +1421,7 @@ void flexran_check_and_remove_slices(mid_t mod_id) /* don't update slice_config, it will be read in below */ /* we need to memcpy the higher slice to the position we just deleted */ memcpy(dl[i], dl[n_dl-1], sizeof(*dl[n_dl-1])); + memset(dl[n_dl-1], 0, sizeof(*dl[n_dl-1])); --sc_update[mod_id]->n_dl; } Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul; @@ -1436,6 +1437,7 @@ void flexran_check_and_remove_slices(mid_t mod_id) mod_id, i, ul[i]->id); /* see DL remarks */ memcpy(ul[i], ul[n_ul-1], sizeof(*ul[n_ul-1])); + memset(ul[n_ul-1], 0, sizeof(*ul[n_ul-1])); --sc_update[mod_id]->n_ul; } } From bd041a34aafe7133ad886264ce59ba86658f9ddc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 20 May 2018 17:14:55 +0200 Subject: [PATCH 48/99] use changed RAN API, set scheduler for new slice --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 4 +-- .../MAC/flexran_agent_mac_internal.c | 34 +++++++++++++------ .../flexran_agent_mac_slice_verification.c | 18 +++++++--- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 1e091feba5..c752469414 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1497,12 +1497,12 @@ void flexran_agent_slice_update(mid_t mod_id) /* create new DL and UL slices if necessary */ for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) { - flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id, 0); + flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id); slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); } for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) { - flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id, 0); + flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id); slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index a1a905d4a5..e1ca3273e8 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -969,7 +969,7 @@ void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__F if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL; dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx); dl_slice->has_accounting = 1; - dl_slice->scheduler_name = flexran_get_dl_slice_scheduler_name(mod_id, slice_idx); + dl_slice->scheduler_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx); } void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice) @@ -1007,7 +1007,7 @@ void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__F if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/ /*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/ ul_slice->has_accounting = 0; - ul_slice->scheduler_name = flexran_get_ul_slice_scheduler_name(mod_id, slice_idx); + ul_slice->scheduler_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx); } void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) @@ -1069,10 +1069,12 @@ void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSli update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; } - if (update->scheduler_name - && strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_W(FLEXRAN_AGENT, "[DL slice %d] ignoring new scheduler name \"%s\"!\n", - update->id, update->scheduler_name); + if (!exist->scheduler_name + || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { + LOG_I(FLEXRAN_AGENT, "[DL slice %d] update scheduler: %s -> %s\n", + update->id, exist->scheduler_name, update->scheduler_name); + /* TODO dangerous? */ + exist->scheduler_name = update->scheduler_name; } } @@ -1135,10 +1137,12 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; } - if (update->scheduler_name - && strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_W(FLEXRAN_AGENT, "[UL slice %d] ignoring new scheduler name \"%s\"!\n", - update->id, update->scheduler_name); + if (!exist->scheduler_name + || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { + LOG_I(FLEXRAN_AGENT, "[UL slice %d] update scheduler: %s -> %s\n", + update->id, exist->scheduler_name, update->scheduler_name); + /* TODO dangerous? */ + exist->scheduler_name = update->scheduler_name; } } @@ -1416,6 +1420,11 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); changes++; } + if (!oldc->scheduler_name + || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { + flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + changes++; + } return changes; } @@ -1477,6 +1486,11 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", mod_id, slice_idx); } + if (!oldc->scheduler_name + || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { + flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + changes++; + } return changes; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c index addc8d2e75..5dcc355612 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -84,8 +84,13 @@ int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls) } /* sorting is an enum */ /* accounting is an enum */ - if (dls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler is not allowed\n", mod_id); + if (!dls->scheduler_name) { + LOG_E(FLEXRAN_AGENT, "[%d] no scheduler name found\n", mod_id); + return 0; + } + if (strcmp(dls->scheduler_name, "schedule_ue_spec") != 0) { + LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler to something different " + "than schedule_ue_spec is currently not allowed\n", mod_id); return 0; } @@ -183,8 +188,13 @@ int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) } /* sorting is an enum */ /* accounting is an enum */ - if (uls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler is not allowed\n", mod_id); + if (!uls->scheduler_name) { + LOG_E(FLEXRAN_AGENT, "[%d] no scheduler name found\n", mod_id); + return 0; + } + if (strcmp(uls->scheduler_name, "schedule_ulsch_rnti") != 0) { + LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler to something different " + "than schedule_ulsch_rnti is currently not allowed\n", mod_id); return 0; } From 0c0e7b6ead51151ec7f7a5b7040bc6b87eb04255 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 21 May 2018 12:25:17 +0200 Subject: [PATCH 49/99] simplify control flow --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 22 ++----------------- .../MAC/flexran_agent_mac_internal.c | 6 +---- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index c752469414..834283945b 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1472,24 +1472,6 @@ void flexran_agent_slice_update(mid_t mod_id) flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); } - /* in case we tried to add a slice and it failed (e.g. due to high sum - * percentage being too high), revert to the correct number of slices. - * Also, do not write if we try the last time */ - if (perform_slice_config_update_count == 1) { - if (slice_config[mod_id]->n_dl != sc_update[mod_id]->n_dl) { - sc_update[mod_id]->n_dl = slice_config[mod_id]->n_dl; - LOG_W(FLEXRAN_AGENT, "[%d] reverting to original number of %ld DL slices\n", - mod_id, sc_update[mod_id]->n_dl); - } - if (slice_config[mod_id]->n_ul != sc_update[mod_id]->n_ul) { - sc_update[mod_id]->n_ul = slice_config[mod_id]->n_ul; - LOG_W(FLEXRAN_AGENT, "[%d] reverting to original number of %ld UL slices\n", - mod_id, sc_update[mod_id]->n_ul); - } - pthread_mutex_unlock(&sc_update_mtx); - return; - } - /********* write new config *********/ /* check for removal (sc_update[X]->dl[Y].percentage == 0) * and update sc_update & slice_config accordingly */ @@ -1499,22 +1481,22 @@ void flexran_agent_slice_update(mid_t mod_id) for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) { flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id); slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); - flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); } for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) { flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id); slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); - flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); } for (i = 0; i < slice_config[mod_id]->n_dl; i++) { changes += apply_new_slice_dl_config(mod_id, slice_config[mod_id]->dl[i], sc_update[mod_id]->dl[i]); + flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); } for (i = 0; i < slice_config[mod_id]->n_ul; i++) { changes += apply_new_slice_ul_config(mod_id, slice_config[mod_id]->ul[i], sc_update[mod_id]->ul[i]); + flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); } if (n_ue_slice_assoc_updates > 0) { changes += apply_ue_slice_assoc_update(mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index e1ca3273e8..50eb17d919 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1365,11 +1365,7 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) } pthread_mutex_unlock(&sc_update_mtx); - /* perform the slice configuration reads a couple of times. If there are - * inconsistencies (i.e. the MAC refuses a configuration), we will have a - * couple of warnings because the current configuration and the one in - * sc_update will be diverged */ - perform_slice_config_update_count = 3; + perform_slice_config_update_count = 1; } int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc) From e94b0bde512964c81da34a031f06f51fe8bdedcc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 21 May 2018 12:28:31 +0200 Subject: [PATCH 50/99] FlexRAN fixes * properly allocate memory for scheduler name/sorting * free mem of sc_update, include todo for slice_config * set has_x to one, add fct whether sorting update necessary * set n_ul/n_dl to correct value after every loop iteration * support for delete of multiple slices * allocate memory for scheduler name in slice_config * check that we really set the scheduler --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 60 ++++++-- .../MAC/flexran_agent_mac_internal.c | 138 +++++++++++------- 2 files changed, 130 insertions(+), 68 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 834283945b..1daf0d5183 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1405,40 +1405,67 @@ void flexran_create_config_structures(mid_t mod_id) void flexran_check_and_remove_slices(mid_t mod_id) { - int i; Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl; - size_t n_dl = sc_update[mod_id]->n_dl; - for (i = 0; i < n_dl; i++) { + Protocol__FlexDlSlice **dlreal = slice_config[mod_id]->dl; + int i = 0; + while (i < sc_update[mod_id]->n_dl) { /* remove slices whose percentage is zero */ - if (dl[i]->percentage > 0) continue; + if (dl[i]->percentage > 0) { + ++i; + continue; + } if (flexran_remove_dl_slice(mod_id, i) < 1) { LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", mod_id, i, dl[i]->id); + ++i; continue; } LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", mod_id, i, dl[i]->id); - /* don't update slice_config, it will be read in below */ - /* we need to memcpy the higher slice to the position we just deleted */ - memcpy(dl[i], dl[n_dl-1], sizeof(*dl[n_dl-1])); - memset(dl[n_dl-1], 0, sizeof(*dl[n_dl-1])); + if (dl[i]->n_sorting > 0) free(dl[i]->sorting); + free(dl[i]->scheduler_name); + if (dlreal[i]->n_sorting > 0) { + dlreal[i]->n_sorting = 0; + free(dlreal[i]->sorting); + } + free(dlreal[i]->scheduler_name); --sc_update[mod_id]->n_dl; + --slice_config[mod_id]->n_dl; + const size_t last = sc_update[mod_id]->n_dl; + /* we need to memcpy the higher slice to the position we just deleted */ + memcpy(dl[i], dl[last], sizeof(*dl[last])); + memset(dl[last], 0, sizeof(*dl[last])); + memcpy(dlreal[i], dlreal[last], sizeof(*dlreal[last])); + memset(dlreal[last], 0, sizeof(*dlreal[last])); + /* dont increase i but recheck the slice which has been copied to here */ } Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul; - size_t n_ul = sc_update[mod_id]->n_ul; - for (i = 0; i < n_ul; i++) { - if (ul[i]->percentage > 0) continue; + Protocol__FlexUlSlice **ulreal = slice_config[mod_id]->ul; + i = 0; + while (i < sc_update[mod_id]->n_ul) { + if (ul[i]->percentage > 0) { + ++i; + continue; + } if (flexran_remove_ul_slice(mod_id, i) < 1) { LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", mod_id, i, ul[i]->id); + ++i; continue; } LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", mod_id, i, ul[i]->id); - /* see DL remarks */ - memcpy(ul[i], ul[n_ul-1], sizeof(*ul[n_ul-1])); - memset(ul[n_ul-1], 0, sizeof(*ul[n_ul-1])); + free(ul[i]->scheduler_name); + free(ulreal[i]->scheduler_name); --sc_update[mod_id]->n_ul; + --slice_config[mod_id]->n_ul; + const size_t last = sc_update[mod_id]->n_ul; + /* see DL remarks */ + memcpy(ul[i], ul[last], sizeof(*ul[last])); + memset(ul[last], 0, sizeof(*ul[last])); + memcpy(ulreal[i], ulreal[last], sizeof(*ulreal[last])); + memset(ulreal[last], 0, sizeof(*ulreal[last])); + /* dont increase i but recheck the slice which has been copied to here */ } } @@ -1480,12 +1507,13 @@ void flexran_agent_slice_update(mid_t mod_id) /* create new DL and UL slices if necessary */ for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) { flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id); - slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); } for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) { flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id); - slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); } + slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); + slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); + changes += apply_new_slice_config(mod_id, slice_config[mod_id], sc_update[mod_id]); for (i = 0; i < slice_config[mod_id]->n_dl; i++) { changes += apply_new_slice_dl_config(mod_id, slice_config[mod_id]->dl[i], diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 50eb17d919..c85f410313 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -969,7 +969,12 @@ void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__F if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL; dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx); dl_slice->has_accounting = 1; - dl_slice->scheduler_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx); + const char *s_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx); + if (!dl_slice->scheduler_name + || strcmp(dl_slice->scheduler_name, s_name) != 0) { + dl_slice->scheduler_name = realloc(dl_slice->scheduler_name, strlen(s_name) + 1); + strcpy(dl_slice->scheduler_name, s_name); + } } void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice) @@ -1007,7 +1012,34 @@ void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__F if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/ /*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/ ul_slice->has_accounting = 0; - ul_slice->scheduler_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx); + const char *s_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx); + if (!ul_slice->scheduler_name + || strcmp(ul_slice->scheduler_name, s_name) != 0) { + ul_slice->scheduler_name = realloc(ul_slice->scheduler_name, strlen(s_name) + 1); + strcpy(ul_slice->scheduler_name, s_name); + } +} + +int check_dl_sorting_update(Protocol__FlexDlSlice *old, Protocol__FlexDlSlice *new) +{ + /* sorting_update => true when old->n_sorting == 0 or different numbers of + * elements; otherwise will check * element-wise */ + int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); + for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { + sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); + } + return sorting_update; +} + +int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *new) +{ + /* sorting_update => true when old->n_sorting == 0 or different numbers of + * elements; otherwise will check * element-wise */ + int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); + for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { + sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); + } + return sorting_update; } void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) @@ -1016,65 +1048,66 @@ void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSli LOG_I(FLEXRAN_AGENT, "[DL slice %d] update label: %d -> %d\n", update->id, exist->label, update->label); exist->label = update->label; + exist->has_label = 1; } if (update->percentage != exist->percentage) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update percentage: %d -> %d\n", update->id, exist->percentage, update->percentage); exist->percentage = update->percentage; + exist->has_percentage = 1; } if (update->isolation != exist->isolation) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update isolation: %d -> %d\n", update->id, exist->isolation, update->isolation); exist->isolation = update->isolation; + exist->has_isolation = 1; } if (update->priority != exist->priority) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update priority: %d -> %d\n", update->id, exist->priority, update->priority); exist->priority = update->priority; + exist->has_priority = 1; } if (update->position_low != exist->position_low) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_low: %d -> %d\n", update->id, exist->position_low, update->position_low); exist->position_low = update->position_low; + exist->has_position_low = 1; } if (update->position_high != exist->position_high) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_high: %d -> %d\n", update->id, exist->position_high, update->position_high); exist->position_high = update->position_high; + exist->has_position_high = 1; } if (update->maxmcs != exist->maxmcs) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update maxmcs: %d -> %d\n", update->id, exist->maxmcs, update->maxmcs); exist->maxmcs = update->maxmcs; + exist->has_maxmcs = 1; } - int sorting_update = 0; - int n = min(exist->n_sorting, update->n_sorting); - /* check whether something has changed. If update->n_sorting is 0, - * sorting_update will remain false, so no update will be done */ - int i = 0; - while(i < n && !sorting_update) { - sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]); - i++; - } - if (sorting_update) { + if (check_dl_sorting_update(exist, update)) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update sorting array\n", update->id); - if (exist->n_sorting != update->n_sorting) - LOG_W(FLEXRAN_AGENT, "[slice %d] only writing %d elements\n", - update->id, n); - for (int i = 0; i < n; i++) + if (exist->n_sorting != update->n_sorting) { + exist->n_sorting = update->n_sorting; + exist->sorting = realloc(exist->sorting, exist->n_sorting * sizeof(Protocol__FlexDlSorting)); + if (!exist->sorting) exist->n_sorting = 0; + } + for (int i = 0; i < exist->n_sorting; i++) exist->sorting[i] = update->sorting[i]; } if (update->accounting != exist->accounting) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update accounting: %d -> %d\n", update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; + exist->has_accounting = 1; } if (!exist->scheduler_name || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { LOG_I(FLEXRAN_AGENT, "[DL slice %d] update scheduler: %s -> %s\n", update->id, exist->scheduler_name, update->scheduler_name); - /* TODO dangerous? */ - exist->scheduler_name = update->scheduler_name; + if (exist->scheduler_name) free(exist->scheduler_name); + exist->scheduler_name = strdup(update->scheduler_name); } } @@ -1084,26 +1117,31 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli LOG_I(FLEXRAN_AGENT, "[UL slice %d] update label: %d -> %d\n", update->id, exist->label, update->label); exist->label = update->label; + exist->has_label = 1; } if (update->percentage != exist->percentage) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update percentage: %d -> %d\n", update->id, exist->percentage, update->percentage); exist->percentage = update->percentage; + exist->has_percentage = 1; } if (update->isolation != exist->isolation) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update isolation: %d -> %d\n", update->id, exist->isolation, update->isolation); exist->isolation = update->isolation; + exist->has_isolation = 1; } if (update->priority != exist->priority) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update priority: %d -> %d\n", update->id, exist->priority, update->priority); exist->priority = update->priority; + exist->has_priority = 1; } if (update->first_rb != exist->first_rb) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update first_rb: %d -> %d\n", update->id, exist->first_rb, update->first_rb); exist->first_rb = update ->first_rb; + exist->has_first_rb = 1; } /*if (update->lenght_rb != exist->lenght_rb) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update lenght_rb: %d -> %d\n", @@ -1114,11 +1152,11 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli LOG_I(FLEXRAN_AGENT, "[UL slice %d] update maxmcs: %d -> %d\n", update->id, exist->maxmcs, update->maxmcs); exist->maxmcs = update->maxmcs; + exist->has_maxmcs = 1; } + /* TODO int sorting_update = 0; int n = min(exist->n_sorting, update->n_sorting); - /* check whether something has changed. If update-> n_sorting is 0, - * sorting_update will remain false, so no update will be done */ int i = 0; while (i < n && !sorting_update) { sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]); @@ -1132,17 +1170,19 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli for (i = 0; i < n; i++) exist->sorting[i] = update->sorting[i]; } + */ if (update->accounting != exist->accounting) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update accounting: %d -> %d\n", update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; + exist->has_accounting = 1; } if (!exist->scheduler_name || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { LOG_I(FLEXRAN_AGENT, "[UL slice %d] update scheduler: %s -> %s\n", update->id, exist->scheduler_name, update->scheduler_name); - /* TODO dangerous? */ - exist->scheduler_name = update->scheduler_name; + if (exist->scheduler_name) free(exist->scheduler_name); + exist->scheduler_name = strdup(update->scheduler_name); } } @@ -1181,16 +1221,16 @@ void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s, Protocol__FlexDlSlice } if (s->n_sorting == 0) { s->n_sorting = from ? from->n_sorting : sc_update[mod_id]->dl[0]->n_sorting; - /* TODO Dangerous? */ - s->sorting = from ? from->sorting : sc_update[mod_id]->dl[0]->sorting; + s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexDlSorting)); + if (!s->sorting) s->n_sorting = 0; + for (int i = 0; i < s->n_sorting; ++i) + s->sorting[i] = from ? from->sorting[i] : sc_update[0]->dl[0]->sorting[i]; } if (!s->has_accounting) { - /* TODO Dangerous? */ s->accounting = from ? from->accounting : sc_update[mod_id]->dl[0]->accounting; } if (!s->scheduler_name) { - /* TODO Dangerous? */ - s->scheduler_name = from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name; + s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name); } } @@ -1248,16 +1288,16 @@ void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s, Protocol__FlexUlSlice } if (s->n_sorting == 0) { s->n_sorting = from ? from->n_sorting : sc_update[0]->ul[0]->n_sorting; - /* TODO Dangerous? */ - s->sorting = from ? from->sorting : sc_update[0]->ul[0]->sorting; + s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexUlSorting)); + if (!s->sorting) s->n_sorting = 0; + for (int i = 0; i < s->n_sorting; ++i) + s->sorting[i] = from ? from->sorting[i] : sc_update[0]->ul[0]->sorting[i]; } if (!s->has_accounting) { - /* TODO Dangerous? */ s->accounting = from ? from->accounting : sc_update[0]->ul[0]->accounting; } if (!s->scheduler_name) { - /* TODO Dangerous? */ - s->scheduler_name = from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name; + s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name); } } @@ -1374,7 +1414,6 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco * later when reading the configuration. There is thus a direct feedback * whether it has been set. */ int changes = 0; - int n; int slice_idx = flexran_find_dl_slice(mod_id, newc->id); if (slice_idx < 0) { LOG_W(FLEXRAN_AGENT, "cannot find index for slice ID %d\n", newc->id); @@ -1404,13 +1443,9 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco flexran_set_dl_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); changes++; } - n = min(oldc->n_sorting, newc->n_sorting); - for (int i = 0; i < n; i++) { - if (oldc->sorting[i] != newc->sorting[i]) { - flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, n); - changes++; - break; - } + if (check_dl_sorting_update(oldc, newc)) { + flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, newc->n_sorting); + changes++; } if (oldc->accounting != newc->accounting) { flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); @@ -1418,7 +1453,9 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco } if (!oldc->scheduler_name || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + int ret = flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", + newc->id, slice_idx); changes++; } return changes; @@ -1430,7 +1467,6 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco * later when reading the configuration. There is thus a direct feedback * whether it has been set. */ int changes = 0; - int n; int slice_idx = flexran_find_ul_slice(mod_id, newc->id); if (slice_idx < 0) { LOG_W(FLEXRAN_AGENT, "cannot find index for slice ID %d\n", newc->id); @@ -1466,15 +1502,11 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); changes++; } - n = min(oldc->n_sorting, newc->n_sorting); - for (int i = 0; i < n; i++) { - if (oldc->sorting[i] != newc->sorting[i]) { - /*flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); - changes++;*/ - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", - mod_id, slice_idx); - break; - } + if (check_ul_sorting_update(oldc, newc)) { + /*flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); + changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", + mod_id, slice_idx); } if (oldc->accounting != newc->accounting) { /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting); @@ -1484,7 +1516,9 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco } if (!oldc->scheduler_name || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + int ret = flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", + newc->id, slice_idx); changes++; } return changes; From 472ebf5622be595408a55a46b7619f474a68d13a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 21 May 2018 13:33:31 +0200 Subject: [PATCH 51/99] mark UL slice sorting overwriting as TODO --- .../CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c index 5dcc355612..c78b92e1af 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -178,6 +178,7 @@ int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice max mcs (%d)\n", mod_id, uls->maxmcs); return 0; } + /* TODO if (uls->n_sorting == 0) { LOG_E(FLEXRAN_AGENT, "[%d] no sorting in UL slice\n", mod_id); return 0; @@ -186,6 +187,7 @@ int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) LOG_E(FLEXRAN_AGENT, "[%d] no sorting found in UL slice\n", mod_id); return 0; } + */ /* sorting is an enum */ /* accounting is an enum */ if (!uls->scheduler_name) { From 44481a564980c22708101398567dcc0516964eed Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 20 May 2018 17:36:13 +0200 Subject: [PATCH 52/99] FlexRAN: improve info messages --- .../MAC/flexran_agent_mac_internal.c | 102 +++++++++--------- .../flexran_agent_mac_slice_verification.c | 67 ++++++++---- 2 files changed, 95 insertions(+), 74 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index c85f410313..1289e7551f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1042,52 +1042,52 @@ int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *n return sorting_update; } -void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) +void overwrite_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) { if (update->label != exist->label) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update label: %d -> %d\n", - update->id, exist->label, update->label); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update label: %d -> %d\n", + mod_id, update->id, exist->label, update->label); exist->label = update->label; exist->has_label = 1; } if (update->percentage != exist->percentage) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update percentage: %d -> %d\n", - update->id, exist->percentage, update->percentage); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update percentage: %d -> %d\n", + mod_id, update->id, exist->percentage, update->percentage); exist->percentage = update->percentage; exist->has_percentage = 1; } if (update->isolation != exist->isolation) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update isolation: %d -> %d\n", - update->id, exist->isolation, update->isolation); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update isolation: %d -> %d\n", + mod_id, update->id, exist->isolation, update->isolation); exist->isolation = update->isolation; exist->has_isolation = 1; } if (update->priority != exist->priority) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update priority: %d -> %d\n", - update->id, exist->priority, update->priority); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update priority: %d -> %d\n", + mod_id, update->id, exist->priority, update->priority); exist->priority = update->priority; exist->has_priority = 1; } if (update->position_low != exist->position_low) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_low: %d -> %d\n", - update->id, exist->position_low, update->position_low); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_low: %d -> %d\n", + mod_id, update->id, exist->position_low, update->position_low); exist->position_low = update->position_low; exist->has_position_low = 1; } if (update->position_high != exist->position_high) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update position_high: %d -> %d\n", - update->id, exist->position_high, update->position_high); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_high: %d -> %d\n", + mod_id, update->id, exist->position_high, update->position_high); exist->position_high = update->position_high; exist->has_position_high = 1; } if (update->maxmcs != exist->maxmcs) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update maxmcs: %d -> %d\n", - update->id, exist->maxmcs, update->maxmcs); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update maxmcs: %d -> %d\n", + mod_id, update->id, exist->maxmcs, update->maxmcs); exist->maxmcs = update->maxmcs; exist->has_maxmcs = 1; } if (check_dl_sorting_update(exist, update)) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update sorting array\n", update->id); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update sorting array\n", mod_id, update->id); if (exist->n_sorting != update->n_sorting) { exist->n_sorting = update->n_sorting; exist->sorting = realloc(exist->sorting, exist->n_sorting * sizeof(Protocol__FlexDlSorting)); @@ -1097,60 +1097,60 @@ void overwrite_slice_config_dl(Protocol__FlexDlSlice *exist, Protocol__FlexDlSli exist->sorting[i] = update->sorting[i]; } if (update->accounting != exist->accounting) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update accounting: %d -> %d\n", - update->id, exist->accounting, update->accounting); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update accounting: %d -> %d\n", + mod_id, update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; exist->has_accounting = 1; } if (!exist->scheduler_name || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_I(FLEXRAN_AGENT, "[DL slice %d] update scheduler: %s -> %s\n", - update->id, exist->scheduler_name, update->scheduler_name); + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update scheduler: %s -> %s\n", + mod_id, update->id, exist->scheduler_name, update->scheduler_name); if (exist->scheduler_name) free(exist->scheduler_name); exist->scheduler_name = strdup(update->scheduler_name); } } -void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update) +void overwrite_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update) { if (update->label != exist->label) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update label: %d -> %d\n", - update->id, exist->label, update->label); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update label: %d -> %d\n", + mod_id, update->id, exist->label, update->label); exist->label = update->label; exist->has_label = 1; } if (update->percentage != exist->percentage) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update percentage: %d -> %d\n", - update->id, exist->percentage, update->percentage); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update percentage: %d -> %d\n", + mod_id, update->id, exist->percentage, update->percentage); exist->percentage = update->percentage; exist->has_percentage = 1; } if (update->isolation != exist->isolation) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update isolation: %d -> %d\n", - update->id, exist->isolation, update->isolation); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update isolation: %d -> %d\n", + mod_id, update->id, exist->isolation, update->isolation); exist->isolation = update->isolation; exist->has_isolation = 1; } if (update->priority != exist->priority) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update priority: %d -> %d\n", - update->id, exist->priority, update->priority); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update priority: %d -> %d\n", + mod_id, update->id, exist->priority, update->priority); exist->priority = update->priority; exist->has_priority = 1; } if (update->first_rb != exist->first_rb) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update first_rb: %d -> %d\n", - update->id, exist->first_rb, update->first_rb); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update first_rb: %d -> %d\n", + mod_id, update->id, exist->first_rb, update->first_rb); exist->first_rb = update ->first_rb; exist->has_first_rb = 1; } /*if (update->lenght_rb != exist->lenght_rb) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update lenght_rb: %d -> %d\n", - update->id, exist->lenght_rb, update->lenght_rb); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update lenght_rb: %d -> %d\n", + mod_id, update->id, exist->lenght_rb, update->lenght_rb); exist->lenght_rb = update->lenght_rb; }*/ if (update->maxmcs != exist->maxmcs) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update maxmcs: %d -> %d\n", - update->id, exist->maxmcs, update->maxmcs); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update maxmcs: %d -> %d\n", + mod_id, update->id, exist->maxmcs, update->maxmcs); exist->maxmcs = update->maxmcs; exist->has_maxmcs = 1; } @@ -1163,24 +1163,24 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli i++; } if (sorting_update) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update sorting array\n", update->id); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update sorting array\n", update->id, mod_id); if (exist->n_sorting != update->n_sorting) - LOG_W(FLEXRAN_AGENT, "[UL slice %d] only writing %d elements\n", - update->id, n); + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] only writing %d elements\n", + mod_id, update->id, n); for (i = 0; i < n; i++) exist->sorting[i] = update->sorting[i]; } */ if (update->accounting != exist->accounting) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update accounting: %d -> %d\n", - update->id, exist->accounting, update->accounting); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update accounting: %d -> %d\n", + mod_id, update->id, exist->accounting, update->accounting); exist->accounting = update->accounting; exist->has_accounting = 1; } if (!exist->scheduler_name || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_I(FLEXRAN_AGENT, "[UL slice %d] update scheduler: %s -> %s\n", - update->id, exist->scheduler_name, update->scheduler_name); + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update scheduler: %s -> %s\n", + mod_id, update->id, exist->scheduler_name, update->scheduler_name); if (exist->scheduler_name) free(exist->scheduler_name); exist->scheduler_name = strdup(update->scheduler_name); } @@ -1361,7 +1361,7 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) * create new one and overwrite with the update */ Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id); - overwrite_slice_config_dl(dls, sup->dl[i]); + overwrite_slice_config_dl(mod_id, dls, sup->dl[i]); } } else { LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id); @@ -1397,7 +1397,7 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) * create new one and overwrite with the update */ Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id); - overwrite_slice_config_ul(uls, sup->ul[i]); + overwrite_slice_config_ul(mod_id, uls, sup->ul[i]); } } else { LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id); @@ -1416,7 +1416,7 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco int changes = 0; int slice_idx = flexran_find_dl_slice(mod_id, newc->id); if (slice_idx < 0) { - LOG_W(FLEXRAN_AGENT, "cannot find index for slice ID %d\n", newc->id); + LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); return 0; } if (oldc->percentage != newc->percentage) { @@ -1469,7 +1469,7 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco int changes = 0; int slice_idx = flexran_find_ul_slice(mod_id, newc->id); if (slice_idx < 0) { - LOG_W(FLEXRAN_AGENT, "cannot find index for slice ID %d\n", newc->id); + LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); return 0; } if (oldc->percentage != newc->percentage) { @@ -1480,13 +1480,13 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco /*flexran_set_ul_slice_isolation(mod_id, slice_idx, newc->isolation); *changes++;*/ LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting isolation is not supported\n", - mod_id, slice_idx); + mod_id, newc->id); } if (oldc->priority != newc->priority) { /*flexran_set_ul_slice_priority(mod_id, slice_idx, newc->priority); *changes++;*/ LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the priority is not supported\n", - mod_id, slice_idx); + mod_id, newc->id); } if (oldc->first_rb != newc->first_rb) { flexran_set_ul_slice_first_rb(mod_id, slice_idx, newc->first_rb); @@ -1496,7 +1496,7 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco flexran_set_ul_slice_length_rb(mod_id, slice_idx, newc->length_rb); changes++; LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting length_rb is not supported\n", - mod_id, slice_idx); + mod_id, newc->id); }*/ if (oldc->maxmcs != newc->maxmcs) { flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); @@ -1506,13 +1506,13 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco /*flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); changes++;*/ LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", - mod_id, slice_idx); + mod_id, newc->id); } if (oldc->accounting != newc->accounting) { /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting); *changes++;*/ LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", - mod_id, slice_idx); + mod_id, newc->id); } if (!oldc->scheduler_name || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c index c78b92e1af..67329e91be 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -57,40 +57,48 @@ int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls) /* verify parameters individualy */ /* label is enum */ if (!flexran_dl_slice_verify_pct(dls->percentage)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice percentage (%d)\n", mod_id, dls->percentage); + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice percentage (%d)\n", + mod_id, dls->id, dls->percentage); return 0; } /* isolation is a protobuf bool */ if (!flexran_dl_slice_verify_priority(dls->priority)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice priority (%d)\n", mod_id, dls->priority); + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice priority (%d)\n", + mod_id, dls->id, dls->priority); return 0; } if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice position low (%d) and/or high (%d)\n", - mod_id, dls->position_low, dls->position_high); + LOG_E(FLEXRAN_AGENT, + "[%d][DL slice %d] illegal DL slice position low (%d) and/or high (%d)\n", + mod_id, dls->id, dls->position_low, dls->position_high); return 0; } if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice max mcs %d\n", mod_id, dls->maxmcs); + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice max mcs %d\n", + mod_id, dls->id, dls->maxmcs); return 0; } if (dls->n_sorting == 0) { - LOG_E(FLEXRAN_AGENT, "[%d] no sorting in DL slice", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting in DL slice\n", + mod_id, dls->id); return 0; } if (!dls->sorting) { - LOG_E(FLEXRAN_AGENT, "[%d] no sorting found in DL slice\n", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting found in DL slice\n", + mod_id, dls->id); return 0; } /* sorting is an enum */ /* accounting is an enum */ if (!dls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d] no scheduler name found\n", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no scheduler name found\n", + mod_id, dls->id); return 0; } if (strcmp(dls->scheduler_name, "schedule_ue_spec") != 0) { - LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler to something different " - "than schedule_ue_spec is currently not allowed\n", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the scheduler to something " + "different than schedule_ue_spec is currently not allowed\n", + mod_id, dls->id); return 0; } @@ -125,7 +133,8 @@ int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existin } if (n < 1 || n > MAX_NUM_SLICES) { - LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting slices (%d -> %d)\n", mod_id, n_ex, n); + LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n", + mod_id, n_ex, n); return 0; } @@ -144,7 +153,9 @@ int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existin pct += update[i]->percentage; } if (pct < 1 || pct > 100) { - LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", mod_id, pct_orig, pct); + LOG_E(FLEXRAN_AGENT, + "[%d] invalid total RB share for DL slices (%d%% -> %d%%)\n", + mod_id, pct_orig, pct); return 0; } @@ -162,41 +173,49 @@ int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) /* verify parameters individually */ /* label is enum */ if (!flexran_ul_slice_verify_pct(uls->percentage)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice percentage (%d)\n", mod_id, uls->percentage); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", + mod_id, uls->id, uls->percentage); return 0; } /* isolation is a protobuf bool */ if (!flexran_ul_slice_verify_priority(uls->priority)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice percentage (%d)\n", mod_id, uls->priority); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", + mod_id, uls->id, uls->priority); return 0; } if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice first RB (%d)\n", mod_id, uls->first_rb); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice first RB (%d)\n", + mod_id, uls->id, uls->first_rb); return 0; } if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) { - LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice max mcs (%d)\n", mod_id, uls->maxmcs); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice max mcs (%d)\n", + mod_id, uls->id, uls->maxmcs); return 0; } /* TODO if (uls->n_sorting == 0) { - LOG_E(FLEXRAN_AGENT, "[%d] no sorting in UL slice\n", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting in UL slice\n", + mod_id, uls->id); return 0; } if (!uls->sorting) { - LOG_E(FLEXRAN_AGENT, "[%d] no sorting found in UL slice\n", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting found in UL slice\n", + mod_id, uls->id); return 0; } */ /* sorting is an enum */ /* accounting is an enum */ if (!uls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d] no scheduler name found\n", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no scheduler name found\n", + mod_id, uls->id); return 0; } if (strcmp(uls->scheduler_name, "schedule_ulsch_rnti") != 0) { - LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler to something different " - "than schedule_ulsch_rnti is currently not allowed\n", mod_id); + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the scheduler to something " + "different than schedule_ulsch_rnti is currently not allowed\n", + mod_id, uls->id); return 0; } @@ -235,7 +254,8 @@ int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existin } if (n < 1 || n > MAX_NUM_SLICES) { - LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting slices (%d -> %d)\n", mod_id, n_ex, n); + LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n", + mod_id, n_ex, n); return 0; } @@ -254,7 +274,8 @@ int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existin pct += update[i]->percentage; } if (pct < 1 || pct > 100) { - LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", mod_id, pct_orig, pct); + LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", + mod_id, pct_orig, pct); return 0; } From 7a0c00330b2b134f32bf3b1f335a55d189faf729 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 21 May 2018 14:34:37 +0200 Subject: [PATCH 53/99] put intra-/inter slice sharing within slice config --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 3 ++ .../MAC/flexran_agent_mac_internal.c | 48 +++++++++++++++++++ .../MAC/flexran_agent_mac_internal.h | 8 ++++ .../ENB_APP/MESSAGES/V2/config_messages.proto | 12 ++--- 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 1daf0d5183..273cb66567 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1393,6 +1393,8 @@ void flexran_create_config_structures(mid_t mod_id) sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); if (!slice_config[mod_id] || !sc_update[mod_id]) return; + flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); + flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); for (i = 0; i < n_dl; i++) { flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); @@ -1526,6 +1528,7 @@ void flexran_agent_slice_update(mid_t mod_id) sc_update[mod_id]->ul[i]); flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); } + flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); if (n_ue_slice_assoc_updates > 0) { changes += apply_ue_slice_assoc_update(mod_id); } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 1289e7551f..1c2aef3baa 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -939,6 +939,14 @@ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) return fsc; } +void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s) +{ + s->intraslice_share_active = flexran_get_intraslice_sharing_active(mod_id); + s->has_intraslice_share_active = 1; + s->interslice_share_active = flexran_get_interslice_sharing_active(mod_id); + s->has_interslice_share_active = 1; +} + void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice) { dl_slice->id = flexran_get_dl_slice_id(mod_id, slice_idx); @@ -1042,6 +1050,24 @@ int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *n return sorting_update; } +void overwrite_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *exist, Protocol__FlexSliceConfig *update) +{ + if (update->has_intraslice_share_active + && exist->intraslice_share_active != update->intraslice_share_active) { + LOG_I(FLEXRAN_AGENT, "[%d] update intraslice_share_active: %d -> %d\n", + mod_id, exist->intraslice_share_active, update->intraslice_share_active); + exist->intraslice_share_active = update->intraslice_share_active; + exist->has_intraslice_share_active = 1; + } + if (update->has_interslice_share_active + && exist->interslice_share_active != update->interslice_share_active) { + LOG_I(FLEXRAN_AGENT, "[%d] update interslice_share_active: %d -> %d\n", + mod_id, exist->interslice_share_active, update->interslice_share_active); + exist->interslice_share_active = update->interslice_share_active; + exist->has_interslice_share_active = 1; + } +} + void overwrite_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) { if (update->label != exist->label) { @@ -1333,6 +1359,11 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) } pthread_mutex_lock(&sc_update_mtx); + /* no need for tests in the current state as there are only two protobuf + * bools for intra-/interslice sharing. The function applies new values if + * applicable */ + overwrite_slice_config(mod_id, sc_update[mod_id], sup); + if (sup->n_dl == 0) { LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); } else { @@ -1408,6 +1439,23 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) perform_slice_config_update_count = 1; } +int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news) +{ + /* not setting the old configuration is intentional, as it will be picked up + * later when reading the configuration. There is thus a direct feedback + * whether it has been set. */ + int changes = 0; + if (olds->intraslice_share_active != news->intraslice_share_active) { + flexran_set_intraslice_sharing_active(mod_id, news->intraslice_share_active); + changes++; + } + if (olds->interslice_share_active != news->interslice_share_active) { + flexran_set_interslice_sharing_active(mod_id, news->interslice_share_active); + changes++; + } + return changes; +} + int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc) { /* not setting the old configuration is intentional, as it will be picked up diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index 2f8f3f8258..01fc51f6a6 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -113,6 +113,10 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name); * configs and m_ul UL slice configs */ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul); +/* read the general slice parameters via RAN into the given + * Protocol__FlexSliceConfig struct */ +void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s); + /* read the DL slice config via the RAN into a given Protocol__FlexDlSlice * struct */ void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice); @@ -125,6 +129,10 @@ void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__F * applied later by performing a diff between slice_config and sc_update */ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice); +/* apply generic slice parameters (e.g. intra-/interslice sharing activated or + * not) if there are changes. Returns the number of changed parameters. */ +int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news); + /* apply new configuration of slice in DL if there are changes between the * parameters. Returns the number of changed parameters. */ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc); diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index b186193b8c..0dd5140efa 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -44,16 +44,16 @@ message flex_cell_config { optional int32 dl_pdsch_power = 38; // operating downlink power optional int32 ul_pusch_power = 39; // operating uplink power - // whether remaining RBs after first intra-slice allocation will - // be allocated to UEs of the same slice - optional bool intraslice_share_active = 40; - // whether remaining RBs after slice allocation will be allocated - // to UEs of another slice. Isolated slices will be ignored. - optional bool interslice_share_active = 41; optional flex_slice_config slice_config = 42; } message flex_slice_config { + // whether remaining RBs after first intra-slice allocation will + // be allocated to UEs of the same slice + optional bool intraslice_share_active = 4; + // whether remaining RBs after slice allocation will be allocated + // to UEs of another slice. Isolated slices will be ignored. + optional bool interslice_share_active = 3; repeated flex_dl_slice dl = 1; repeated flex_ul_slice ul = 2; } From ef0d86564c205262b077e9d5b9d9ea8eb003e18c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 21 May 2018 12:26:48 +0200 Subject: [PATCH 54/99] when sending config report, copy slice config to new mem --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 70 ++++++++++++++++++- openair2/ENB_APP/flexran_agent_common.c | 19 ++++- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 273cb66567..7a61bad6d3 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1540,5 +1540,73 @@ void flexran_agent_slice_update(mid_t mod_id) Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) { - return slice_config[mod_id]; + if (!slice_config[mod_id]) return NULL; + Protocol__FlexSliceConfig *config = NULL; + + pthread_mutex_lock(&sc_update_mtx); + config = flexran_agent_create_slice_config(slice_config[mod_id]->n_dl, + slice_config[mod_id]->n_ul); + if (!config) { + pthread_mutex_unlock(&sc_update_mtx); + return NULL; + } + config->has_intraslice_share_active = 1; + config->intraslice_share_active = slice_config[mod_id]->intraslice_share_active; + config->has_interslice_share_active = 1; + config->interslice_share_active = slice_config[mod_id]->interslice_share_active; + for (int i = 0; i < slice_config[mod_id]->n_dl; ++i) { + if (!config->dl[i]) continue; + config->dl[i]->has_id = 1; + config->dl[i]->id = slice_config[mod_id]->dl[i]->id; + config->dl[i]->has_label = 1; + config->dl[i]->label = slice_config[mod_id]->dl[i]->label; + config->dl[i]->has_percentage = 1; + config->dl[i]->percentage = slice_config[mod_id]->dl[i]->percentage; + config->dl[i]->has_isolation = 1; + config->dl[i]->isolation = slice_config[mod_id]->dl[i]->isolation; + config->dl[i]->has_priority = 1; + config->dl[i]->priority = slice_config[mod_id]->dl[i]->priority; + config->dl[i]->has_position_low = 1; + config->dl[i]->position_low = slice_config[mod_id]->dl[i]->position_low; + config->dl[i]->has_position_high = 1; + config->dl[i]->position_high = slice_config[mod_id]->dl[i]->position_high; + config->dl[i]->has_maxmcs = 1; + config->dl[i]->maxmcs = slice_config[mod_id]->dl[i]->maxmcs; + config->dl[i]->n_sorting = slice_config[mod_id]->dl[i]->n_sorting; + config->dl[i]->sorting = calloc(config->dl[i]->n_sorting, sizeof(Protocol__FlexDlSorting)); + if (!config->dl[i]->sorting) config->dl[i]->n_sorting = 0; + for (int j = 0; j < config->dl[i]->n_sorting; ++j) + config->dl[i]->sorting[j] = slice_config[mod_id]->dl[i]->sorting[j]; + config->dl[i]->has_accounting = 1; + config->dl[i]->accounting = slice_config[mod_id]->dl[i]->accounting; + config->dl[i]->scheduler_name = strdup(slice_config[mod_id]->dl[i]->scheduler_name); + } + for (int i = 0; i < slice_config[mod_id]->n_ul; ++i) { + if (!config->ul[i]) continue; + config->ul[i]->has_id = 1; + config->ul[i]->id = slice_config[mod_id]->ul[i]->id; + config->ul[i]->has_label = 1; + config->ul[i]->label = slice_config[mod_id]->ul[i]->label; + config->ul[i]->has_percentage = 1; + config->ul[i]->percentage = slice_config[mod_id]->ul[i]->percentage; + config->ul[i]->has_isolation = 1; + config->ul[i]->isolation = slice_config[mod_id]->ul[i]->isolation; + config->ul[i]->has_priority = 1; + config->ul[i]->priority = slice_config[mod_id]->ul[i]->priority; + config->ul[i]->has_first_rb = 1; + config->ul[i]->first_rb = slice_config[mod_id]->ul[i]->first_rb; + config->ul[i]->has_maxmcs = 1; + config->ul[i]->maxmcs = slice_config[mod_id]->ul[i]->maxmcs; + config->ul[i]->n_sorting = slice_config[mod_id]->ul[i]->n_sorting; + config->ul[i]->sorting = calloc(config->ul[i]->n_sorting, sizeof(Protocol__FlexUlSorting)); + if (!config->ul[i]->sorting) config->ul[i]->n_sorting = 0; + for (int j = 0; j < config->ul[i]->n_sorting; ++j) + config->ul[i]->sorting[j] = slice_config[mod_id]->ul[i]->sorting[j]; + config->ul[i]->has_accounting = 1; + config->ul[i]->accounting = slice_config[mod_id]->ul[i]->accounting; + config->ul[i]->scheduler_name = strdup(slice_config[mod_id]->ul[i]->scheduler_name); + } + + pthread_mutex_unlock(&sc_update_mtx); + return config; } diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index d08517edea..b6a7fa26cd 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -288,11 +288,26 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { free(reply->cell_config[i]->si_config->si_message); free(reply->cell_config[i]->si_config); } + if (reply->cell_config[i]->slice_config != NULL) { + for (j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) { + if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0) + free(reply->cell_config[i]->slice_config->dl[j]->sorting); + free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name); + free(reply->cell_config[i]->slice_config->dl[j]); + } + free(reply->cell_config[i]->slice_config->dl); + for (j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) { + if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0) + free(reply->cell_config[i]->slice_config->ul[j]->sorting); + free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name); + free(reply->cell_config[i]->slice_config->ul[j]); + } + free(reply->cell_config[i]->slice_config->ul); + free(reply->cell_config[i]->slice_config); + } free(reply->cell_config[i]); } free(reply->cell_config); - /* don't free the slice_config, it is maintained internally during - * the liftetime of the agent */ free(reply); free(msg); From 0846460753b1bed8ff42d16f554b40e7f81d5ccd Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Apr 2018 12:39:34 +0200 Subject: [PATCH 55/99] show which task sends TERMINATE_MESSAGE to which task --- targets/RT/USER/lte-softmodem.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index a1130ce387..e747d38089 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -773,12 +773,13 @@ void wait_eNBs(void) { /* * helper function to terminate a certain ITTI task */ -void terminate_task(task_id_t task_id, module_id_t mod_id) +void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) { - LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + LOG_I(ENB_APP, "sending TERMINATE_MESSAGE from task %s (%d) to task %s (%d)\n", + itti_get_task_name(from), from, itti_get_task_name(to), to); MessageDef *msg; - msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); - itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); + msg = itti_alloc_new_message (from, TERMINATE_MESSAGE); + itti_send_msg_to_task (to, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } extern void free_transport(PHY_VARS_eNB *); @@ -814,8 +815,8 @@ int stop_L1L2(module_id_t enb_id) } /* these tasks need to pick up new configuration */ - terminate_task(TASK_RRC_ENB, enb_id); - terminate_task(TASK_L2L1, enb_id); + terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); + terminate_task(enb_id, TASK_ENB_APP, TASK_L2L1); LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); kill_eNB_proc(enb_id); LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); From 35b3a2af14ab8c5ec8b544fca11a46e9d0db593b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Apr 2018 13:30:44 +0200 Subject: [PATCH 56/99] Reorganize TASK_L2L1 loop --- targets/RT/USER/lte-softmodem.c | 52 +++++++++------------------------ 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index e747d38089..60b5a0b15f 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -449,46 +449,22 @@ void *l2l1_task(void *arg) { itti_set_task_real_time(TASK_L2L1); itti_mark_task_ready(TASK_L2L1); - /* Wait for the initialize message */ - printf("Wait for the ITTI initialize message\n"); - do { - if (message_p != NULL) { - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - - itti_receive_msg (TASK_L2L1, &message_p); - - switch (ITTI_MSG_ID(message_p)) { - case INITIALIZE_MESSAGE: - /* Start eNB thread */ - printf("L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); - start_eNB = 1; - break; - - case TERMINATE_MESSAGE: - printf("received terminate message\n"); - oai_exit=1; - start_eNB = 0; - itti_exit_task (); - break; - - default: - printf("Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - break; - } - } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE); - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); -/* ???? no else but seems to be UE only ??? - do { - // Wait for a message + /* Wait for the initialize message */ + printf("Wait for the ITTI initialize message\n"); + while (1) { itti_receive_msg (TASK_L2L1, &message_p); switch (ITTI_MSG_ID(message_p)) { + case INITIALIZE_MESSAGE: + /* Start eNB thread */ + LOG_D(PHY, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); + start_eNB = 1; + break; + case TERMINATE_MESSAGE: + LOG_W(PHY, " *** Exiting L2L1 thread\n"); oai_exit=1; + start_eNB = 0; itti_exit_task (); break; @@ -511,8 +487,9 @@ void *l2l1_task(void *arg) { result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } while(!oai_exit); -*/ + message_p = NULL; + }; + return NULL; } #endif @@ -788,7 +765,6 @@ extern void phy_free_RU(RU_t*); int stop_L1L2(module_id_t enb_id) { LOG_W(ENB_APP, "stopping lte-softmodem\n"); - oai_exit = 1; if (!RC.ru) { LOG_UI(ENB_APP, "no RU configured\n"); From c56b5af00e1e1d402d094d03db7011097e738ae7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Apr 2018 08:45:44 +0200 Subject: [PATCH 57/99] bugfix: kill td/te threads only if initialized * init_td_thread()/init_te_thread() are only initialized depending on condition get_nprocs() > 2 && codingw * apply the same the same for the functions kill_td_thread()/kill_te_thread() --- targets/RT/USER/lte-enb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index c8c35cf2e8..5dcb84d63c 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1031,8 +1031,10 @@ void kill_eNB_proc(int inst) { proc = &eNB->proc; proc_rxtx = &proc->proc_rxtx[0]; - kill_td_thread(eNB); - kill_te_thread(eNB); + if(get_nprocs() > 2 && codingw) { + kill_td_thread(eNB); + kill_te_thread(eNB); + } LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); for (i=0; i<2; i++) { pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx); From 2e1dfb5b3e422681f1ae8fe746e9b5943dbaf580 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Apr 2018 14:24:20 +0200 Subject: [PATCH 58/99] place oai_exit test after wait_on_condition() in threads --- targets/RT/USER/lte-enb.c | 4 ++-- targets/RT/USER/lte-ru.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 5dcb84d63c..61d689e182 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -783,10 +783,10 @@ static void* eNB_thread_prach( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; + if (oai_exit) break; LOG_D(PHY,"Running eNB prach procedures\n"); prach_procedures(eNB @@ -824,10 +824,10 @@ static void* eNB_thread_prach_br( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; + if (oai_exit) break; LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n"); prach_procedures(eNB,1); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 578b647d96..0a25dca360 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1080,8 +1080,8 @@ static void* ru_thread_prach( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; + if (oai_exit) break; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); if (ru->eNB_list[0]){ prach_procedures( @@ -1130,8 +1130,8 @@ static void* ru_thread_prach_br( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"ru_prach_thread_br") < 0) break; + if (oai_exit) break; rx_prach(NULL, ru, NULL, From f0670154b332af38b9cb7c25800fff245a422176 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Apr 2018 14:25:41 +0200 Subject: [PATCH 59/99] Correctly join RU threads * join pthread_FH (ru_thread) once all condition variables have been set * join RU FHTX only if it has been started (check as for pthread_create()) * join PRACH thread in the monolithic case * send broadcast on condition variable cond_eNBs, as there can be multiple waits on it * integrate stop_ru(*ru) into kill_RU_proc(*ru) * Correct memory freeing --- targets/RT/USER/lte-ru.c | 79 +++++++++++++++------------------ targets/RT/USER/lte-softmodem.c | 34 +++++++------- targets/RT/USER/lte-softmodem.h | 2 +- 3 files changed, 53 insertions(+), 62 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 0a25dca360..d20b614ad7 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2230,11 +2230,36 @@ void init_RU_proc(RU_t *ru) { } -void kill_RU_proc(int inst) +void kill_RU_proc(RU_t *ru) { - RU_t *ru = RC.ru[inst]; RU_proc_t *proc = &ru->proc; +#if defined(PRE_SCD_THREAD) + pthread_mutex_lock(&proc->mutex_pre_scd); + ru->proc.instance_pre_scd = 0; + pthread_cond_signal(&proc->cond_pre_scd); + pthread_mutex_unlock(&proc->mutex_pre_scd); + pthread_join(proc->pthread_pre_scd, NULL); + pthread_mutex_destroy(&proc->mutex_pre_scd); + pthread_cond_destroy(&proc->cond_pre_scd); +#endif +#ifdef PHY_TX_THREAD + pthread_mutex_lock(&proc->mutex_phy_tx); + proc->instance_cnt_phy_tx = 0; + pthread_cond_signal(&proc->cond_phy_tx); + pthread_mutex_unlock(&proc->mutex_phy_tx); + pthread_join(ru->proc.pthread_phy_tx, NULL); + pthread_mutex_destroy( &proc->mutex_phy_tx); + pthread_cond_destroy( &proc->cond_phy_tx); + pthread_mutex_lock(&proc->mutex_rf_tx); + proc->instance_cnt_rf_tx = 0; + pthread_cond_signal(&proc->cond_rf_tx); + pthread_mutex_unlock(&proc->mutex_rf_tx); + pthread_join(proc->pthread_rf_tx, NULL); + pthread_mutex_destroy( &proc->mutex_rf_tx); + pthread_cond_destroy( &proc->cond_rf_tx); +#endif + if (get_nprocs() > 2 && fepw) { LOG_D(PHY, "killing FEP thread\n"); kill_fep_thread(ru); @@ -2271,8 +2296,10 @@ void kill_RU_proc(int inst) pthread_mutex_lock(&proc->mutex_eNBs); proc->ru_tx_ready = 0; - proc->instance_cnt_eNBs = 0; - pthread_cond_signal(&proc->cond_eNBs); + proc->instance_cnt_eNBs = 1; + // cond_eNBs is used by both ru_thread and ru_thread_tx, so we need to send + // a broadcast to wake up both threads + pthread_cond_broadcast(&proc->cond_eNBs); pthread_mutex_unlock(&proc->mutex_eNBs); pthread_mutex_lock(&proc->mutex_asynch_rxtx); @@ -2280,10 +2307,12 @@ void kill_RU_proc(int inst) pthread_cond_signal(&proc->cond_asynch_rxtx); pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - /*LOG_D(PHY, "Joining pthread_FH\n"); + LOG_D(PHY, "Joining pthread_FH\n"); pthread_join(proc->pthread_FH, NULL); - LOG_D(PHY, "Joining pthread_FHTX\n"); - pthread_join(proc->pthread_FH1, NULL);*/ + if (!single_thread_flag && get_nprocs() > 4) { + LOG_D(PHY, "Joining pthread_FHTX\n"); + pthread_join(proc->pthread_FH1, NULL); + } if (ru->function == NGFI_RRU_IF4p5) { LOG_D(PHY, "Joining pthread_prach\n"); pthread_join(proc->pthread_prach, NULL); @@ -2755,45 +2784,11 @@ void init_RU(char *rf_config_file) { } - - - -void stop_ru(RU_t *ru) { - -#if defined(PRE_SCD_THREAD) || defined(PHY_TX_THREAD) - int *status; -#endif - printf("Stopping RU %p processing threads\n",(void*)ru); -#if defined(PRE_SCD_THREAD) - if(ru){ - ru->proc.instance_pre_scd = 0; - pthread_cond_signal( &ru->proc.cond_pre_scd ); - pthread_join(ru->proc.pthread_pre_scd, (void**)&status ); - pthread_mutex_destroy(&ru->proc.mutex_pre_scd ); - pthread_cond_destroy(&ru->proc.cond_pre_scd ); - } -#endif -#ifdef PHY_TX_THREAD - if(ru){ - ru->proc.instance_cnt_phy_tx = 0; - pthread_cond_signal(&ru->proc.cond_phy_tx); - pthread_join( ru->proc.pthread_phy_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_phy_tx ); - pthread_cond_destroy( &ru->proc.cond_phy_tx ); - ru->proc.instance_cnt_rf_tx = 0; - pthread_cond_signal(&ru->proc.cond_rf_tx); - pthread_join( ru->proc.pthread_rf_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_rf_tx ); - pthread_cond_destroy( &ru->proc.cond_rf_tx ); - } -#endif -} - void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { LOG_I(PHY, "Stopping RU %d processing threads\n", inst); - kill_RU_proc(inst); + kill_RU_proc(RC.ru[inst]); } } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 60b5a0b15f..25a55a6e56 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -793,10 +793,11 @@ int stop_L1L2(module_id_t enb_id) /* these tasks need to pick up new configuration */ terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); terminate_task(enb_id, TASK_ENB_APP, TASK_L2L1); + oai_exit = 1; LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); kill_eNB_proc(enb_id); LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); - kill_RU_proc(enb_id); + kill_RU_proc(RC.ru[enb_id]); oai_exit = 0; for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) { free_transport(RC.eNB[enb_id][cc_id]); @@ -1241,25 +1242,20 @@ int main( int argc, char **argv ) printf("stopping MODEM threads\n"); - // cleanup - for (ru_id=0;ru_id Date: Thu, 26 Apr 2018 17:17:56 +0200 Subject: [PATCH 60/99] cell reconfiguration/restart: take protobuf, perform in ENB_APP * instead of the lengthy YAML parsing, can now handle protobuf message * after setting the parameters, send a message to ENB_APP to perform it * old YAML way still works --- openair2/COMMON/flexran_messages_def.h | 29 +++++++ openair2/COMMON/messages_def.h | 2 +- openair2/ENB_APP/enb_app.c | 54 +++++++++++++ openair2/ENB_APP/enb_app.h | 4 +- openair2/ENB_APP/flexran_agent_common.c | 7 +- .../ENB_APP/flexran_agent_common_internal.c | 81 +++++++------------ .../ENB_APP/flexran_agent_common_internal.h | 4 + 7 files changed, 124 insertions(+), 57 deletions(-) create mode 100644 openair2/COMMON/flexran_messages_def.h diff --git a/openair2/COMMON/flexran_messages_def.h b/openair2/COMMON/flexran_messages_def.h new file mode 100644 index 0000000000..fdcdf698dc --- /dev/null +++ b/openair2/COMMON/flexran_messages_def.h @@ -0,0 +1,29 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + * flexran_messages_def.h + * + * Created on: Apr 26, 2018 + * Author: R. Schmidt + */ + +MESSAGE_DEF(SOFT_RESTART_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, IttiMsgEmpty, soft_restart_message) diff --git a/openair2/COMMON/messages_def.h b/openair2/COMMON/messages_def.h index 2434d15776..f6e2dd0f4b 100644 --- a/openair2/COMMON/messages_def.h +++ b/openair2/COMMON/messages_def.h @@ -38,4 +38,4 @@ #include "sctp_messages_def.h" #include "udp_messages_def.h" #include "gtpv1_u_messages_def.h" - +#include "flexran_messages_def.h" diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index f95fdd7e5a..89df62db7b 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -65,6 +65,8 @@ extern RAN_CONTEXT_t RC; # define ENB_REGISTER_RETRY_DELAY 10 # endif +#include "targets/RT/USER/lte-softmodem.h" + /*------------------------------------------------------------------------------*/ /* @@ -245,6 +247,10 @@ void *eNB_app_task(void *args_p) LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p)); break; + case SOFT_RESTART_MESSAGE: + handle_reconfiguration(instance); + break; + case S1AP_REGISTER_ENB_CNF: # if defined(ENABLE_USE_MME) LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), @@ -322,3 +328,51 @@ void *eNB_app_task(void *args_p) return NULL; } + +void handle_reconfiguration(module_id_t mod_id) +{ + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC, &start); + flexran_agent_info_t *flexran = RC.flexran[mod_id]; + + if (ENB_WAIT == flexran->node_ctrl_state) { + /* this is already waiting, just release */ + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_NORMAL_OPERATION; + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + pthread_cond_signal(&flexran->cond_node_ctrl); + return; + } + + if (stop_L1L2(mod_id) < 0) { + LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); + return; + } + + /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not + * executed by the FlexRAN thread */ + if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_WAIT; + while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) + pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + } + + if (restart_L1L2(mod_id) < 0) { + LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); + itti_terminate_tasks(TASK_PHY_ENB); + return; + } + + clock_gettime(CLOCK_MONOTONIC, &end); + end.tv_sec -= start.tv_sec; + if (end.tv_nsec >= start.tv_nsec) { + end.tv_nsec -= start.tv_nsec; + } else { + end.tv_sec -= 1; + end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; + } + LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); +} diff --git a/openair2/ENB_APP/enb_app.h b/openair2/ENB_APP/enb_app.h index 4dfea72eef..9eb5ea2400 100644 --- a/openair2/ENB_APP/enb_app.h +++ b/openair2/ENB_APP/enb_app.h @@ -31,11 +31,11 @@ #define ENB_APP_H_ #include +#include "platform_types.h" void *eNB_app_task(void *args_p); -/* needed for flexran: start PHY and RRC when restarting */ -void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end); +void handle_reconfiguration(module_id_t mod_id); #endif /* ENB_APP_H_ */ diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index b6a7fa26cd..7578dec03f 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1130,10 +1130,11 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (enb_config->n_cell_config > 1) LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n"); - if (enb_config->cell_config[0]->slice_config) + if (enb_config->cell_config[0]->slice_config) { prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); - - /* could test for cell configs here and maybe reconfigure/soft-restart */ + } else { + initiate_soft_restart(mod_id, enb_config->cell_config[0]); + } *msg = NULL; return 0; diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 8874a0f648..501e878d32 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -31,57 +31,7 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" - -/* needed to soft-restart the lte-softmodem */ -#include "targets/RT/USER/lte-softmodem.h" - -void handle_reconfiguration(mid_t mod_id) -{ - struct timespec start, end; - clock_gettime(CLOCK_MONOTONIC, &start); - flexran_agent_info_t *flexran = RC.flexran[mod_id]; - - if (ENB_WAIT == flexran->node_ctrl_state) { - /* this is already waiting, just release */ - pthread_mutex_lock(&flexran->mutex_node_ctrl); - flexran->node_ctrl_state = ENB_NORMAL_OPERATION; - pthread_mutex_unlock(&flexran->mutex_node_ctrl); - pthread_cond_signal(&flexran->cond_node_ctrl); - return; - } - - if (stop_L1L2(mod_id) < 0) { - LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); - return; - } - - /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not - * executed by the FlexRAN thread */ - if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { - LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); - pthread_mutex_lock(&flexran->mutex_node_ctrl); - flexran->node_ctrl_state = ENB_WAIT; - while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) - pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); - pthread_mutex_unlock(&flexran->mutex_node_ctrl); - } - - if (restart_L1L2(mod_id) < 0) { - LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); - itti_terminate_tasks(TASK_PHY_ENB); - return; - } - - clock_gettime(CLOCK_MONOTONIC, &end); - end.tv_sec -= start.tv_sec; - if (end.tv_nsec >= start.tv_nsec) { - end.tv_nsec -= start.tv_nsec; - } else { - end.tv_sec -= 1; - end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; - } - LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); -} +#include "enb_app.h" int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { @@ -589,3 +539,32 @@ int apply_parameter_modification(void *parameter, yaml_parser_t *parser) { return -1; } + +void initiate_soft_restart(module_id_t mod_id, Protocol__FlexCellConfig *c) +{ + uint8_t cc_id = c->has_cell_id ? c->cell_id : 0; + if (c->has_eutra_band) { + flexran_agent_set_operating_eutra_band(mod_id, cc_id, c->eutra_band); + LOG_I(ENB_APP, "Setting eutra_band to %d\n", c->eutra_band); + } + if (c->has_dl_freq && c->has_ul_freq) { + flexran_agent_set_operating_dl_freq(mod_id, cc_id, c->dl_freq); + LOG_I(ENB_APP, "Setting dl_freq to %d\n", c->dl_freq); + int32_t ul_freq_offset = c->ul_freq - c->dl_freq; + flexran_agent_set_operating_ul_freq(mod_id, cc_id, ul_freq_offset); + LOG_I(ENB_APP, "Setting ul_freq to %d\n", c->ul_freq); + } + if (c->has_dl_bandwidth) { + flexran_agent_set_operating_bandwidth(mod_id, cc_id, c->dl_bandwidth); + LOG_I(ENB_APP, "Setting bandwidth to %d\n", c->dl_bandwidth); + if (c->has_ul_bandwidth && c->ul_bandwidth != c->dl_bandwidth) + LOG_W(ENB_APP, "UL/DL bandwidth mismatch, applied DL bandwidth\n"); + } else if (c->has_ul_bandwidth) { + flexran_agent_set_operating_bandwidth(mod_id, cc_id, c->ul_bandwidth); + LOG_I(ENB_APP, "Setting bandwidth to %d\n", c->ul_bandwidth); + } + + MessageDef *msg; + msg = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SOFT_RESTART_MESSAGE); + itti_send_msg_to_task(ENB_APP, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); +} diff --git a/openair2/ENB_APP/flexran_agent_common_internal.h b/openair2/ENB_APP/flexran_agent_common_internal.h index bf908ac132..544321e228 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.h +++ b/openair2/ENB_APP/flexran_agent_common_internal.h @@ -32,6 +32,7 @@ #include #include "flexran_agent_defs.h" +#include "flexran.pb-c.h" int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length); @@ -57,4 +58,7 @@ int skip_subsystem_parameters_config(yaml_parser_t *parser); //that is not yet implmeneted in order to skip its configuration, without affecting the rest int skip_parameter_modification(yaml_parser_t *parser); +// applies reconfiguration parameters and notifies ENB APP +void initiate_soft_restart(mid_t mod_id, Protocol__FlexCellConfig *c); + #endif From 917b9ca0c2ab2a039ed839eabf990f5eabf42973 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 27 Apr 2018 12:16:09 +0200 Subject: [PATCH 61/99] correct ITTI task name --- openair2/ENB_APP/flexran_agent_common_internal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 501e878d32..9f1a1d3710 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -566,5 +566,5 @@ void initiate_soft_restart(module_id_t mod_id, Protocol__FlexCellConfig *c) MessageDef *msg; msg = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SOFT_RESTART_MESSAGE); - itti_send_msg_to_task(ENB_APP, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } From 175d28ee357a61f1f1a19d704b94d44e6f581799 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 3 May 2018 10:26:17 +0200 Subject: [PATCH 62/99] bugfixes kill_eNB_proc() * put mutex lock around instance_prach * destroy attributes --- targets/RT/USER/lte-enb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 61d689e182..87aa874227 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1043,8 +1043,10 @@ void kill_eNB_proc(int inst) { pthread_cond_signal(&proc_rxtx[i].cond_rxtx); pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx); } + pthread_mutex_lock(&proc->mutex_prach); proc->instance_cnt_prach = 0; pthread_cond_signal( &proc->cond_prach ); + pthread_mutex_unlock(&proc->mutex_prach); pthread_cond_signal( &proc->cond_asynch_rxtx ); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); @@ -1071,6 +1073,16 @@ void kill_eNB_proc(int inst) { pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); } + + pthread_attr_destroy(&proc->attr_prach); + pthread_attr_destroy(&proc->attr_asynch_rxtx); + pthread_attr_destroy(&proc_rxtx[0].attr_rxtx); + pthread_attr_destroy(&proc_rxtx[1].attr_rxtx); +#ifdef Rel14 + pthread_mutex_destroy(&proc->mutex_RU_PRACH_br); + pthread_attr_destroy(&proc->attr_prach_br); +#endif + } } From d24e17f0f7749b06a89eb50adacadadf1cf4bc67 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 3 May 2018 10:33:10 +0200 Subject: [PATCH 63/99] improve load_module_shlib() * check whether a library has been loaded before; in this case, don't allocate new memory but load from old library again * vital parameters, previous exit_fun are checked by AssertFatal() * structure has changed a bit to make it easier to follow (instead of nested ifs includes one goto to the end of the function) * formatting has been improved --- common/utils/load_module_shlib.c | 150 ++++++++++++++++++------------- 1 file changed, 87 insertions(+), 63 deletions(-) diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index c0afdb0b64..b9ce5954dd 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -120,75 +120,99 @@ int ret; int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg) { - void *lib_handle; - initfunc_t fpi; - checkverfunc_t fpc; - getfarrayfunc_t fpg; - char *shlib_path; - char *afname=NULL; - int ret=0; + void *lib_handle = NULL; + initfunc_t fpi; + checkverfunc_t fpc; + getfarrayfunc_t fpg; + char *shlib_path = NULL; + char *afname = NULL; + int ret = 0; + int lib_idx = -1; - if (loader_data.shlibpath == NULL) { - loader_init(); - } + AssertFatal(modname, "no library name given\n"); - shlib_path = loader_format_shlibpath(modname); + if (!loader_data.shlibpath) { + loader_init(); + } - ret = 0; - lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); - if (!lib_handle) { - fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); - ret = -1; - } else { - printf("[LOADER] library %s successfully loaded\n", shlib_path); - afname=malloc(strlen(modname)+15); - sprintf(afname,"%s_checkbuildver",modname); - fpc = dlsym(lib_handle,afname); - if (fpc != NULL ){ - int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); - if (chkver_ret < 0) { - fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); - exit_fun("[LOADER] unrecoverable error"); - } - } - sprintf(afname,"%s_autoinit",modname); - fpi = dlsym(lib_handle,afname); + shlib_path = loader_format_shlibpath(modname); - if (fpi != NULL ) { - fpi(autoinit_arg); - } + for (int i = 0; i < loader_data.numshlibs; i++) { + if (strcmp(loader_data.shlibs[i].name, modname) == 0) { + printf("[LOADER] library %s has been loaded previously, reloading function pointers\n", + shlib_path); + lib_idx = i; + break; + } + } + if (lib_idx < 0) { + lib_idx = loader_data.numshlibs; + ++loader_data.numshlibs; + AssertFatal(loader_data.numshlibs <= loader_data.maxshlibs, + "shared lib loader: can not load more than %d shlibs\n", + loader_data.maxshlibs); + loader_data.shlibs[lib_idx].name = strdup(modname); + loader_data.shlibs[lib_idx].thisshlib_path = strdup(shlib_path); + } - if (farray != NULL) { - loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t)); - loader_data.shlibs[loader_data.numshlibs].numfunc=0; - for (int i=0; i= 0, + "[LOADER] %s %d lib %s, version mismatch", + __FILE__, __LINE__, modname); + } + sprintf(afname,"%s_autoinit",modname); + fpi = dlsym(lib_handle,afname); + + if (fpi) { + fpi(autoinit_arg); + } + + if (farray) { + if (!loader_data.shlibs[lib_idx].funcarray) { + loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t)); + AssertFatal(loader_data.shlibs[lib_idx].funcarray, "unable to allocate memory\n"); + } + loader_data.shlibs[lib_idx].numfunc = 0; + for (int i = 0; i < numf; i++) { + farray[i].fptr = dlsym(lib_handle,farray[i].fname); + AssertFatal(farray[i].fptr, "%s: function not found %s\n", + dlerror(), farray[i].fname); + loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname); + loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr; + loader_data.shlibs[lib_idx].numfunc++; + } /* for int i... */ + } else { /* farray ! NULL */ + sprintf(afname,"%s_getfarray",modname); + fpg = dlsym(lib_handle,afname); + if (fpg) { + loader_data.shlibs[lib_idx].numfunc = + fpg(&(loader_data.shlibs[lib_idx].funcarray)); + } + } /* farray ! NULL */ + +load_module_shlib_exit: + if (shlib_path) free(shlib_path); + if (afname) free(afname); + if (lib_handle) dlclose(lib_handle); + return ret; } void * get_shlibmodule_fptr(char *modname, char *fname) From 604ec25a684756c033e0463b7ca73ad89873b753 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 3 May 2018 10:35:13 +0200 Subject: [PATCH 64/99] improve soft-restarting messages --- openair2/ENB_APP/enb_app.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 89df62db7b..1289cf59b5 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -335,6 +335,8 @@ void handle_reconfiguration(module_id_t mod_id) clock_gettime(CLOCK_MONOTONIC, &start); flexran_agent_info_t *flexran = RC.flexran[mod_id]; + LOG_N(ENB_APP, "lte-softmodem soft-restart requested\n"); + if (ENB_WAIT == flexran->node_ctrl_state) { /* this is already waiting, just release */ pthread_mutex_lock(&flexran->mutex_node_ctrl); @@ -352,7 +354,7 @@ void handle_reconfiguration(module_id_t mod_id) /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not * executed by the FlexRAN thread */ if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { - LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + LOG_N(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); pthread_mutex_lock(&flexran->mutex_node_ctrl); flexran->node_ctrl_state = ENB_WAIT; while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) @@ -361,7 +363,7 @@ void handle_reconfiguration(module_id_t mod_id) } if (restart_L1L2(mod_id) < 0) { - LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); + LOG_E(ENB_APP, "can not restart, killing lte-softmodem\n"); itti_terminate_tasks(TASK_PHY_ENB); return; } @@ -374,5 +376,5 @@ void handle_reconfiguration(module_id_t mod_id) end.tv_sec -= 1; end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; } - LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); + LOG_N(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); } From 1e9f3235d37058f42d00a40f72fa2b18e237f7c6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 4 May 2018 09:55:55 +0200 Subject: [PATCH 65/99] fix: avoid AssertFatal() in load_module_shlib() don't fail in library utility function, return with error code instead and let application decide what is best on how to proceed --- common/utils/load_module_shlib.c | 37 +++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index b9ce5954dd..a4b4742c94 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -129,7 +129,10 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void * int ret = 0; int lib_idx = -1; - AssertFatal(modname, "no library name given\n"); + if (!modname) { + fprintf(stderr, "[LOADER] load_module_shlib(): no library name given\n"); + return -1; + } if (!loader_data.shlibpath) { loader_init(); @@ -148,9 +151,12 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void * if (lib_idx < 0) { lib_idx = loader_data.numshlibs; ++loader_data.numshlibs; - AssertFatal(loader_data.numshlibs <= loader_data.maxshlibs, - "shared lib loader: can not load more than %d shlibs\n", - loader_data.maxshlibs); + if (loader_data.numshlibs > loader_data.maxshlibs) { + fprintf(stderr, "[LOADER] can not load more than %d shlibs\n", + loader_data.maxshlibs); + ret = -1; + goto load_module_shlib_exit; + } loader_data.shlibs[lib_idx].name = strdup(modname); loader_data.shlibs[lib_idx].thisshlib_path = strdup(shlib_path); } @@ -174,9 +180,12 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void * if (fpc) { int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[lib_idx].shlib_buildversion)); - AssertFatal(chkver_ret >= 0, - "[LOADER] %s %d lib %s, version mismatch", - __FILE__, __LINE__, modname); + if (chkver_ret < 0) { + fprintf(stderr, "[LOADER] %s %d lib %s, version mismatch", + __FILE__, __LINE__, modname); + ret = -1; + goto load_module_shlib_exit; + } } sprintf(afname,"%s_autoinit",modname); fpi = dlsym(lib_handle,afname); @@ -188,13 +197,21 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void * if (farray) { if (!loader_data.shlibs[lib_idx].funcarray) { loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t)); - AssertFatal(loader_data.shlibs[lib_idx].funcarray, "unable to allocate memory\n"); + if (!loader_data.shlibs[lib_idx].funcarray) { + fprintf(stderr, "[LOADER] load_module_shlib(): unable to allocate memory\n"); + ret = -1; + goto load_module_shlib_exit; + } } loader_data.shlibs[lib_idx].numfunc = 0; for (int i = 0; i < numf; i++) { farray[i].fptr = dlsym(lib_handle,farray[i].fname); - AssertFatal(farray[i].fptr, "%s: function not found %s\n", - dlerror(), farray[i].fname); + if (!farray[i].fptr) { + fprintf(stderr, "[LOADER] load_module_shlib(): function %s not found: %s\n", + farray[i].fname, dlerror()); + ret = -1; + goto load_module_shlib_exit; + } loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname); loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr; loader_data.shlibs[lib_idx].numfunc++; From 62957b97d8d4303224ccd5a673d6c1f3c89253b7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 4 May 2018 15:53:19 +0200 Subject: [PATCH 66/99] bugfix FlexRAN: only write to file if file is not null --- openair2/ENB_APP/flexran_agent_common.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 7578dec03f..c55633af31 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -414,8 +414,14 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ FILE *f; f = fopen(target, "wb"); - fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); - fclose(f); + if (f) { + fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); + fclose(f); + } + else { + LOG_W(FLEXRAN_AGENT, "[%d] can not write control delegation data to %s\n", + mod_id, target); + } // long time_elapsed_nanos = timer_end(vartime); *msg = NULL; From da35afb01b1c27db8b876e16971e336eb2c0206e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 4 May 2018 16:12:09 +0200 Subject: [PATCH 67/99] fix: repair RC.mac memory allocation - there can be a race between the FlexRAN agent reading the RC.mac and its allocation in main.c - In order to circumvent this, change the allocation by allocating everything "into" a local variable - finally "make it visible" by storing the pointer in RC.mac --- openair2/LAYER2/MAC/main.c | 186 +++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 103 deletions(-) diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 8d3d88aaaa..b325c9b3ea 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -46,122 +46,102 @@ extern RAN_CONTEXT_t RC; - void mac_top_init_eNB(void) { + module_id_t i, j; + int list_el; + UE_list_t *UE_list; + slice_info_t *sli; + eNB_MAC_INST **mac; - module_id_t i, j; - int list_el; - UE_list_t *UE_list; - slice_info_t *sli; - eNB_MAC_INST *mac; + LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n", + RC.nb_macrlc_inst); - LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n", - RC.nb_macrlc_inst); + if (RC.nb_macrlc_inst <= 0) { + RC.mac = NULL; + return; + } - if (RC.nb_macrlc_inst > 0) { - if (RC.mac == NULL){ - RC.mac = - (eNB_MAC_INST **) malloc16(RC.nb_macrlc_inst * - sizeof(eNB_MAC_INST *)); - bzero(RC.mac, RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *)); - } - AssertFatal(RC.mac != NULL, - "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", - RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), - RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); - for (i = 0; i < RC.nb_macrlc_inst; i++) { - if (RC.mac[i] == NULL) { - RC.mac[i] = (eNB_MAC_INST *) malloc16(sizeof(eNB_MAC_INST)); - AssertFatal(RC.mac[i] != NULL, - "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", - RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), - RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); - LOG_D(MAC, - "[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n", - sizeof(eNB_MAC_INST), RC.nb_macrlc_inst, RC.mac); - bzero(RC.mac[i], sizeof(eNB_MAC_INST)); - } - RC.mac[i]->Mod_id = i; - for (j = 0; j < MAX_NUM_CCs; j++) { - RC.mac[i]->DL_req[j].dl_config_request_body. - dl_config_pdu_list = RC.mac[i]->dl_config_pdu_list[j]; - RC.mac[i]->UL_req[j].ul_config_request_body. - ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list[j]; - for (int k = 0; k < 10; k++) - RC.mac[i]->UL_req_tmp[j][k]. - ul_config_request_body.ul_config_pdu_list = - RC.mac[i]->ul_config_pdu_list_tmp[j][k]; - for(int sf=0;sf<10;sf++){ - RC.mac[i]->HI_DCI0_req[j][sf].hi_dci0_request_body.hi_dci0_pdu_list =RC.mac[i]->hi_dci0_pdu_list[j][sf]; - } - - RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list = - RC.mac[i]->tx_request_pdu[j]; - RC.mac[i]->ul_handle = 0; - } - } - - AssertFatal(rlc_module_init() == 0, - "Could not initialize RLC layer\n"); - - // These should be out of here later - pdcp_layer_init(); - - rrc_init_global_param(); - - } else { - RC.mac = NULL; + mac = malloc16(RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *)); + AssertFatal(mac != NULL, + "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", + RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), + RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); + for (i = 0; i < RC.nb_macrlc_inst; i++) { + mac[i] = malloc16(sizeof(eNB_MAC_INST)); + AssertFatal(mac[i] != NULL, + "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", + RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), + RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); + LOG_D(MAC, + "[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n", + sizeof(eNB_MAC_INST), RC.nb_macrlc_inst, mac); + bzero(mac[i], sizeof(eNB_MAC_INST)); + mac[i]->Mod_id = i; + for (j = 0; j < MAX_NUM_CCs; j++) { + mac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = + mac[i]->dl_config_pdu_list[j]; + mac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = + mac[i]->ul_config_pdu_list[j]; + for (int k = 0; k < 10; k++) + mac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list = + mac[i]->ul_config_pdu_list_tmp[j][k]; + for(int sf=0;sf<10;sf++) + mac[i]->HI_DCI0_req[j][sf].hi_dci0_request_body.hi_dci0_pdu_list = + mac[i]->hi_dci0_pdu_list[j][sf]; + mac[i]->TX_req[j].tx_request_body.tx_pdu_list = mac[i]->tx_request_pdu[j]; + mac[i]->ul_handle = 0; } - // Initialize Linked-List for Active UEs and slice configuration - for (i = 0; i < RC.nb_macrlc_inst; i++) { - mac = RC.mac[i]; + mac[i]->if_inst = IF_Module_init(i); + UE_list = &mac[i]->UE_list; + UE_list->num_UEs = 0; + UE_list->head = -1; + UE_list->head_ul = -1; + UE_list->avail = 0; - mac->if_inst = IF_Module_init(i); - - UE_list = &mac->UE_list; - - UE_list->num_UEs = 0; - UE_list->head = -1; - UE_list->head_ul = -1; - UE_list->avail = 0; - - for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) { + for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) { UE_list->next[list_el] = list_el + 1; UE_list->next_ul[list_el] = list_el + 1; - } - - UE_list->next[list_el] = -1; - UE_list->next_ul[list_el] = -1; - - sli = &mac->slice_info; - - sli->intraslice_share_active = 1; - sli->interslice_share_active = 1; - - sli->n_dl = 1; - memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); - sli->dl[0].pct = 1.0; - sli->dl[0].prio = 10; - sli->dl[0].pos_high = N_RBG_MAX; - sli->dl[0].maxmcs = 28; - sli->dl[0].sorting = 0x012345; - sli->dl[0].sched_name = "schedule_ue_spec"; - sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); - AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); - - sli->n_ul = 1; - memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); - sli->ul[0].pct = 1.0; - sli->ul[0].maxmcs = 20; - sli->ul[0].sorting = 0x0123; - sli->ul[0].sched_name = "schedule_ulsch_rnti"; - sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); - AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); } + UE_list->next[list_el] = -1; + UE_list->next_ul[list_el] = -1; + sli = &mac[i]->slice_info; + sli->intraslice_share_active = 1; + sli->interslice_share_active = 1; + + sli->n_dl = 1; + memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); + sli->dl[0].pct = 1.0; + sli->dl[0].prio = 10; + sli->dl[0].pos_high = N_RBG_MAX; + sli->dl[0].maxmcs = 28; + sli->dl[0].sorting = 0x012345; + sli->dl[0].sched_name = "schedule_ue_spec"; + sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); + AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); + + sli->n_ul = 1; + memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); + sli->ul[0].pct = 1.0; + sli->ul[0].maxmcs = 20; + sli->ul[0].sorting = 0x0123; + sli->ul[0].sched_name = "schedule_ulsch_rnti"; + sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); + AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); + } + + RC.mac = mac; + + AssertFatal(rlc_module_init() == 0, + "Could not initialize RLC layer\n"); + + // These should be out of here later + pdcp_layer_init(); + + rrc_init_global_param(); } void mac_init_cell_params(int Mod_idP, int CC_idP) From 0bb6a19f71a1721ce11acf252c7b2160dd60390f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 4 May 2018 16:17:44 +0200 Subject: [PATCH 68/99] only initialize RC.mac once --- openair2/ENB_APP/enb_config.c | 2 +- openair2/LAYER2/MAC/config.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 012375e668..195ab17877 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -292,7 +292,7 @@ void RCconfig_L1(void) { LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_CC[0]=%d for init_eNB_afterRU()\n", __FUNCTION__, RC.nb_CC[0]); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst); - mac_top_init_eNB(); + //mac_top_init_eNB(); configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n .remote_portd); } diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index a7bf532b09..5331f07a68 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -733,7 +733,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, if (RC.mac == NULL) l2_init_eNB(); - mac_top_init_eNB(); + //mac_top_init_eNB(); RC.mac[Mod_idP]->common_channels[CC_idP].mib = mib; RC.mac[Mod_idP]->common_channels[CC_idP].physCellId = physCellId; From 6c4f58a0a0a5ba63c49848d17cf1b5e7ad489349 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Fri, 1 Jun 2018 00:03:26 +0200 Subject: [PATCH 69/99] move UE_list/slice init in dedicated functions --- openair2/LAYER2/MAC/mac_proto.h | 4 ++ openair2/LAYER2/MAC/main.c | 89 ++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 1400d862d6..0d4cd72ae9 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -165,6 +165,10 @@ void add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, //main.c +void init_UE_list(UE_list_t *UE_list); + +void init_slice_info(slice_info_t *sli); + int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index b325c9b3ea..8fb8d44e0a 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -46,12 +46,57 @@ extern RAN_CONTEXT_t RC; +void init_UE_list(UE_list_t *UE_list) +{ + int list_el; + UE_list->num_UEs = 0; + UE_list->head = -1; + UE_list->head_ul = -1; + UE_list->avail = 0; + for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) { + UE_list->next[list_el] = list_el + 1; + UE_list->next_ul[list_el] = list_el + 1; + } + UE_list->next[list_el] = -1; + UE_list->next_ul[list_el] = -1; + memset(UE_list->DLSCH_pdu, 0, sizeof(UE_list->DLSCH_pdu)); + memset(UE_list->UE_template, 0, sizeof(UE_list->UE_template)); + memset(UE_list->eNB_UE_stats, 0, sizeof(UE_list->eNB_UE_stats)); + memset(UE_list->UE_sched_ctrl, 0, sizeof(UE_list->UE_sched_ctrl)); + memset(UE_list->active, 0, sizeof(UE_list->active)); + memset(UE_list->assoc_dl_slice_idx, 0, sizeof(UE_list->assoc_dl_slice_idx)); + memset(UE_list->assoc_ul_slice_idx, 0, sizeof(UE_list->assoc_ul_slice_idx)); +} + +void init_slice_info(slice_info_t *sli) +{ + sli->intraslice_share_active = 1; + sli->interslice_share_active = 1; + + sli->n_dl = 1; + memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); + sli->dl[0].pct = 1.0; + sli->dl[0].prio = 10; + sli->dl[0].pos_high = N_RBG_MAX; + sli->dl[0].maxmcs = 28; + sli->dl[0].sorting = 0x012345; + sli->dl[0].sched_name = "schedule_ue_spec"; + sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); + AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); + + sli->n_ul = 1; + memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); + sli->ul[0].pct = 1.0; + sli->ul[0].maxmcs = 20; + sli->ul[0].sorting = 0x0123; + sli->ul[0].sched_name = "schedule_ulsch_rnti"; + sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); + AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); +} + void mac_top_init_eNB(void) { module_id_t i, j; - int list_el; - UE_list_t *UE_list; - slice_info_t *sli; eNB_MAC_INST **mac; LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n", @@ -95,42 +140,8 @@ void mac_top_init_eNB(void) mac[i]->if_inst = IF_Module_init(i); - UE_list = &mac[i]->UE_list; - UE_list->num_UEs = 0; - UE_list->head = -1; - UE_list->head_ul = -1; - UE_list->avail = 0; - - for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) { - UE_list->next[list_el] = list_el + 1; - UE_list->next_ul[list_el] = list_el + 1; - } - UE_list->next[list_el] = -1; - UE_list->next_ul[list_el] = -1; - - sli = &mac[i]->slice_info; - sli->intraslice_share_active = 1; - sli->interslice_share_active = 1; - - sli->n_dl = 1; - memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); - sli->dl[0].pct = 1.0; - sli->dl[0].prio = 10; - sli->dl[0].pos_high = N_RBG_MAX; - sli->dl[0].maxmcs = 28; - sli->dl[0].sorting = 0x012345; - sli->dl[0].sched_name = "schedule_ue_spec"; - sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); - AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); - - sli->n_ul = 1; - memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); - sli->ul[0].pct = 1.0; - sli->ul[0].maxmcs = 20; - sli->ul[0].sorting = 0x0123; - sli->ul[0].sched_name = "schedule_ulsch_rnti"; - sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); - AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); + init_UE_list(&mac[i]->UE_list); + init_slice_info(&mac[i]->slice_info); } RC.mac = mac; From 1adbaa7a547b0cf67be257789bbe333c520c23b9 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Fri, 1 Jun 2018 00:04:39 +0200 Subject: [PATCH 70/99] when restarting, re-init MAC UE_list --- targets/RT/USER/lte-softmodem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 25a55a6e56..b606ee2f46 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -831,6 +831,9 @@ int restart_L1L2(module_id_t enb_id) /* TODO this should be done for all RUs associated to this eNB */ memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); set_function_spec_param(RC.ru[enb_id]); + /* reset the list of connected UEs in the MAC, since in this process with + * loose all UEs (have to reconnect) */ + init_UE_list(&RC.mac[enb_id]->UE_list); LOG_I(ENB_APP, "attempting to create ITTI tasks\n"); if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { From 9399bed23a03b29f3f84b067203d0a640050098c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 6 Jun 2018 10:46:35 +0200 Subject: [PATCH 71/99] FlexRAN MAC: align allocated memory for lfds --- .../ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 7a61bad6d3..5ad7a6d496 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1272,8 +1272,17 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { lfds700_misc_prng_init(&ps[mod_id]); int num_elements = RINGBUFFER_SIZE + 1; //Allow RINGBUFFER_SIZE messages to be stored in the ringbuffer at any time - dl_mac_config_array[mod_id] = malloc( sizeof(struct lfds700_ringbuffer_element) * num_elements); - lfds700_ringbuffer_init_valid_on_current_logical_core( &ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL ); + /* lfds700_ringbuffer_init_valid_on_current_logical_core()'s second argument + * must be aligned to LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES. From the + * documentation: "Heap allocated variables however will by no means be + * correctly aligned and an aligned malloc must be used." Therefore, we use + * posix_memalign */ + i = posix_memalign((void **)&dl_mac_config_array[mod_id], + LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, + sizeof(struct lfds700_ringbuffer_element) * num_elements); + AssertFatal(i == 0, "posix_memalign(): could not allocate aligned memory for lfds library\n"); + lfds700_ringbuffer_init_valid_on_current_logical_core(&ringbuffer_state[mod_id], + dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL); for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { for (j = 0; j < 8; j++) { if (RC.mac && RC.mac[mod_id]) From 3b80c73f937b8942fedeff92c19ec33fb156d6a9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 6 Jun 2018 16:42:17 +0200 Subject: [PATCH 72/99] FlexRAN: Loop over UEs using UE_id, not index --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 35 +++--- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 16 ++- openair2/ENB_APP/flexran_agent_common.c | 113 +++++++++--------- openair2/ENB_APP/flexran_agent_handler.c | 9 +- openair2/ENB_APP/flexran_agent_ran_api.c | 15 +++ openair2/ENB_APP/flexran_agent_ran_api.h | 4 + 6 files changed, 110 insertions(+), 82 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 5ad7a6d496..caddb0616a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -894,7 +894,6 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle for (j = 0; j < 8; j++) { if (RC.mac && RC.mac[mod_id] && RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid == 1) { available_harq[i] = j; - sf_trigger_msg->n_dl_info++; break; } } @@ -903,10 +902,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10); - /*TODO: Fill in the number of dl HARQ related info, based on the number of currently - *transmitting UEs - */ - // sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id); + sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id); Protocol__FlexDlInfo **dl_info = NULL; @@ -916,33 +912,31 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle goto error; i = -1; //Fill the status of the current HARQ process for each UE - for(UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (available_harq[UE_id] < 0) { + for(i = 0; i < sf_trigger_msg->n_dl_info; i++) { + if (available_harq[i] < 0) continue; - } else { - i++; - } dl_info[i] = malloc(sizeof(Protocol__FlexDlInfo)); if(dl_info[i] == NULL) goto error; + UE_id = flexran_get_ue_id(mod_id, i); protocol__flex_dl_info__init(dl_info[i]); dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); dl_info[i]->has_rnti = 1; /*Fill in the right id of this round's HARQ process for this UE*/ // uint8_t harq_id; //uint8_t harq_status; - // flexran_get_harq(mod_id, UE_PCCID(mod_id,i), i, frame, subframe, &harq_id, &harq_status); + // flexran_get_harq(mod_id, UE_PCCID(mod_id, UE_id), i, frame, subframe, &harq_id, &harq_status); dl_info[i]->harq_process_id = available_harq[UE_id]; if (RC.mac && RC.mac[mod_id]) - RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][UE_id].harq_pid = 0; + RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id, UE_id)][UE_id].harq_pid = 0; dl_info[i]->has_harq_process_id = 1; /* Fill in the status of the HARQ process (2 TBs)*/ dl_info[i]->n_harq_status = 2; dl_info[i]->harq_status = malloc(sizeof(uint32_t) * dl_info[i]->n_harq_status); for (j = 0; j < dl_info[i]->n_harq_status; j++) { - dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[i].round[UE_PCCID(mod_id,i)][j]; + dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[UE_id].round[UE_PCCID(mod_id, UE_id)][j]; // TODO: This should be different per TB } // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d and harq %d (round %d)\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10, dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]); @@ -950,7 +944,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Need to make a retransmission for harq %d (round %d)\n", flexran_get_current_frame(mod_id), flexran_get_current_subframe(mod_id), dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]); } /*Fill in the serving cell index for this UE */ - dl_info[i]->serv_cell_index = UE_PCCID(mod_id,i); + dl_info[i]->serv_cell_index = UE_PCCID(mod_id, UE_id); dl_info[i]->has_serv_cell_index = 1; } } @@ -974,18 +968,21 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle if(ul_info[i] == NULL) goto error; protocol__flex_ul_info__init(ul_info[i]); - ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, i); + + UE_id = flexran_get_ue_id(mod_id, i); + + ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); ul_info[i]->has_rnti = 1; /* Fill in the Tx power control command for this UE (if available), * primary carrier */ - if(flexran_get_tpc(mod_id, i, 0) != 1){ + if(flexran_get_tpc(mod_id, UE_id, 0) != 1){ /* assume primary carrier */ - ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); + ul_info[i]->tpc = flexran_get_tpc(mod_id, UE_id, 0); ul_info[i]->has_tpc = 1; } else{ /* assume primary carrier */ - ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); + ul_info[i]->tpc = flexran_get_tpc(mod_id, UE_id, 0); ul_info[i]->has_tpc = 0; } /*TODO: fill in the amount of data in bytes in the MAC SDU received in this subframe for the @@ -999,7 +996,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle ul_info[i]->reception_status = PROTOCOL__FLEX_RECEPTION_STATUS__FLRS_OK; ul_info[i]->has_reception_status = 1; /*Fill in the serving cell index for this UE */ - ul_info[i]->serv_cell_index = UE_PCCID(mod_id,i); + ul_info[i]->serv_cell_index = UE_PCCID(mod_id, UE_id); ul_info[i]->has_serv_cell_index = 1; } } diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 34833ca898..d685845f26 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -264,27 +264,31 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { - int i; + //int i; // int priority = 0; // Warning Preventing // void *data; // int size; // err_code_t err_code = -100; triggered_rrc = true; - int num; + //int num; + /* TODO do we need this at the current state? meas_stats is never put into a + * protobuf message?! num = flexran_get_num_ues (mod_id); meas_stats = malloc(sizeof(rrc_meas_stats) * num); for (i = 0; i < num; i++){ - meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, i); - meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id,i); - meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i) - 140; + UE_id = flexran_get_ue_id(mod_id, i); + meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, UE_id); + meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id, UE_id); + meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id, UE_id) - 140; // measResults->measResultPCell.rsrpResult - 140; - meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i)/2 - 20; + meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id)/2 - 20; // (measResults->measResultPCell.rsrqResult)/2 - 20; } + */ // repl->neigh_meas = NULL; // if (meas->measResultNeighCells != NULL) { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index c55633af31..1a92c9e262 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -459,6 +459,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl xid = (lc_config_request_msg->header)->xid; int i, j; + int UE_id; Protocol__FlexLcConfigReply *lc_config_reply_msg; lc_config_reply_msg = malloc(sizeof(Protocol__FlexLcConfigReply)); @@ -484,13 +485,15 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_ue_config[i] = malloc(sizeof(Protocol__FlexLcUeConfig)); protocol__flex_lc_ue_config__init(lc_ue_config[i]); + UE_id = flexran_get_ue_id(mod_id, i); + lc_ue_config[i]->has_rnti = 1; - lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i); + lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); //TODO: Set the number of LC configurations that will be reported for this UE //Set this according to the current state of the UE. This is only a temporary fix int status = 0; - status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, i)); + status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, UE_id)); /* TODO needs to be revised and appropriate API to be implemented */ if (status < RRC_CONNECTED) { lc_ue_config[i]->n_lc_config = 0; @@ -513,14 +516,14 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_config[j]->has_lcid = 1; lc_config[j]->lcid = j+1; - int lcg = flexran_get_lcg(mod_id, i, j+1); + int lcg = flexran_get_lcg(mod_id, UE_id, j+1); if (lcg >= 0 && lcg <= 3) { lc_config[j]->has_lcg = 1; - lc_config[j]->lcg = flexran_get_lcg(mod_id, i,j+1); + lc_config[j]->lcg = flexran_get_lcg(mod_id, UE_id, j+1); } lc_config[j]->has_direction = 1; - lc_config[j]->direction = flexran_get_direction(i,j+1); + lc_config[j]->direction = flexran_get_direction(UE_id, j+1); //TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported lc_config[j]->has_qos_bearer_type = 1; lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR; @@ -587,6 +590,7 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl xid = (ue_config_request_msg->header)->xid; int i; + int UE_id; Protocol__FlexUeConfigReply *ue_config_reply_msg; ue_config_reply_msg = malloc(sizeof(Protocol__FlexUeConfigReply)); @@ -611,30 +615,31 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config[i] = malloc(sizeof(Protocol__FlexUeConfig)); protocol__flex_ue_config__init(ue_config[i]); - ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i); + UE_id = flexran_get_ue_id(mod_id, i); + ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); ue_config[i]->has_rnti = 1; - ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, i); + ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, UE_id); ue_config[i]->has_imsi = 1; - ue_config[i]->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, i); + ue_config[i]->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, UE_id); ue_config[i]->has_dl_slice_id = 1; - ue_config[i]->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, i); + ue_config[i]->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, UE_id); ue_config[i]->has_ul_slice_id = 1; //TODO: Set the DRX configuration (optional) //Not supported for now, so we do not set it - if (flexran_get_time_alignment_timer(mod_id,i) != -1) { - ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); - ue_config[i]->has_time_alignment_timer = 1; + if (flexran_get_time_alignment_timer(mod_id, UE_id) != -1) { + ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id, UE_id); + ue_config[i]->has_time_alignment_timer = 1; } - if (flexran_get_meas_gap_config(mod_id,i) != -1) { - ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); - ue_config[i]->has_meas_gap_config_pattern = 1; + if (flexran_get_meas_gap_config(mod_id, UE_id) != -1) { + ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id, UE_id); + ue_config[i]->has_meas_gap_config_pattern = 1; } if (ue_config[i]->has_meas_gap_config_pattern == 1 && - ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); + ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { + ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id, UE_id); ue_config[i]->has_meas_gap_config_sf_offset = 1; } //TODO: Set the SPS configuration (Optional) @@ -646,77 +651,77 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl //TODO: Set the CQI configuration (Optional) //We do not set it for now - if (flexran_get_ue_transmission_mode(mod_id,i) != -1) { - ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); + if (flexran_get_ue_transmission_mode(mod_id, UE_id) != -1) { + ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id, UE_id); ue_config[i]->has_transmission_mode = 1; } - ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); + ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, UE_id); ue_config[i]->has_ue_aggregated_max_bitrate_ul = 1; - ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); + ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id, UE_id); ue_config[i]->has_ue_aggregated_max_bitrate_dl = 1; Protocol__FlexUeCapabilities *capabilities; capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); protocol__flex_ue_capabilities__init(capabilities); capabilities->has_half_duplex = 1; - capabilities->half_duplex = flexran_get_half_duplex(mod_id, i); + capabilities->half_duplex = flexran_get_half_duplex(mod_id, UE_id); capabilities->has_intra_sf_hopping = 1; - capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i); + capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, UE_id); capabilities->has_type2_sb_1 = 1; - capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i); + capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, UE_id); capabilities->has_ue_category = 1; - capabilities->ue_category = flexran_get_ue_category(mod_id, i); + capabilities->ue_category = flexran_get_ue_category(mod_id, UE_id); capabilities->has_res_alloc_type1 = 1; - capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i); + capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, UE_id); //Set the capabilites to the message ue_config[i]->capabilities = capabilities; - if (flexran_get_ue_transmission_antenna(mod_id,i) != -1) { + if (flexran_get_ue_transmission_antenna(mod_id, UE_id) != -1) { ue_config[i]->has_ue_transmission_antenna = 1; - ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); + ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id, UE_id); } - if (flexran_get_tti_bundling(mod_id,i) != -1) { + if (flexran_get_tti_bundling(mod_id, UE_id) != -1) { ue_config[i]->has_tti_bundling = 1; - ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id,i); + ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id, UE_id); } - if (flexran_get_maxHARQ_TX(mod_id,i) != -1) { + if (flexran_get_maxHARQ_TX(mod_id, UE_id) != -1) { ue_config[i]->has_max_harq_tx = 1; - ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); + ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id, UE_id); } - if (flexran_get_beta_offset_ack_index(mod_id,i) != -1) { - ue_config[i]->has_beta_offset_ack_index = 1; - ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); + if (flexran_get_beta_offset_ack_index(mod_id, UE_id) != -1) { + ue_config[i]->has_beta_offset_ack_index = 1; + ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id, UE_id); } - if (flexran_get_beta_offset_ri_index(mod_id,i) != -1) { + if (flexran_get_beta_offset_ri_index(mod_id, UE_id) != -1) { ue_config[i]->has_beta_offset_ri_index = 1; - ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); + ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id, UE_id); } - if (flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { + if (flexran_get_beta_offset_cqi_index(mod_id, UE_id) != -1) { ue_config[i]->has_beta_offset_cqi_index = 1; - ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); + ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id, UE_id); } /* assume primary carrier */ - if (flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0) != -1) { + if (flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0) != -1) { ue_config[i]->has_ack_nack_simultaneous_trans = 1; - ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0); + ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0); } - if (flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { + if (flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id) != -1) { ue_config[i]->has_simultaneous_ack_nack_cqi = 1; - ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); + ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id); } - if (flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { + if (flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id) != -1) { ue_config[i]->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); + int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id); if (mode > 4) { ue_config[i]->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; } else { @@ -724,26 +729,26 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl } } - if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { + if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id) != -1) { ue_config[i]->has_tdd_ack_nack_feedback = 1; - ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); + ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id); } - if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { + if(flexran_get_ack_nack_repetition_factor(mod_id, UE_id) != -1) { ue_config[i]->has_ack_nack_repetition_factor = 1; - ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); + ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id, UE_id); } - if (flexran_get_extended_bsr_size(mod_id, i) != -1) { + if (flexran_get_extended_bsr_size(mod_id, UE_id) != -1) { ue_config[i]->has_extended_bsr_size = 1; - ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); + ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, UE_id); } //TODO: Set carrier aggregation support (boolean) ue_config[i]->has_ca_support = 0; ue_config[i]->ca_support = 0; ue_config[i]->has_pcell_carrier_index = 1; - ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, i); + ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, UE_id); if(ue_config[i]->has_ca_support){ //TODO: Set cross carrier scheduling support (boolean) ue_config[i]->has_cross_carrier_sched_support = 0; @@ -858,8 +863,8 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i] = malloc(sizeof(Protocol__FlexCellConfig)); protocol__flex_cell_config__init(cell_conf[i]); - cell_conf[i]->phy_cell_id = 1; - cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(mod_id,i); + cell_conf[i]->phy_cell_id = flexran_get_cell_id(mod_id,i); + cell_conf[i]->has_phy_cell_id = 1; cell_conf[i]->cell_id = i; cell_conf[i]->has_cell_id = 1; diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index fa3270696a..74ea5bfa1f 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -210,6 +210,7 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 int enb_id = mod_id; + int UE_id; //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; //UE_list_t *eNB_UE_list= &eNB->UE_list; @@ -249,8 +250,9 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr goto error; } for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; - report_config.ue_report_type[i].ue_report_flags = ue_flags; + UE_id = flexran_get_ue_id(mod_id, i); + report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, UE_id); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; + report_config.ue_report_type[i].ue_report_flags = ue_flags; } //Set the number of CCs and create a list with the cell stats configs report_config.nr_cc = MAX_NUM_CCs; @@ -359,7 +361,8 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr goto error; } for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i]; + UE_id = flexran_get_ue_id(mod_id, i); + report_config.ue_report_type[i].ue_rnti = ue_req->rnti[UE_id]; report_config.ue_report_type[i].ue_report_flags = ue_req->flags; } break; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index dc74652874..f47db710c4 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -113,6 +113,21 @@ int flexran_get_num_ues(mid_t mod_id) return RC.mac[mod_id]->UE_list.num_UEs; } +int flexran_get_ue_id(mid_t mod_id, int i) +{ + int n; + if (!mac_is_present(mod_id)) return 0; + /* get the (i+1)'th active UE */ + for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { + if (RC.mac[mod_id]->UE_list.active[n] == TRUE) { + if (i == 0) + return n; + --i; + } + } + return 0; +} + rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) { return UE_RNTI(mod_id, ue_id); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index d64d5806e6..a9c9299398 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -73,6 +73,10 @@ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); /* Return the number of attached UEs */ int flexran_get_num_ues(mid_t mod_id); +/* Return the UE id of attached UE as opposed to the index [0,NUM UEs] (i.e., + * the i'th active UE). Returns 0 if the i'th active UE could not be found. */ +int flexran_get_ue_id(mid_t mod_id, int i); + /* Get the rnti of a UE with id ue_id */ rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id); From 97c69dc4a4f5b8946197c38f85c4919fc2804c31 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 7 Jun 2018 11:58:34 +0200 Subject: [PATCH 73/99] Drop traffic in PDCP if RLC buffer is full If the buffer in the RLC is full, testing the buffer state over and over again slows the DL traffic down. In order to circumvent this, the PDCP will drop any data during a configurable time (compile-time) before it delivers data to RLC again. To change this, see the constant TM_SKIP_FULL_BUF_MS in pdcp.h. --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 46 +++++++++++++++++++---------- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 2 ++ openair2/LAYER2/RLC/rlc.h | 1 + 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 4731039c1a..8b96542e33 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -169,6 +169,11 @@ boolean_t pdcp_data_req( start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); } + for (pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) { + if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti) + break; + } + // PDCP transparent mode for MBMS traffic if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { @@ -366,13 +371,24 @@ boolean_t pdcp_data_req( LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size, "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); - rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p + /* if RLC buffer for this UE has been full, we want to skip all subsequent + * traffic for TM_SKIP_FULL_BUF_MS ms. Afterwards, it will be checkd again */ + if (pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] == 0 + || pdcp_enb[ctxt_pP->module_id].sfn - pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] >= TM_SKIP_FULL_BUF_MS) { + pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] = 0; + rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, + confirmP, pdcp_pdu_size, pdcp_pdu_p #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,sourceL2Id - ,destinationL2Id + ,sourceL2Id + ,destinationL2Id #endif - ); - + ); + } else { + /* RLC would free pdcp_pdu_p, but since we skip it, have to do it + * ourselves and fake normal operation */ + free_mem_block(pdcp_pdu_p, __func__); + rlc_status = RLC_OP_SKIPPED_FUL_BUF; + } } switch (rlc_status) { @@ -392,10 +408,19 @@ boolean_t pdcp_data_req( break; case RLC_OP_STATUS_OUT_OF_RESSOURCES: + pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] = pdcp_enb[ctxt_pP->module_id].sfn; LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + int h = TM_SKIP_FULL_BUF_MS; + LOG_W(PDCP, "Blocking incoming traffic for %d ms\n", h); ret= FALSE; break; + case RLC_OP_SKIPPED_FUL_BUF: + LOG_D(PDCP, "Skipping RLC request due to full buffer\n"); + /* fake good return so that GTP doesn't spam us */ + ret = TRUE; + break; + default: LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); ret= FALSE; @@ -408,16 +433,6 @@ boolean_t pdcp_data_req( stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); } - /* - * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK - * so we return TRUE afterwards - */ - - for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ - if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) - break; - } - //LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn); Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; @@ -1066,6 +1081,7 @@ void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){ if (pdcp_enb[ctxt_pP->module_id].rnti[i] == 0 ){ pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti; pdcp_enb[ctxt_pP->module_id].uid[i]=i; + pdcp_enb[ctxt_pP->module_id].time_buf_full[i] = 0; pdcp_enb[ctxt_pP->module_id].num_ues++; printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti); // ret=1; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 054bb5fac4..1bfe4e022a 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -106,6 +106,8 @@ typedef struct pdcp_enb_s { uint16_t uid[MAX_MOBILES_PER_ENB]; rnti_t rnti[MAX_MOBILES_PER_ENB]; uint16_t num_ues; +#define TM_SKIP_FULL_BUF_MS (500) + uint64_t time_buf_full[MAX_MOBILES_PER_ENB]; uint64_t sfn; frame_t frame; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 8c557188a2..dfb22f1a0d 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -67,6 +67,7 @@ typedef uint64_t hash_key_t; #define RLC_OP_STATUS_BAD_PARAMETER 22 #define RLC_OP_STATUS_INTERNAL_ERROR 2 #define RLC_OP_STATUS_OUT_OF_RESSOURCES 3 +#define RLC_OP_SKIPPED_FUL_BUF 4 #define RLC_MUI_UNDEFINED (mui_t)0 From cca5c1b71af1af1748706decc0592198d8474447 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 7 Jun 2018 17:42:38 +0200 Subject: [PATCH 74/99] FlexRAN: use correct identifiers for PDCP, RRC * give the correct UE_id instead an index of the protobuf message (they can diverge from each other) * in the PDCP part of the RAN API, the RAN API has to make the conversion UE_id (MAC) to UID (PDCP) * a follow up commit could clean up the interfaces: - the MAC functions take the UE_id - the RRC functions take the RNTI - the PDCP functions take the UID this would mean the caller has to find those ID but would decrease computations since the RAN API functions do not have to do that themselves --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 91 ++++++------ .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.c | 8 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 31 +++-- openair2/ENB_APP/flexran_agent_ran_api.c | 130 ++++++++++++------ openair2/ENB_APP/flexran_agent_ran_api.h | 36 ++--- 5 files changed, 179 insertions(+), 117 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index caddb0616a..1732b39342 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -73,6 +73,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i, j, k; + int UE_id; int cc_id = 0; int enb_id = mod_id; @@ -82,6 +83,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, for (i = 0; i < report_config->nr_ue; i++) { + UE_id = flexran_get_ue_id(mod_id, i); + ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; ue_report[i]->has_rnti = 1; @@ -103,7 +106,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, /* Check flag for creation of PHR report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { - ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; + ue_report[i]->phr = flexran_get_ue_phr (enb_id, UE_id); // eNB_UE_list->UE_template[UE_PCCID(enb_id,UE_id)][UE_id].phr_info; ue_report[i]->has_phr = 1; } @@ -125,11 +128,11 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, protocol__flex_rlc_bsr__init(rlc_reports[j]); rlc_reports[j]->lc_id = j+1; rlc_reports[j]->has_lc_id = 1; - rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, i, j + 1); + rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, UE_id, j + 1); rlc_reports[j]->has_tx_queue_size = 1; //TODO:Set tx queue head of line delay in ms - rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, i, j + 1); + rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, UE_id, j + 1); rlc_reports[j]->has_tx_queue_hol_delay = 1; //TODO:Set retransmission queue size in bytes rlc_reports[j]->retransmission_queue_size = 10; @@ -138,7 +141,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, rlc_reports[j]->retransmission_queue_hol_delay = 100; rlc_reports[j]->has_retransmission_queue_hol_delay = 0; //TODO DONE:Set current size of the pending message in bytes - rlc_reports[j]->status_pdu_size = flexran_get_num_pdus_buffer(enb_id , i, j + 1); + rlc_reports[j]->status_pdu_size = flexran_get_num_pdus_buffer(enb_id, UE_id, j + 1); rlc_reports[j]->has_status_pdu_size = 1; } @@ -152,7 +155,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, /* Check flag for creation of MAC CE buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; + ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id, UE_id, 0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values // found in stats_common.pb-c.h. See @@ -173,7 +176,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, dl_report->sfn_sn = flexran_get_sfn_sf(enb_id); dl_report->has_sfn_sn = 1; //Set the number of DL CQI reports for this UE. One for each CC - dl_report->n_csi_report = flexran_get_active_CC(enb_id,i); + dl_report->n_csi_report = flexran_get_active_CC(enb_id, UE_id); dl_report->n_csi_report = 1 ; //Create the actual CSI reports. Protocol__FlexDlCsi **csi_reports; @@ -190,7 +193,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, csi_reports[j]->serv_cell_index = j; csi_reports[j]->has_serv_cell_index = 1; //The rank indicator value for this cc - csi_reports[j]->ri = flexran_get_current_RI(enb_id,i,j); + csi_reports[j]->ri = flexran_get_current_RI(enb_id, UE_id, j); csi_reports[j]->has_ri = 1; //TODO: the type of CSI report based on the configuration of the UE //For now we only support type P10, which only needs a wideband value @@ -209,7 +212,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, protocol__flex_csi_p10__init(csi10); //TODO: set the wideband value // NN: this is also depends on cc_id - csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; + csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,UE_id)][UE_id].dl_cqi; csi10->has_wb_cqi = 1; //Add the type of measurements to the csi report in the proper union type csi_reports[j]->p10csi = csi10; @@ -226,26 +229,26 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); csi11->n_wb_cqi = 1; - csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); + csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, UE_id); // According To spec 36.213 if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { // TODO PMI - csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, UE_id, 0); csi11->has_wb_pmi = 1; } else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){ // TODO PMI - csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, UE_id, 0); csi11->has_wb_pmi = 1; } else if (flexran_get_antenna_ports(enb_id, j) == 4 && csi_reports[j]->ri == 2){ // TODO PMI - csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, UE_id, 0); csi11->has_wb_pmi = 1; @@ -269,7 +272,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, goto error; protocol__flex_csi_p20__init(csi20); - csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); csi20->has_wb_cqi = 1; @@ -293,7 +296,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_p21__init(csi21); - // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside @@ -321,7 +324,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a12__init(csi12); - // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); // csi12->sb_pmi = 1 ; //TODO inside @@ -336,17 +339,17 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a22__init(csi22); - // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); // csi22->sb_cqi = 1 ; //TODO inside - // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i); + // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, UE_id); // csi22->has_wb_pmi = 1; // csi22->sb_pmi = 1 ; //TODO inside // csi22->has_wb_pmi = 1; - // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i); + // csi22->sb_list = flexran_get_ue_wcqi (enb_id, UE_id); } @@ -359,7 +362,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a20__init(csi20); - // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); // csi20->has_wb_cqi = 1; // csi20>sb_cqi = 1 ; //TODO inside @@ -489,8 +492,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1; full_ul_report->pucch_dbm[j]->serv_cell_index = j; - if(flexran_get_p0_pucch_dbm(enb_id,i, j) != -1){ - full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id,i,j); + if(flexran_get_p0_pucch_dbm(enb_id, UE_id, j) != -1){ + full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id, UE_id, j); full_ul_report->pucch_dbm[j]->has_p0_pucch_dbm = 1; } } @@ -511,69 +514,69 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, protocol__flex_mac_stats__init(macstats); - macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, i, cc_id); + macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, UE_id, cc_id); macstats->has_total_bytes_sdus_dl = 1; - macstats->total_bytes_sdus_ul = flexran_get_total_size_ul_mac_sdus(mod_id, i, cc_id); + macstats->total_bytes_sdus_ul = flexran_get_total_size_ul_mac_sdus(mod_id, UE_id, cc_id); macstats->has_total_bytes_sdus_ul = 1; - macstats->tbs_dl = flexran_get_TBS_dl(mod_id, i, cc_id); + macstats->tbs_dl = flexran_get_TBS_dl(mod_id, UE_id, cc_id); macstats->has_tbs_dl = 1; - macstats->tbs_ul = flexran_get_TBS_ul(mod_id, i, cc_id); + macstats->tbs_ul = flexran_get_TBS_ul(mod_id, UE_id, cc_id); macstats->has_tbs_ul = 1; - macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, i, cc_id); + macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, UE_id, cc_id); macstats->has_prb_retx_dl = 1; - macstats->prb_retx_ul = flexran_get_num_prb_retx_ul_per_ue(mod_id, i, cc_id); + macstats->prb_retx_ul = flexran_get_num_prb_retx_ul_per_ue(mod_id, UE_id, cc_id); macstats->has_prb_retx_ul = 1; - macstats->prb_dl = flexran_get_num_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->prb_dl = flexran_get_num_prb_dl_tx_per_ue(mod_id, UE_id, cc_id); macstats->has_prb_dl = 1; - macstats->prb_ul = flexran_get_num_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->prb_ul = flexran_get_num_prb_ul_rx_per_ue(mod_id, UE_id, cc_id); macstats->has_prb_ul = 1; - macstats->mcs1_dl = flexran_get_mcs1_dl(mod_id, i, cc_id); + macstats->mcs1_dl = flexran_get_mcs1_dl(mod_id, UE_id, cc_id); macstats->has_mcs1_dl = 1; - macstats->mcs2_dl = flexran_get_mcs2_dl(mod_id, i, cc_id); + macstats->mcs2_dl = flexran_get_mcs2_dl(mod_id, UE_id, cc_id); macstats->has_mcs2_dl = 1; - macstats->mcs1_ul = flexran_get_mcs1_ul(mod_id, i, cc_id); + macstats->mcs1_ul = flexran_get_mcs1_ul(mod_id, UE_id, cc_id); macstats->has_mcs1_ul = 1; - macstats->mcs2_ul = flexran_get_mcs2_ul(mod_id, i, cc_id); + macstats->mcs2_ul = flexran_get_mcs2_ul(mod_id, UE_id, cc_id); macstats->has_mcs2_ul = 1; - macstats->total_prb_dl = flexran_get_total_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->total_prb_dl = flexran_get_total_prb_dl_tx_per_ue(mod_id, UE_id, cc_id); macstats->has_total_prb_dl = 1; - macstats->total_prb_ul = flexran_get_total_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->total_prb_ul = flexran_get_total_prb_ul_rx_per_ue(mod_id, UE_id, cc_id); macstats->has_total_prb_ul = 1; - macstats->total_pdu_dl = flexran_get_total_num_pdu_dl(mod_id, i, cc_id); + macstats->total_pdu_dl = flexran_get_total_num_pdu_dl(mod_id, UE_id, cc_id); macstats->has_total_pdu_dl = 1; - macstats->total_pdu_ul = flexran_get_total_num_pdu_ul(mod_id, i, cc_id); + macstats->total_pdu_ul = flexran_get_total_num_pdu_ul(mod_id, UE_id, cc_id); macstats->has_total_pdu_ul = 1; - macstats->total_tbs_dl = flexran_get_total_TBS_dl(mod_id, i, cc_id); + macstats->total_tbs_dl = flexran_get_total_TBS_dl(mod_id, UE_id, cc_id); macstats->has_total_tbs_dl = 1; - macstats->total_tbs_ul = flexran_get_total_TBS_ul(mod_id, i, cc_id); + macstats->total_tbs_ul = flexran_get_total_TBS_ul(mod_id, UE_id, cc_id); macstats->has_total_tbs_ul = 1; - macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, i); + macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, UE_id); macstats->has_harq_round = 1; Protocol__FlexMacSdusDl ** mac_sdus; - mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, i, cc_id)); + mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, UE_id, cc_id)); if (mac_sdus == NULL) goto error; - macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, i, cc_id); + macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, UE_id, cc_id); for (j = 0; j < macstats->n_mac_sdus_dl; j++){ @@ -581,10 +584,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, mac_sdus[j] = malloc(sizeof(Protocol__FlexMacSdusDl)); protocol__flex_mac_sdus_dl__init(mac_sdus[j]); - mac_sdus[j]->lcid = flexran_get_mac_sdu_lcid_index(mod_id, i, cc_id, j); + mac_sdus[j]->lcid = flexran_get_mac_sdu_lcid_index(mod_id, UE_id, cc_id, j); mac_sdus[j]->has_lcid = 1; - mac_sdus[j]->sdu_length = flexran_get_mac_sdu_size(mod_id, i, cc_id, mac_sdus[j]->lcid); + mac_sdus[j]->sdu_length = flexran_get_mac_sdu_size(mod_id, UE_id, cc_id, mac_sdus[j]->lcid); mac_sdus[j]->has_sdu_length = 1; diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index b2723f7181..7cb39fb723 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -78,6 +78,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i; + int UE_id; // int cc_id = 0; @@ -85,6 +86,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, if (report_config->nr_ue > 0) { for (i = 0; i < report_config->nr_ue; i++) { + UE_id = flexran_get_ue_id(mod_id, i); /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) { @@ -95,7 +97,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, goto error; protocol__flex_pdcp_stats__init(pdcp_aggr_stats); - flexran_agent_pdcp_aggregate_stats(mod_id, i, pdcp_aggr_stats); + flexran_agent_pdcp_aggregate_stats(mod_id, UE_id, pdcp_aggr_stats); pdcp_aggr_stats->has_pkt_tx=1; pdcp_aggr_stats->has_pkt_tx_bytes =1; @@ -104,7 +106,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->has_pkt_tx_aiat =1; pdcp_aggr_stats->has_pkt_tx_aiat_w =1; - pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, UE_id, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_tx_sn =1; pdcp_aggr_stats->has_pkt_rx =1; @@ -115,7 +117,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->has_pkt_rx_aiat_w =1; pdcp_aggr_stats->has_pkt_rx_oo =1; - pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, UE_id, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_rx_sn =1; pdcp_aggr_stats->sfn = flexran_get_pdcp_sfn(mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index d685845f26..b79ad88417 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -499,11 +499,14 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i,j; + int UE_id; /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { for (i = 0; i < report_config->nr_ue; i++) { + + UE_id = flexran_get_ue_id(mod_id, i); /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) { @@ -515,14 +518,14 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, goto error; protocol__flex_rrc_measurements__init(rrc_measurements); - rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i); - rrc_measurements->has_measid = 1; - - rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i); - rrc_measurements->has_pcell_rsrp = 1; - - rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i); - rrc_measurements->has_pcell_rsrq = 1 ; + rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id, UE_id); + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id, UE_id); + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id); + rrc_measurements->has_pcell_rsrq = 1 ; /* Target Cell, Neghibouring*/ @@ -533,7 +536,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_neigh_cells_measurements__init(neigh_meas); - neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, i); + neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, UE_id); Protocol__FlexEutraMeasurements **eutra_meas = NULL; @@ -551,7 +554,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_eutra_measurements__init(eutra_meas[j]); - eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, i, j); + eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, UE_id, j); eutra_meas[j]->has_phys_cell_id = 1; @@ -562,10 +565,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_eutra_ref_signal_meas__init(meas_result); - meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, UE_id, eutra_meas[j]->phys_cell_id); meas_result->has_rsrp = 1; - meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, UE_id, eutra_meas[j]->phys_cell_id); meas_result->has_rsrq = 1; eutra_meas[j]->meas_result = meas_result; @@ -629,8 +632,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, for (i = 0; i < report_config->nr_ue; i++){ + UE_id = flexran_get_ue_id(mod_id, i); + if (ue_report[i]->rrc_measurements->neigh_meas != NULL){ - for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, i); j++){ + for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, UE_id); j++){ free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]); } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index f47db710c4..0b41e4a479 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1209,106 +1209,158 @@ void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_fra /*********** PDCP *************/ /*PDCP super frame counter flexRAN*/ -uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){ + +/* TODO the following is a hack. all the functions below should instead already + * receive the PDCP's uid and operate on it and the caller has the obligation + * to get the ID for this layer. + */ +static inline uint16_t flexran_get_pdcp_uid(mid_t mod_id, mid_t ue_id) +{ + rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); + if (rnti == NOT_A_RNTI) return 0; + + for (uint16_t pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) { + if (pdcp_enb[mod_id].rnti[pdcp_uid] == rnti) + return pdcp_uid; + } + return 0; +} + +uint32_t flexran_get_pdcp_sfn(mid_t mod_id) +{ return pdcp_enb[mod_id].sfn; } /*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ +void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); if (obs_window > 0 ){ - Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window; + Pdcp_stats_tx_window_ms[mod_id][uid]=obs_window; } else{ - Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000; + Pdcp_stats_tx_window_ms[mod_id][uid]=1000; } } /*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ +void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); if (obs_window > 0 ){ - Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window; + Pdcp_stats_rx_window_ms[mod_id][uid]=obs_window; } else{ - Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000; + Pdcp_stats_rx_window_ms[mod_id][uid]=1000; } } /*PDCP num tx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - if (mod_id <0 || mod_id> MAX_NUM_CCs || ue_id<0 || ue_id> MAX_MOBILES_PER_ENB || lcid<0 || lcid>NB_RB_MAX) +uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + if (mod_id < 0 || mod_id > MAX_NUM_CCs || ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB + || lcid < 0 || lcid > NB_RB_MAX) return -1; - return Pdcp_stats_tx[mod_id][ue_id][lcid]; + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx[mod_id][uid][lcid]; } /*PDCP num tx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_bytes[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_bytes[mod_id][uid][lcid]; } /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_w[mod_id][uid][lcid]; } /*PDCP throughput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_bytes_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_bytes_w[mod_id][uid][lcid]; } /*PDCP tx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_sn[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_sn[mod_id][uid][lcid]; } /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_aiat[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_aiat[mod_id][uid][lcid]; } /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_aiat_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_aiat_w[mod_id][uid][lcid]; } - /*PDCP num rx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx[mod_id][uid][lcid]; } /*PDCP num rx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_bytes[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_bytes[mod_id][uid][lcid]; } /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_w[mod_id][uid][lcid]; } /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_bytes_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_bytes_w[mod_id][uid][lcid]; } /*PDCP rx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_sn[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_sn[mod_id][uid][lcid]; } /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_aiat[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_aiat[mod_id][uid][lcid]; } /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_aiat_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_aiat_w[mod_id][uid][lcid]; } /*PDCP num of received outoforder pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_outoforder[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_outoforder[mod_id][uid][lcid]; } /******************** RRC *****************************/ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index a9c9299398..37bdaae170 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -425,59 +425,59 @@ uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id); /***************************** PDCP ***********************/ /*PDCP superframe numberflexRAN*/ -uint32_t flexran_get_pdcp_sfn(const mid_t mod_id); +uint32_t flexran_get_pdcp_sfn(mid_t mod_id); /*PDCP pdcp tx stats window*/ -void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window); /*PDCP pdcp rx stats window*/ -void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window); /*PDCP num tx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num tx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP pdcp tx bytes in a given window flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP tx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP tx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num rx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num rx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP rx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP rx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num of received outoforder pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*********************RRC**********************/ /*Get primary cell measuremeant id flexRAN*/ From 77f2ffcdfb887f7543af94a25dcfba06d9cb9d03 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 7 Jun 2018 17:46:01 +0200 Subject: [PATCH 75/99] FlexRAN: call the agent_rrc_xface with the mod_id --- openair2/RRC/LTE/rrc_eNB.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 10590bc019..e62596aed6 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6658,7 +6658,7 @@ rrc_eNB_decode_dcch( //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); } @@ -6804,7 +6804,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (mac_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } @@ -6857,7 +6857,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } From 204281e3afe5666689b0dcea07a38f22546b4516 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 17 Jun 2018 13:48:39 +0200 Subject: [PATCH 76/99] change types in RCconfig_flexran(), avoid seg fault the integration of the nfapi-L2-emulator-for-develop (f254107b2) added more types in the RCconfig_flexran(), but they were partially wrong. This commit fixes those types after the rebase of this branch on top of 2018.w19 --- openair2/ENB_APP/enb_config.c | 87 +++++++++++++++++------------------ 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 195ab17877..6d9b2edf82 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -101,54 +101,51 @@ void RCconfig_flexran() ue_TimersAndConstants_t300, ue_TimersAndConstants_t301, ue_TimersAndConstants_t310, ue_TimersAndConstants_t311, ue_TimersAndConstants_n310, ue_TimersAndConstants_n311, - ue_TransmissionMode; + ue_TransmissionMode, ue_multiple_max; - int32_t ue_multiple_max = 0; - - e_SL_CP_Len_r12 rxPool_sc_CP_Len; - e_SL_PeriodComm_r12 rxPool_sc_Period; - e_SL_CP_Len_r12 rxPool_data_CP_Len; - long rxPool_ResourceConfig_prb_Num; - long rxPool_ResourceConfig_prb_Start; - long rxPool_ResourceConfig_prb_End; - SL_OffsetIndicator_r12_PR rxPool_ResourceConfig_offsetIndicator_present; - long rxPool_ResourceConfig_offsetIndicator_choice; - SubframeBitmapSL_r12_PR rxPool_ResourceConfig_subframeBitmap_present; - char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; - long rxPool_ResourceConfig_subframeBitmap_choice_bs_size; - long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - - //SIB19 - //for discRxPool - SL_CP_Len_r12_t discRxPool_cp_Len; - e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPool_discPeriod; - long discRxPool_numRetx; - long discRxPool_numRepetition; - long discRxPool_ResourceConfig_prb_Num; - long discRxPool_ResourceConfig_prb_Start; - long discRxPool_ResourceConfig_prb_End; - SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present; - long discRxPool_ResourceConfig_offsetIndicator_choice; - SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present; - char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; - long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; - long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - //for discRxPoolPS - SL_CP_Len_r12_t discRxPoolPS_cp_Len; - e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPoolPS_discPeriod; - long discRxPoolPS_numRetx; - long discRxPoolPS_numRepetition; - long discRxPoolPS_ResourceConfig_prb_Num; - long discRxPoolPS_ResourceConfig_prb_Start; - long discRxPoolPS_ResourceConfig_prb_End; - SL_OffsetIndicator_r12_PR discRxPoolPS_ResourceConfig_offsetIndicator_present; - long discRxPoolPS_ResourceConfig_offsetIndicator_choice; - SubframeBitmapSL_r12_PR discRxPoolPS_ResourceConfig_subframeBitmap_present; - char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; - long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; - long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + const char* rxPool_sc_CP_Len; + const char* rxPool_sc_Period; + const char* rxPool_data_CP_Len; + libconfig_int rxPool_ResourceConfig_prb_Num; + libconfig_int rxPool_ResourceConfig_prb_Start; + libconfig_int rxPool_ResourceConfig_prb_End; + const char* rxPool_ResourceConfig_offsetIndicator_present; + libconfig_int rxPool_ResourceConfig_offsetIndicator_choice; + const char* rxPool_ResourceConfig_subframeBitmap_present; + char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + //SIB19 + //for discRxPool + const char* discRxPool_cp_Len; + const char* discRxPool_discPeriod; + libconfig_int discRxPool_numRetx; + libconfig_int discRxPool_numRepetition; + libconfig_int discRxPool_ResourceConfig_prb_Num; + libconfig_int discRxPool_ResourceConfig_prb_Start; + libconfig_int discRxPool_ResourceConfig_prb_End; + const char* discRxPool_ResourceConfig_offsetIndicator_present; + libconfig_int discRxPool_ResourceConfig_offsetIndicator_choice; + const char* discRxPool_ResourceConfig_subframeBitmap_present; + char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + //for discRxPoolPS + const char* discRxPoolPS_cp_Len; + const char* discRxPoolPS_discPeriod; + libconfig_int discRxPoolPS_numRetx; + libconfig_int discRxPoolPS_numRepetition; + libconfig_int discRxPoolPS_ResourceConfig_prb_Num; + libconfig_int discRxPoolPS_ResourceConfig_prb_Start; + libconfig_int discRxPoolPS_ResourceConfig_prb_End; + const char* discRxPoolPS_ResourceConfig_offsetIndicator_present; + libconfig_int discRxPoolPS_ResourceConfig_offsetIndicator_choice; + const char* discRxPoolPS_ResourceConfig_subframeBitmap_present; + char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; /* get number of eNBs */ paramdef_t ENBSParams[] = ENBSPARAMS_DESC; From 3278aa494dcb68881be740668bf73b0df512734a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Jun 2018 15:20:30 +0200 Subject: [PATCH 77/99] Return immediately from pdcp_data_req When the RLC layer returns error codes (like dropped packets), this is still counted as PDCP layer traffic. In order to reflect dropped packets or malfunctioning, this patch makes that upon an RLC error code, the function is exited immediately. In this case, it is not counted as additional PDCP traffic. An example is too much UDP traffic. If the RLC buffer is saturated and the packet therefore refused, incoming traffic won't be counted anymore. With this patch, the PDCP layer statistics won't count such traffic anymore. --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 8b96542e33..135c6e73fa 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -399,27 +399,24 @@ boolean_t pdcp_data_req( case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; - break; + return FALSE; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; - break; + return FALSE; case RLC_OP_STATUS_OUT_OF_RESSOURCES: pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] = pdcp_enb[ctxt_pP->module_id].sfn; LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); int h = TM_SKIP_FULL_BUF_MS; LOG_W(PDCP, "Blocking incoming traffic for %d ms\n", h); - ret= FALSE; - break; + return FALSE; case RLC_OP_SKIPPED_FUL_BUF: LOG_D(PDCP, "Skipping RLC request due to full buffer\n"); - /* fake good return so that GTP doesn't spam us */ - ret = TRUE; - break; + /* fake good return so that GTP doesn't spam us and return immediately so + * that dropped traffic is not counted in PDCP traffic stats */ + return TRUE; default: LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); From 71a9115abdf819b8a0bc03e1657eb7aee5b26ece Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Jun 2018 15:25:29 +0200 Subject: [PATCH 78/99] Iterate over actual number of CC, not NFAPI_CC_MAX --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 16 ++++++++-------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 10 ++++------ openair2/LAYER2/MAC/pre_processor.c | 6 +++--- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 7a58cff2e5..80fd4ec370 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -510,7 +510,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } //weight = get_ue_weight(module_idP,UE_id); aggregation = 2; - for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); // get number of PRBs less those used by common channels @@ -559,7 +559,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, sort_UEs(module_idP, slice_idxP, frameP, subframeP); } - for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; @@ -1464,7 +1464,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // otherwise it contains the id of the slice it belongs to. // (Information about slicing must be retained to deal with isolation). // FIXME: This method does not consider RBGs that are free and belong to no slices - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { cc = &RC.mac[Mod_id]->common_channels[CC_id]; N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { @@ -1481,7 +1481,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // Find out which slices need other resources. // FIXME: I don't think is really needed since we check nb_rbs_remaining later - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { for (i = 0; i < sli->n_dl; ++i) { has_traffic[CC_id][i] = 0; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { @@ -1497,7 +1497,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // MULTIPLEXING // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); min_rb_unit = get_min_rb_unit(Mod_id, CC_id); @@ -1589,7 +1589,7 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ slice_info_t *sli = &RC.mac[Mod_id]->slice_info; //UE_sched_ctrl *ue_sched_ctl; - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { for (i = 0; i < sli->n_dl; ++i) { // Sort UE again @@ -1636,7 +1636,7 @@ fill_DLSCH_dci(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); - for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); if (mbsfn_flagP[CC_id] > 0) @@ -1866,7 +1866,7 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) start_meas(&eNB->schedule_pch); - for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { cc = &eNB->common_channels[CC_id]; vrb_map = (void *) &cc->vrb_map; n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 4618d363f9..937c561a21 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1006,12 +1006,10 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, break; } } + if (sched_subframe < subframeP) sched_frame++; - for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { - - - + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { //leave out first RB for PUCCH first_rb[CC_id] = 1; @@ -1090,7 +1088,7 @@ schedule_ulsch_rnti(module_id_t module_idP, nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); UE_list->first_rb_offset[CC_id][slice_idx] = cmin(N_RB_UL, sli->ul[slice_idx].first_rb); } @@ -1098,7 +1096,7 @@ schedule_ulsch_rnti(module_id_t module_idP, //LOG_D(MAC, "entering ulsch preprocesor\n"); ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_subframeP, first_rb); - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx]; } //LOG_D(MAC, "exiting ulsch preprocesor\n"); diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index a2c88674c8..124d3efbff 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -450,7 +450,7 @@ void decode_slice_positioning(module_id_t Mod_idP, int RBG, start_frequency, end_frequency; // Init slice_alloc_mask - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_idP]; ++CC_id) { for (RBG = 0; RBG < N_RBG_MAX; ++RBG) { slice_allocation_mask[CC_id][RBG] = 0; } @@ -458,7 +458,7 @@ void decode_slice_positioning(module_id_t Mod_idP, start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_low; end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_high; - for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_idP]; ++CC_id) { for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { slice_allocation_mask[CC_id][RBG] = 1; } @@ -1418,7 +1418,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, uint8_t *vrb_map; COMMON_channels_t *cc; // - for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id,(int)(UE_RNTI(module_idP, UE_id))); // initialize harq_pid and round From 08b122e3ff11febe097632e52cf88143cbdfbc84 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Jun 2018 15:34:15 +0200 Subject: [PATCH 79/99] FlexRAN: update slice config array dimensions --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 6 +++--- .../CONTROL_MODULES/MAC/flexran_agent_mac_internal.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 1732b39342..6cc3caced6 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -53,13 +53,13 @@ struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; /* the slice config as kept in the underlying system */ -Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB]; +Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; /* a structure that keeps updates which will be reflected in slice_config later */ -Protocol__FlexSliceConfig *sc_update[NUM_MAX_ENB]; +Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; /* indicates whether sc_update contains new data */ int perform_slice_config_update_count = 1; /* queue of incoming new UE<>slice association commands */ -Protocol__FlexUeConfig *ue_slice_assoc_update[NUM_MAX_UE]; +Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; int n_ue_slice_assoc_updates = 0; /* mutex for sc_update: do not receive new config and write it at the same time */ pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 1c2aef3baa..54b98ade20 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -34,10 +34,10 @@ #include "flexran_agent_mac_slice_verification.h" /* from flexran_agent_mac.c */ -extern Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB]; -extern Protocol__FlexSliceConfig *sc_update[NUM_MAX_ENB]; +extern Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; +extern Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; extern int perform_slice_config_update_count; -extern Protocol__FlexUeConfig *ue_slice_assoc_update[NUM_MAX_UE]; +extern Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; extern int n_ue_slice_assoc_updates; extern pthread_mutex_t sc_update_mtx; @@ -1574,7 +1574,7 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) { - if (n_ue_slice_assoc_updates == NUM_MAX_UE) { + if (n_ue_slice_assoc_updates == MAX_NUM_SLICES) { LOG_E(FLEXRAN_AGENT, "[%d] can not handle flex_ue_config message, buffer is full; try again later\n", mod_id); From 21983a202857f9a8b93d616cfa84d5f4c3a4be56 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 23 Jun 2018 12:23:57 +0200 Subject: [PATCH 80/99] Patch fairRR scheduler to use slice iface of pre-processor --- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 76589eebdb..8a9b4ce4df 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -542,6 +542,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, uint16_t temp_total_rbs_count; unsigned char temp_total_ue_count; unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; + uint8_t slice_allocation[MAX_NUM_CCs][N_RBG_MAX]; int UE_id, i; uint16_t j; uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -660,17 +661,22 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, transmission_mode = get_tmode(Mod_id,CC_id,UE_id); + /* slicing support has been introduced into the scheduler. Provide dummy + * data so that the preprocessor "simply works" */ + for (int i = 0; i < MAX_NUM_CCs; ++i) + for (int j = 0; i < N_RBG_MAX; ++j) + slice_allocation[i][j] = 1; + LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n "); dlsch_scheduler_pre_processor_allocate (Mod_id, UE_id, CC_id, N_RBG[CC_id], - transmission_mode, min_rb_unit[CC_id], - N_RB_DL, (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining, rballoc_sub, + slice_allocation, MIMO_mode_indicator); temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id]; temp_total_ue_count--; From e1a598bc8d53d448e390d5b01a3446680d1334e6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Aug 2018 12:03:24 +0200 Subject: [PATCH 81/99] Fix function parameter definition/order Affects: * store_dlsch_buffer() * assign_rbs_required() --- openair2/LAYER2/MAC/mac_proto.h | 4 ++-- openair2/LAYER2/MAC/pre_processor.c | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 0d4cd72ae9..e0fdade419 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -700,8 +700,8 @@ int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti, int harq_pid ); int rrc_mac_remove_ue(module_id_t Mod_id, rnti_t rntiP); -void store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP); -void assign_rbs_required(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], int min_rb_unit[NFAPI_CC_MAX]); +void store_dlsch_buffer(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframeP); +void assign_rbs_required(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], int min_rb_unit[NFAPI_CC_MAX]); int maxround(module_id_t Mod_id, uint16_t rnti, int frame, sub_frame_t subframe, uint8_t ul_flag); diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 124d3efbff..4c7146a41c 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -177,8 +177,8 @@ assign_rbs_required(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframe, - int min_rb_unit[NFAPI_CC_MAX], - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + int min_rb_unit[NFAPI_CC_MAX]) { uint16_t TBS = 0; @@ -1279,9 +1279,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, store_dlsch_buffer(Mod_id, slice_idx, frameP, subframeP); // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, slice_idx, frameP, subframeP, - min_rb_unit, - nb_rbs_required); + assign_rbs_required(Mod_id, slice_idx, frameP, subframeP, nb_rbs_required, min_rb_unit); // Sorts the user on the basis of dlsch logical channel buffer and CQI sort_UEs(Mod_id, slice_idx, frameP, subframeP); From 972f52fd56197ade1bac1338561ec031cb4c3eed Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Aug 2018 12:44:44 +0200 Subject: [PATCH 82/99] fix remove LOG_N in restart --- openair2/ENB_APP/enb_app.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 1289cf59b5..7cb0550ed1 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -335,7 +335,7 @@ void handle_reconfiguration(module_id_t mod_id) clock_gettime(CLOCK_MONOTONIC, &start); flexran_agent_info_t *flexran = RC.flexran[mod_id]; - LOG_N(ENB_APP, "lte-softmodem soft-restart requested\n"); + LOG_I(ENB_APP, "lte-softmodem soft-restart requested\n"); if (ENB_WAIT == flexran->node_ctrl_state) { /* this is already waiting, just release */ @@ -354,7 +354,7 @@ void handle_reconfiguration(module_id_t mod_id) /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not * executed by the FlexRAN thread */ if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { - LOG_N(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); pthread_mutex_lock(&flexran->mutex_node_ctrl); flexran->node_ctrl_state = ENB_WAIT; while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) @@ -376,5 +376,5 @@ void handle_reconfiguration(module_id_t mod_id) end.tv_sec -= 1; end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; } - LOG_N(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); + LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); } From 49b167d6aedf5a00d40f8233c31a2a5f53921749 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Aug 2018 12:04:39 +0200 Subject: [PATCH 83/99] Remove warnings pre_processor --- openair2/LAYER2/MAC/pre_processor.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 4c7146a41c..8b33cae488 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1401,8 +1401,8 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, int UE_id; uint8_t CC_id; int i, j; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_list_t *UE_list; + UE_sched_ctrl *ue_sched_ctl; int N_RB_DL, RBGsize, RBGsize_last; int N_RBG[NFAPI_CC_MAX]; @@ -1411,8 +1411,6 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, #endif rnti_t rnti; - UE_list_t *UE_list; - UE_sched_ctrl *ue_sched_ctl; uint8_t *vrb_map; COMMON_channels_t *cc; // From 07ad2470d13ec87a756015306ee74bda771afc80 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Aug 2018 15:55:53 +0200 Subject: [PATCH 84/99] Remove warnings pre_processor_fairRR --- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 8a9b4ce4df..693623c116 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -555,8 +555,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, uint8_t CC_id; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - int N_RB_DL; - int transmission_mode = 0; UE_sched_ctrl *ue_sched_ctl; // int rrc_status = RRC_IDLE; COMMON_channels_t *cc; @@ -591,14 +589,14 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, + 0, frameP, subframeP, - N_RBG[CC_id], + min_rb_unit, (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, rballoc_sub, - MIMO_mode_indicator); + MIMO_mode_indicator, + mbsfn_flag); } } @@ -622,7 +620,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, average_rbs_per_user[CC_id] = 0; cc = &RC.mac[Mod_id]->common_channels[CC_id]; // Get total available RBS count and total UE count - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); temp_total_rbs_count = RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs; temp_total_ue_count = dlsch_ue_select[CC_id].ue_num; @@ -659,8 +656,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, nb_rbs_required_remaining[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], dlsch_ue_select[CC_id].list[i].nb_rb); } - transmission_mode = get_tmode(Mod_id,CC_id,UE_id); - /* slicing support has been introduced into the scheduler. Provide dummy * data so that the preprocessor "simply works" */ for (int i = 0; i < MAX_NUM_CCs; ++i) From 9f0461430489ad47ec70ae730ececa71bed8c59b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Aug 2018 16:30:31 +0200 Subject: [PATCH 85/99] Remove huge comment from sort_UEs() Commit 7823858e2d11e8cabc1ca7bf7f507b9a050942d3 introduced this as a comment. --- openair2/LAYER2/MAC/pre_processor.c | 72 ----------------------------- 1 file changed, 72 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 8b33cae488..37a7b47000 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -499,78 +499,6 @@ void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subfra } else { UE_list->head = -1; } - -#if 0 - - - int UE_id1, UE_id2; - int pCC_id1, pCC_id2; - int cqi1, cqi2, round1, round2; - int i = 0, ii = 0; //,j=0; - rnti_t rnti1, rnti2; - - UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - - for (ii = UE_list->next[i]; ii >= 0; ii = UE_list->next[ii]) { - - UE_id1 = i; - rnti1 = UE_RNTI(Mod_idP, UE_id1); - if (rnti1 == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1) - continue; - pCC_id1 = UE_PCCID(Mod_idP, UE_id1); - cqi1 = maxcqi(Mod_idP, UE_id1); // - round1 = maxround(Mod_idP, rnti1, frameP, subframeP, 0); - - UE_id2 = ii; - rnti2 = UE_RNTI(Mod_idP, UE_id2); - if (rnti2 == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1) - continue; - cqi2 = maxcqi(Mod_idP, UE_id2); - round2 = maxround(Mod_idP, rnti2, frameP, subframeP, 0); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0); - pCC_id2 = UE_PCCID(Mod_idP, UE_id2); - - if (round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order - swap_UEs(UE_list, UE_id1, UE_id2, 0); - } else if (round2 == round1) { - // RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service. - // for(j=0;jUE_template[pCC_id1][UE_id1]. - dl_buffer_info[1] + - UE_list->UE_template[pCC_id1][UE_id1]. - dl_buffer_info[2]) < - (UE_list->UE_template[pCC_id2][UE_id2]. - dl_buffer_info[1] + - UE_list->UE_template[pCC_id2][UE_id2]. - dl_buffer_info[2])) { - swap_UEs(UE_list, UE_id1, UE_id2, 0); - } else if (UE_list->UE_template[pCC_id1] - [UE_id1].dl_buffer_head_sdu_creation_time_max < - UE_list->UE_template[pCC_id2] - [UE_id2].dl_buffer_head_sdu_creation_time_max) { - swap_UEs(UE_list, UE_id1, UE_id2, 0); - } else if (UE_list->UE_template[pCC_id1][UE_id1]. - dl_buffer_total < - UE_list->UE_template[pCC_id2][UE_id2]. - dl_buffer_total) { - swap_UEs(UE_list, UE_id1, UE_id2, 0); - } else if (cqi1 < cqi2) { - swap_UEs(UE_list, UE_id1, UE_id2, 0); - } - } - } - } -#endif } void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, From 1f60f4ecea17668d719e7900d56cb9da92cd797e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 16 Aug 2018 14:38:04 +0200 Subject: [PATCH 86/99] Log Level Debug for Freeing Transport Channel Msg --- targets/RT/USER/lte-enb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 87aa874227..fc60922bc1 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1120,10 +1120,10 @@ void free_transport(PHY_VARS_eNB *eNB) int j; for (i=0; idlsch[i][j]); - LOG_I(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); + LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); free_eNB_ulsch(eNB->ulsch[1+i]); } free_eNB_ulsch(eNB->ulsch[0]); From d3afce4f3c53f6f8d0cb7a7587291c8e517eaac0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 16 Aug 2018 14:40:13 +0200 Subject: [PATCH 87/99] Print detailed info why mutex locking failed --- openair1/PHY/defs_common.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index fce7f1b885..4de7456410 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -994,9 +994,10 @@ static inline void wait_sync(char *thread_name) { } static inline int wakeup_thread(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "wakeup_thread(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } @@ -1013,8 +1014,10 @@ static inline int wakeup_thread(pthread_mutex_t *mutex,pthread_cond_t *cond,int } static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "[SCHED][eNB] wait_on_condition(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } @@ -1034,9 +1037,10 @@ static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond, } static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "[SCHED][eNB] wait_on_busy_condition(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } @@ -1056,9 +1060,10 @@ static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t * } static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "[SCHED][eNB] release_thread(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } From c1b024d3541ab7136072baeaf327d1adea86fb52 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 16 Aug 2018 14:41:50 +0200 Subject: [PATCH 88/99] stop_L1L2(): Do not turn of RF, is done in ru_thread --- targets/RT/USER/lte-softmodem.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index b606ee2f46..6fd5b78512 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -771,25 +771,6 @@ int stop_L1L2(module_id_t enb_id) return -1; } - /* stop trx devices, multiple carrier currently not supported by RU */ - if (RC.ru[enb_id]) { - if (RC.ru[enb_id]->rfdevice.trx_stop_func) { - RC.ru[enb_id]->rfdevice.trx_stop_func(&RC.ru[enb_id]->rfdevice); - LOG_I(ENB_APP, "turned off RU rfdevice\n"); - } else { - LOG_W(ENB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceding anyway!\n"); - } - if (RC.ru[enb_id]->ifdevice.trx_stop_func) { - RC.ru[enb_id]->ifdevice.trx_stop_func(&RC.ru[enb_id]->ifdevice); - LOG_I(ENB_APP, "turned off RU ifdevice\n"); - } else { - LOG_W(ENB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceding anyway!\n"); - } - } else { - LOG_W(ENB_APP, "no RU found for index %d\n", enb_id); - return -1; - } - /* these tasks need to pick up new configuration */ terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); terminate_task(enb_id, TASK_ENB_APP, TASK_L2L1); From 5a1e8c2869223f8af6cbeac9dd489263bc1af6a7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 16 Aug 2018 14:42:12 +0200 Subject: [PATCH 89/99] Lock sync_var access in restart_L1L2() --- targets/RT/USER/lte-softmodem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 6fd5b78512..d661e1e31c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -801,7 +801,9 @@ int restart_L1L2(module_id_t enb_id) LOG_W(ENB_APP, "restarting lte-softmodem\n"); /* block threads */ + pthread_mutex_lock(&sync_mutex); sync_var = -1; + pthread_mutex_unlock(&sync_mutex); for (cc_id = 0; cc_id < RC.nb_L1_CC[enb_id]; cc_id++) { RC.eNB[enb_id][cc_id]->configured = 0; From af83d352c8f4a260118dcb5d23b1d9a8aad95ac3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 16 Aug 2018 17:19:05 +0200 Subject: [PATCH 90/99] Fix: use frame_subframe2_dl_harq_pid() --- openair2/LAYER2/MAC/pre_processor.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 37a7b47000..53e837d787 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -578,11 +578,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; - // FIXME: Can we use subframe2harqpid() here? - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; if (nb_rbs_required[CC_id][UE_id] > 0) { From fa27b6dcce5d079eb136874cb55463d0d504d894 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 17 Aug 2018 11:10:14 +0200 Subject: [PATCH 91/99] Fix: Correct numbering of protobuf messages (as in RTC) --- openair2/ENB_APP/MESSAGES/V2/config_messages.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 0dd5140efa..1d5da8dd2a 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -50,10 +50,10 @@ message flex_cell_config { message flex_slice_config { // whether remaining RBs after first intra-slice allocation will // be allocated to UEs of the same slice - optional bool intraslice_share_active = 4; + optional bool intraslice_share_active = 3; // whether remaining RBs after slice allocation will be allocated // to UEs of another slice. Isolated slices will be ignored. - optional bool interslice_share_active = 3; + optional bool interslice_share_active = 4; repeated flex_dl_slice dl = 1; repeated flex_ul_slice ul = 2; } From ff83dc70171da26c1489234334bcc7eec34cdaee Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 16 Aug 2018 17:19:39 +0200 Subject: [PATCH 92/99] Fix greedy allocation: schedule not more than what slice has --- openair2/LAYER2/MAC/pre_processor.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 53e837d787..1befe8e8c3 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -543,7 +543,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, rnti_t rnti; uint8_t harq_pid, round; - uint16_t available_rbs; + uint16_t available_rbs[NFAPI_CC_MAX]; uint8_t rbs_retx[NFAPI_CC_MAX]; uint16_t average_rbs_per_user[NFAPI_CC_MAX]; int total_ue_count[NFAPI_CC_MAX]; @@ -562,6 +562,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ue_count_retx[CC_id] = 0; rbs_retx[CC_id] = 0; average_rbs_per_user[CC_id] = 0; + available_rbs[CC_id] = 0; //for (UE_id = 0; UE_id < NFAPI_CC_MAX; ++UE_id) { // ue_retx_flag[CC_id][UE_id] = 0; //} @@ -600,10 +601,18 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Reduces the available RBs according to slicing configuration dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_idx, rbs_retx); + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { + if (UE_list->head < 0) continue; // no UEs in list + // max_rbs_allowed_slice is saved in every UE, so take it from the first one + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_list->head]; + available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; + } + switch (RC.mac[Mod_id]->slice_info.dl[slice_idx].accounting) { // If greedy scheduling, try to account all the required RBs case POL_GREEDY: + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; @@ -612,7 +621,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; - nb_rbs_accounted[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; + if (available_rbs[CC_id] == 0) continue; + nb_rbs_accounted[CC_id][UE_id] = cmin(nb_rbs_required[CC_id][UE_id], available_rbs[CC_id]); + available_rbs[CC_id] -= nb_rbs_accounted[CC_id][UE_id]; } } break; @@ -634,12 +645,12 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - available_rbs = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; + available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; if (ue_count_newtx[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; - } else if (min_rb_unit[CC_id]*ue_count_newtx[CC_id] <= available_rbs) { - average_rbs_per_user[CC_id] = (uint16_t)floor(available_rbs/ue_count_newtx[CC_id]); + } else if (min_rb_unit[CC_id]*ue_count_newtx[CC_id] <= available_rbs[CC_id]) { + average_rbs_per_user[CC_id] = (uint16_t)floor(available_rbs[CC_id]/ue_count_newtx[CC_id]); } else { // consider the total number of use that can be scheduled UE average_rbs_per_user[CC_id] = (uint16_t)min_rb_unit[CC_id]; From f86b51990cbf7b7b1c14d1a5a882c64d869c42d2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 31 Aug 2018 16:08:18 +0200 Subject: [PATCH 93/99] restart: first stop RU, then eNB proc threads --- targets/RT/USER/lte-softmodem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index d661e1e31c..e6e2d5a32c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -775,10 +775,10 @@ int stop_L1L2(module_id_t enb_id) terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); terminate_task(enb_id, TASK_ENB_APP, TASK_L2L1); oai_exit = 1; - LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); - kill_eNB_proc(enb_id); LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); kill_RU_proc(RC.ru[enb_id]); + LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); + kill_eNB_proc(enb_id); oai_exit = 0; for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) { free_transport(RC.eNB[enb_id][cc_id]); From d798e03e9d97ed164c7111da01635629e97f9ac8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Sep 2018 16:38:41 +0200 Subject: [PATCH 94/99] fix rb_table loop --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 937c561a21..5420cfdede 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1309,7 +1309,7 @@ schedule_ulsch_rnti(module_id_t module_idP, // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index] > (N_RB_UL - 1 - first_rb_slice[CC_id])) + while (((rb_table[rb_table_index] > (N_RB_UL - first_rb_slice[CC_id])) || (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) { rb_table_index--; From 066ab904027781c2746f5de17c5e311bfae99001 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Sep 2018 16:39:24 +0200 Subject: [PATCH 95/99] Bugfix: Give correct first_rb value to UE --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 5420cfdede..b10ff88964 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1410,7 +1410,7 @@ schedule_ulsch_rnti(module_id_t module_idP, } // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb_slice[CC_id], // resource_block_start rb_table[rb_table_index], // number_of_resource_blocks UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms 0, // frequency_hopping_enabled_flag From 7162bf6895464bb4666769173c45862b667ce27a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 4 Sep 2018 16:39:56 +0200 Subject: [PATCH 96/99] Bugfix: Assure available_rbs is positive --- openair2/LAYER2/MAC/pre_processor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 1befe8e8c3..5846720c7f 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1696,6 +1696,8 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); + if (available_rbs < 0) + available_rbs = 0; if (total_ue_count[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; From cbc78cd3db009de9c5e5730d64fba7a1f74b1be8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 5 Sep 2018 10:48:29 +0200 Subject: [PATCH 97/99] Don't warn of ignoring sorting --- .../CONTROL_MODULES/MAC/flexran_agent_mac_internal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 54b98ade20..8e0dc57269 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1550,12 +1550,12 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); changes++; } - if (check_ul_sorting_update(oldc, newc)) { - /*flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); - changes++;*/ + /*if (check_ul_sorting_update(oldc, newc)) { + flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); + changes++; LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", mod_id, newc->id); - } + }*/ if (oldc->accounting != newc->accounting) { /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting); *changes++;*/ From 70e1841bb1e985b42a198a9aca2033ec0dba20d6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 5 Sep 2018 10:49:44 +0200 Subject: [PATCH 98/99] Fix: RAN API: remove_ul_slice() frees ul sched_name pointer, when sched_name set, free it when resetting --- openair2/ENB_APP/flexran_agent_ran_api.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 0b41e4a479..973d322a5f 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1756,6 +1756,8 @@ char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { if (!mac_is_present(mod_id)) return 0; + if (RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name) + free(RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name); RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name); RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name); return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL; @@ -1788,7 +1790,7 @@ int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) slice_info_t *sli = &RC.mac[mod_id]->slice_info; if (sli->n_ul <= 1) return -1; - if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name); + if (sli->ul[slice_idx].sched_name) free(sli->ul[slice_idx].sched_name); --sli->n_ul; /* move last element to the position of the removed one */ if (slice_idx != sli->n_ul) @@ -1869,6 +1871,8 @@ char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { if (!mac_is_present(mod_id)) return 0; + if (RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name) + free(RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name); RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name); RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name); return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL; From c1359a103f47aeb790b8c0330c70da9451c1ed7b Mon Sep 17 00:00:00 2001 From: Masayuki HARADA Date: Thu, 6 Sep 2018 19:00:32 +0200 Subject: [PATCH 99/99] Fix wrong slice_allocation loop in fairRR scheduler --- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 693623c116..deb9a22df9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -544,7 +544,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; uint8_t slice_allocation[MAX_NUM_CCs][N_RBG_MAX]; int UE_id, i; - uint16_t j; + uint16_t j,c; uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -658,9 +658,9 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, /* slicing support has been introduced into the scheduler. Provide dummy * data so that the preprocessor "simply works" */ - for (int i = 0; i < MAX_NUM_CCs; ++i) - for (int j = 0; i < N_RBG_MAX; ++j) - slice_allocation[i][j] = 1; + for (c = 0; c < MAX_NUM_CCs; ++c) + for (j = 0; j < N_RBG_MAX; ++j) + slice_allocation[c][j] = 1; LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n "); dlsch_scheduler_pre_processor_allocate (Mod_id,