add support for RAN/radio resource slicing through flexran
This commit is contained in:
@@ -145,6 +145,9 @@
|
|||||||
/*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */
|
/*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */
|
||||||
#define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE)
|
#define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE)
|
||||||
|
|
||||||
|
/*!\brief maximum number of slices / groups */
|
||||||
|
#define MAX_NUM_SLICES 4
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* eNB part
|
* eNB part
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
/*! \file flexran_agent_mac_proto.h
|
/*! \file flexran_agent_mac_proto.h
|
||||||
* \brief MAC functions for FlexRAN agent
|
* \brief MAC functions for FlexRAN agent
|
||||||
* \author Xenofon Foukas
|
* \author Xenofon Foukas and Navid Nikaein
|
||||||
* \date 2016
|
* \date 2016
|
||||||
* \email: x.foukas@sms.ed.ac.uk
|
* \email: x.foukas@sms.ed.ac.uk
|
||||||
* \version 0.1
|
* \version 0.1
|
||||||
@@ -36,6 +36,145 @@
|
|||||||
#include "header.pb-c.h"
|
#include "header.pb-c.h"
|
||||||
#include "flexran.pb-c.h"
|
#include "flexran.pb-c.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* slice specific scheduler
|
||||||
|
*/
|
||||||
|
typedef void (*slice_scheduler)(module_id_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* top level flexran scheduler used by the eNB scheduler
|
||||||
|
*/
|
||||||
|
void flexran_schedule_ue_spec_default(mid_t mod_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info);
|
||||||
|
/*
|
||||||
|
* slice specific scheduler for embb
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_embb(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info);
|
||||||
|
/*
|
||||||
|
* slice specific scheduler for urllc
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_urllc(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* slice specific scheduler for mmtc
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_mmtc(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info);
|
||||||
|
/*
|
||||||
|
* slice specific scheduler for best effort traffic
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_be(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* common flexran scheduler function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info);
|
||||||
|
|
||||||
|
uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage,
|
||||||
|
int total_rbs);
|
||||||
|
|
||||||
|
int flexran_slice_member(int UE_id,
|
||||||
|
int slice_id);
|
||||||
|
|
||||||
|
int flexran_slice_maxmcs(int slice_id) ;
|
||||||
|
|
||||||
|
void _store_dlsch_buffer (module_id_t Mod_id,
|
||||||
|
int slice_id,
|
||||||
|
frame_t frameP,
|
||||||
|
sub_frame_t subframeP);
|
||||||
|
|
||||||
|
|
||||||
|
void _assign_rbs_required (module_id_t Mod_id,
|
||||||
|
int slice_id,
|
||||||
|
frame_t frameP,
|
||||||
|
sub_frame_t subframe,
|
||||||
|
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
||||||
|
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES],
|
||||||
|
int min_rb_unit[MAX_NUM_CCs]);
|
||||||
|
|
||||||
|
int _maxround(module_id_t Mod_id,
|
||||||
|
uint16_t rnti,
|
||||||
|
int frame,
|
||||||
|
sub_frame_t subframe,
|
||||||
|
uint8_t ul_flag );
|
||||||
|
|
||||||
|
int _maxcqi(module_id_t Mod_id,
|
||||||
|
int32_t UE_id);
|
||||||
|
|
||||||
|
void _sort_UEs (module_id_t Mod_idP,
|
||||||
|
int frameP,
|
||||||
|
sub_frame_t subframeP);
|
||||||
|
|
||||||
|
void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||||
|
int slice_id,
|
||||||
|
frame_t frameP,
|
||||||
|
sub_frame_t subframeP,
|
||||||
|
int N_RBG[MAX_NUM_CCs],
|
||||||
|
int *mbsfn_flag);
|
||||||
|
|
||||||
|
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[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
||||||
|
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
||||||
|
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES],
|
||||||
|
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
|
||||||
|
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][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 transmission_mode,
|
||||||
|
int min_rb_unit,
|
||||||
|
uint8_t N_RB_DL,
|
||||||
|
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],
|
||||||
|
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
|
||||||
|
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default scheduler used by the eNB agent
|
* Default scheduler used by the eNB agent
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
#include "header.pb-c.h"
|
#include "header.pb-c.h"
|
||||||
#include "flexran.pb-c.h"
|
#include "flexran.pb-c.h"
|
||||||
#include "flexran_agent_mac.h"
|
#include "flexran_agent_mac.h"
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include "SIMULATION/TOOLS/defs.h" // for taus
|
#include "SIMULATION/TOOLS/defs.h" // for taus
|
||||||
|
|
||||||
@@ -65,8 +66,67 @@
|
|||||||
|
|
||||||
#define ENABLE_MAC_PAYLOAD_DEBUG
|
#define ENABLE_MAC_PAYLOAD_DEBUG
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local variables to support slicing
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!\brief UE ULSCH scheduling states*/
|
||||||
|
typedef enum {
|
||||||
|
MIN_SLICE_STRATEGY = 0,
|
||||||
|
SLICE_MASK,
|
||||||
|
UEID_TO_SLICEID,
|
||||||
|
MAX_SLICE_STRATEGY
|
||||||
|
} SLICING_STRATEGY;
|
||||||
|
|
||||||
|
// this assumes a max of of 16 UE per eNB/CC
|
||||||
|
#define SLICE0_MASK 0x000f
|
||||||
|
#define SLICE1_MASK 0x00f0
|
||||||
|
#define SLICE2_MASK 0x0f00
|
||||||
|
#define SLICE3_MASK 0xf000
|
||||||
|
|
||||||
|
|
||||||
|
// number of active slices for past and current time
|
||||||
|
int n_active_slices = 1;
|
||||||
|
int n_active_slices_current = 1;
|
||||||
|
|
||||||
|
// ue to slice mapping
|
||||||
|
int slicing_strategy = UEID_TO_SLICEID;
|
||||||
|
int slicing_strategy_current = UEID_TO_SLICEID;
|
||||||
|
|
||||||
|
// 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 total_slice_percentage = 0;
|
||||||
|
|
||||||
|
// 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, 0, 0, 0};
|
||||||
|
int update_dl_scheduler_current[MAX_NUM_SLICES] = {1, 0, 0, 0};
|
||||||
|
|
||||||
|
// name of available scheduler
|
||||||
|
char *dl_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_spec_embb",
|
||||||
|
"flexran_schedule_ue_spec_urllc",
|
||||||
|
"flexran_schedule_ue_spec_mmtc",
|
||||||
|
"flexran_schedule_ue_spec_be" // best effort
|
||||||
|
};
|
||||||
|
|
||||||
|
// pointer to the slice specific scheduler
|
||||||
|
slice_scheduler slice_sched[MAX_NUM_SLICES] = {0};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* preprocessor functions for scheduling
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// This function stores the downlink buffer for all the logical channels
|
// This function stores the downlink buffer for all the logical channels
|
||||||
void _store_dlsch_buffer (module_id_t Mod_id,
|
void _store_dlsch_buffer (module_id_t Mod_id,
|
||||||
|
int slice_id,
|
||||||
frame_t frameP,
|
frame_t frameP,
|
||||||
sub_frame_t subframeP)
|
sub_frame_t subframeP)
|
||||||
{
|
{
|
||||||
@@ -79,6 +139,9 @@ void _store_dlsch_buffer (module_id_t Mod_id,
|
|||||||
|
|
||||||
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
|
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
|
||||||
|
|
||||||
|
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||||
|
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
|
// clear logical channel interface variables
|
||||||
@@ -114,8 +177,8 @@ void _store_dlsch_buffer (module_id_t Mod_id,
|
|||||||
*/
|
*/
|
||||||
if (UE_template->dl_buffer_info[i]>0)
|
if (UE_template->dl_buffer_info[i]>0)
|
||||||
LOG_D(MAC,
|
LOG_D(MAC,
|
||||||
"[eNB %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",
|
"[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, frameP, subframeP, UE_id,
|
Mod_id, slice_id,frameP, subframeP, UE_id,
|
||||||
i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i],
|
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_creation_time[i],
|
||||||
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i],
|
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i],
|
||||||
@@ -141,10 +204,12 @@ void _store_dlsch_buffer (module_id_t Mod_id,
|
|||||||
|
|
||||||
// This function returns the estimated number of RBs required by each UE for downlink scheduling
|
// This function returns the estimated number of RBs required by each UE for downlink scheduling
|
||||||
void _assign_rbs_required (module_id_t Mod_id,
|
void _assign_rbs_required (module_id_t Mod_id,
|
||||||
frame_t frameP,
|
int slice_id,
|
||||||
sub_frame_t subframe,
|
frame_t frameP,
|
||||||
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
sub_frame_t subframe,
|
||||||
int min_rb_unit[MAX_NUM_CCs])
|
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
||||||
|
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES],
|
||||||
|
int min_rb_unit[MAX_NUM_CCs])
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@@ -157,6 +222,10 @@ void _assign_rbs_required (module_id_t Mod_id,
|
|||||||
|
|
||||||
// clear rb allocations across all CC_ids
|
// clear rb allocations across all CC_ids
|
||||||
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
|
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
|
||||||
|
|
||||||
|
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
pCCid = UE_PCCID(Mod_id,UE_id);
|
pCCid = UE_PCCID(Mod_id,UE_id);
|
||||||
rnti = UE_list->UE_template[pCCid][UE_id].rnti;
|
rnti = UE_list->UE_template[pCCid][UE_id].rnti;
|
||||||
|
|
||||||
@@ -198,7 +267,8 @@ void _assign_rbs_required (module_id_t Mod_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
|
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
|
||||||
|
nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],
|
||||||
|
flexran_get_N_RB_DL(Mod_id, CC_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",
|
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,
|
UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
|
||||||
nb_rbs_required[CC_id][UE_id],eNB_UE_stats[CC_id]->dlsch_mcs1,TBS);
|
nb_rbs_required[CC_id][UE_id],eNB_UE_stats[CC_id]->dlsch_mcs1,TBS);
|
||||||
@@ -207,17 +277,17 @@ void _assign_rbs_required (module_id_t Mod_id,
|
|||||||
while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) {
|
while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) {
|
||||||
nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
|
nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
|
||||||
|
|
||||||
if (nb_rbs_required[CC_id][UE_id] > flexran_get_N_RB_DL(Mod_id, CC_id)) {
|
if (nb_rbs_required[CC_id][UE_id] > nb_rbs_allowed_slice[CC_id][slice_id]) {
|
||||||
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1, flexran_get_N_RB_DL(Mod_id, CC_id));
|
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1, nb_rbs_allowed_slice[CC_id][slice_id]);
|
||||||
nb_rbs_required[CC_id][UE_id] = flexran_get_N_RB_DL(Mod_id, CC_id);
|
nb_rbs_required[CC_id][UE_id] = nb_rbs_allowed_slice[CC_id][slice_id];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
|
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
|
||||||
} // end of while
|
} // 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",
|
LOG_D(MAC,"[eNB %d][SLICE %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[CC_id]->dlsch_mcs1);
|
Mod_id, slice_id,frameP,UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats[CC_id]->dlsch_mcs1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,6 +461,7 @@ void _dlsch_scheduler_pre_processor_reset (int module_idP,
|
|||||||
int N_RBG,
|
int N_RBG,
|
||||||
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
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[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
||||||
|
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES],
|
||||||
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
|
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
|
||||||
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) {
|
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) {
|
||||||
int i,j;
|
int i,j;
|
||||||
@@ -413,7 +484,8 @@ void _dlsch_scheduler_pre_processor_reset (int module_idP,
|
|||||||
ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
|
ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
|
||||||
ue_sched_ctl->dl_pow_off[CC_id] = 2;
|
ue_sched_ctl->dl_pow_off[CC_id] = 2;
|
||||||
nb_rbs_required_remaining[CC_id][UE_id] = 0;
|
nb_rbs_required_remaining[CC_id][UE_id] = 0;
|
||||||
|
for (i=0; i<n_active_slices;i++)
|
||||||
|
nb_rbs_allowed_slice[CC_id][i] = 0;
|
||||||
#ifdef SF05_LIMIT
|
#ifdef SF05_LIMIT
|
||||||
switch (N_RBG) {
|
switch (N_RBG) {
|
||||||
case 6:
|
case 6:
|
||||||
@@ -464,10 +536,11 @@ void _dlsch_scheduler_pre_processor_reset (int module_idP,
|
|||||||
|
|
||||||
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
|
// 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,
|
void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||||
frame_t frameP,
|
int slice_id,
|
||||||
sub_frame_t subframeP,
|
frame_t frameP,
|
||||||
int N_RBG[MAX_NUM_CCs],
|
sub_frame_t subframeP,
|
||||||
int *mbsfn_flag)
|
int N_RBG[MAX_NUM_CCs],
|
||||||
|
int *mbsfn_flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid=0, total_ue_count;
|
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid=0, total_ue_count;
|
||||||
@@ -476,6 +549,7 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
unsigned char round = 0;
|
unsigned char round = 0;
|
||||||
uint16_t ii,j;
|
uint16_t ii,j;
|
||||||
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||||
|
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES];
|
||||||
uint16_t nb_rbs_required_remaining[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];
|
uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||||
uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0};
|
uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0};
|
||||||
@@ -489,6 +563,7 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
int transmission_mode = 0;
|
int transmission_mode = 0;
|
||||||
UE_sched_ctrl *ue_sched_ctl;
|
UE_sched_ctrl *ue_sched_ctl;
|
||||||
|
|
||||||
|
|
||||||
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||||
|
|
||||||
if (mbsfn_flag[CC_id]>0) // If this CC is allocated for MBSFN skip it here
|
if (mbsfn_flag[CC_id]>0) // If this CC is allocated for MBSFN skip it here
|
||||||
@@ -503,7 +578,8 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
UE_id = i;
|
UE_id = i;
|
||||||
// Initialize scheduling information for all active UEs
|
// Initialize scheduling information for all active UEs
|
||||||
|
|
||||||
|
//if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||||
|
//continue;
|
||||||
_dlsch_scheduler_pre_processor_reset(Mod_id,
|
_dlsch_scheduler_pre_processor_reset(Mod_id,
|
||||||
UE_id,
|
UE_id,
|
||||||
CC_id,
|
CC_id,
|
||||||
@@ -512,6 +588,7 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
N_RBG[CC_id],
|
N_RBG[CC_id],
|
||||||
nb_rbs_required,
|
nb_rbs_required,
|
||||||
nb_rbs_required_remaining,
|
nb_rbs_required_remaining,
|
||||||
|
nb_rbs_allowed_slice,
|
||||||
rballoc_sub,
|
rballoc_sub,
|
||||||
MIMO_mode_indicator);
|
MIMO_mode_indicator);
|
||||||
|
|
||||||
@@ -519,10 +596,10 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store the DLSCH buffer for each logical channel
|
// Store the DLSCH buffer for each logical channel
|
||||||
_store_dlsch_buffer (Mod_id,frameP,subframeP);
|
_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
|
// Calculate the number of RBs required by each UE on the basis of logical channel's buffer
|
||||||
_assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required,min_rb_unit);
|
_assign_rbs_required (Mod_id,slice_id, frameP,subframeP,nb_rbs_required,nb_rbs_allowed_slice,min_rb_unit);
|
||||||
|
|
||||||
// Sorts the user on the basis of dlsch logical channel buffer and CQI
|
// Sorts the user on the basis of dlsch logical channel buffer and CQI
|
||||||
_sort_UEs (Mod_id,frameP,subframeP);
|
_sort_UEs (Mod_id,frameP,subframeP);
|
||||||
@@ -538,6 +615,9 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
continue;
|
continue;
|
||||||
UE_id = i;
|
UE_id = i;
|
||||||
|
|
||||||
|
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
// if there is no available harq_process, skip the UE
|
// if there is no available harq_process, skip the UE
|
||||||
if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
|
if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
|
||||||
continue;
|
continue;
|
||||||
@@ -545,6 +625,7 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
for (ii=0; ii < UE_num_active_CC(UE_list,UE_id); ii++) {
|
for (ii=0; ii < UE_num_active_CC(UE_list,UE_id); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
|
ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id];
|
||||||
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round);
|
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round);
|
||||||
|
|
||||||
average_rbs_per_user[CC_id]=0;
|
average_rbs_per_user[CC_id]=0;
|
||||||
@@ -575,8 +656,8 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
|
|
||||||
if (total_ue_count == 0) {
|
if (total_ue_count == 0) {
|
||||||
average_rbs_per_user[CC_id] = 0;
|
average_rbs_per_user[CC_id] = 0;
|
||||||
} else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) ) {
|
} else if( (min_rb_unit[CC_id] * total_ue_count) <= nb_rbs_allowed_slice[CC_id][slice_id] ) {
|
||||||
average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
|
average_rbs_per_user[CC_id] = (uint16_t) floor(nb_rbs_allowed_slice[CC_id][slice_id]/total_ue_count);
|
||||||
} else {
|
} else {
|
||||||
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
|
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
|
||||||
}
|
}
|
||||||
@@ -588,6 +669,9 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||||
rnti = UE_RNTI(Mod_id,i);
|
rnti = UE_RNTI(Mod_id,i);
|
||||||
|
|
||||||
|
if (flexran_slice_member(i, slice_id) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
|
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][i];
|
CC_id = UE_list->ordered_CCids[ii][i];
|
||||||
|
|
||||||
@@ -607,6 +691,10 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
for(r1=0; r1<2; r1++) {
|
for(r1=0; r1<2; r1++) {
|
||||||
|
|
||||||
for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||||
|
|
||||||
|
if (flexran_slice_member(i, slice_id) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
|
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][i];
|
CC_id = UE_list->ordered_CCids[ii][i];
|
||||||
|
|
||||||
@@ -633,7 +721,10 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||||
UE_id = i;
|
UE_id = i;
|
||||||
|
|
||||||
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
|
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round);
|
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round);
|
||||||
@@ -673,6 +764,9 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
UE_id = i;
|
UE_id = i;
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
|
|
||||||
|
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
|
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
||||||
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
|
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
|
||||||
@@ -688,7 +782,8 @@ void _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];
|
//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,"Total RBs allocated for UE%d = %d\n",UE_id,ue_sched_ctl->pre_nb_available_rbs[CC_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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -696,8 +791,11 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
|||||||
|
|
||||||
#define SF05_LIMIT 1
|
#define SF05_LIMIT 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main scheduling functions to support slicing
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void
|
void
|
||||||
flexran_schedule_ue_spec_default(mid_t mod_id,
|
flexran_schedule_ue_spec_default(mid_t mod_id,
|
||||||
uint32_t frame,
|
uint32_t frame,
|
||||||
@@ -705,6 +803,224 @@ flexran_schedule_ue_spec_default(mid_t mod_id,
|
|||||||
int *mbsfn_flag,
|
int *mbsfn_flag,
|
||||||
Protocol__FlexranMessage **dl_info)
|
Protocol__FlexranMessage **dl_info)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
|
||||||
|
|
||||||
|
for (i = 0; i < n_active_slices; i++) {
|
||||||
|
|
||||||
|
// Load any updated functions
|
||||||
|
if (update_dl_scheduler[i] > 0 ) {
|
||||||
|
slice_sched[i] = dlsym(NULL, dl_scheduler_type[i]);
|
||||||
|
update_dl_scheduler[i] = 0;
|
||||||
|
update_dl_scheduler_current[i] = 0;
|
||||||
|
slice_percentage_current[i]= slice_percentage[i];
|
||||||
|
total_slice_percentage+=slice_percentage[i];
|
||||||
|
LOG_N(MAC,"update dl scheduler slice %d\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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_N(MAC,"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n",
|
||||||
|
mod_id, frame, subframe, n_active_slices_current, n_active_slices);
|
||||||
|
n_active_slices_current = n_active_slices;
|
||||||
|
} else {
|
||||||
|
LOG_W(MAC,"invalid number of 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]){
|
||||||
|
if ((slice_percentage[i] >= 0.0) && (slice_percentage[i] <= 1.0)){
|
||||||
|
if ((total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]) <= 1.0) {
|
||||||
|
total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i];
|
||||||
|
LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n",
|
||||||
|
mod_id, i, frame, subframe, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]);
|
||||||
|
slice_percentage_current[i] = slice_percentage[i];
|
||||||
|
} else {
|
||||||
|
LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n",
|
||||||
|
mod_id,i,
|
||||||
|
total_slice_percentage,
|
||||||
|
total_slice_percentage - slice_percentage_current[i] + slice_percentage[i],
|
||||||
|
slice_percentage[i],slice_percentage_current[i]);
|
||||||
|
slice_percentage[i]= slice_percentage_current[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]);
|
||||||
|
slice_percentage[i]= slice_percentage_current[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_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n",
|
||||||
|
mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]);
|
||||||
|
slice_maxmcs_current[i] = slice_maxmcs[i];
|
||||||
|
} else {
|
||||||
|
LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_percentage[i],slice_percentage[i]);
|
||||||
|
slice_maxmcs[i]= slice_maxmcs_current[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
|
||||||
|
mod_id, i, frame, subframe, dl_scheduler_type[i]);
|
||||||
|
update_dl_scheduler_current[i] = update_dl_scheduler[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run each enabled slice-specific schedulers one by one
|
||||||
|
//LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i);
|
||||||
|
slice_sched[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs){
|
||||||
|
return (uint16_t) floor(rb_percentage * total_rbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int flexran_slice_maxmcs(int slice_id) {
|
||||||
|
return slice_maxmcs[slice_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
int flexran_slice_member(int UE_id, int slice_id){
|
||||||
|
// group membership definition
|
||||||
|
int slice_member = 0 ;
|
||||||
|
|
||||||
|
if ((slice_id < 0) || (slice_id > n_active_slices))
|
||||||
|
LOG_W(MAC,"out of range slice id %d\n",slice_id);
|
||||||
|
|
||||||
|
switch (slicing_strategy) {
|
||||||
|
case SLICE_MASK:
|
||||||
|
switch (slice_id){
|
||||||
|
case 0:
|
||||||
|
if (SLICE0_MASK&UE_id){
|
||||||
|
slice_member=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (SLICE1_MASK&UE_id){
|
||||||
|
slice_member=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (SLICE2_MASK&UE_id){
|
||||||
|
slice_member=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (SLICE3_MASK&UE_id){
|
||||||
|
slice_member=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
LOG_W(MAC,"unknown slice_id %d\n", slice_id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UEID_TO_SLICEID:
|
||||||
|
default:
|
||||||
|
if ((UE_id % n_active_slices) == slice_id){
|
||||||
|
slice_member= 1; // this ue is a member of this slice
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return slice_member;
|
||||||
|
}
|
||||||
|
/* more aggressive rb and mcs allocation with medium priority and the traffic qci */
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_embb(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info)
|
||||||
|
|
||||||
|
{
|
||||||
|
flexran_schedule_ue_spec_common(mod_id,
|
||||||
|
slice_id,
|
||||||
|
frame,
|
||||||
|
subframe,
|
||||||
|
mbsfn_flag,
|
||||||
|
dl_info);
|
||||||
|
|
||||||
|
}
|
||||||
|
/* more conservative mcs allocation with high priority and the traffic qci */
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_urllc(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info)
|
||||||
|
|
||||||
|
{
|
||||||
|
flexran_schedule_ue_spec_common(mod_id,
|
||||||
|
slice_id,
|
||||||
|
frame,
|
||||||
|
subframe,
|
||||||
|
mbsfn_flag,
|
||||||
|
dl_info);
|
||||||
|
|
||||||
|
}
|
||||||
|
/* constant rb allocation with low mcs with low priority and given the UE capabilities */
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_mmtc(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
flexran_schedule_ue_spec_common(mod_id,
|
||||||
|
slice_id,
|
||||||
|
frame,
|
||||||
|
subframe,
|
||||||
|
mbsfn_flag,
|
||||||
|
dl_info);
|
||||||
|
|
||||||
|
}
|
||||||
|
/* regular rb and mcs allocation with low priority */
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_be(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
flexran_schedule_ue_spec_common(mod_id,
|
||||||
|
slice_id,
|
||||||
|
frame,
|
||||||
|
subframe,
|
||||||
|
mbsfn_flag,
|
||||||
|
dl_info);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||||
|
int slice_id,
|
||||||
|
uint32_t frame,
|
||||||
|
uint32_t subframe,
|
||||||
|
int *mbsfn_flag,
|
||||||
|
Protocol__FlexranMessage **dl_info)
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
uint8_t CC_id;
|
uint8_t CC_id;
|
||||||
int UE_id;
|
int UE_id;
|
||||||
@@ -776,10 +1092,11 @@ flexran_schedule_ue_spec_default(mid_t mod_id,
|
|||||||
|
|
||||||
start_meas(&eNB->schedule_dlsch_preprocessor);
|
start_meas(&eNB->schedule_dlsch_preprocessor);
|
||||||
_dlsch_scheduler_pre_processor(mod_id,
|
_dlsch_scheduler_pre_processor(mod_id,
|
||||||
frame,
|
slice_id,
|
||||||
subframe,
|
frame,
|
||||||
N_RBG,
|
subframe,
|
||||||
mbsfn_flag);
|
N_RBG,
|
||||||
|
mbsfn_flag);
|
||||||
stop_meas(&eNB->schedule_dlsch_preprocessor);
|
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);
|
||||||
|
|
||||||
@@ -793,6 +1110,9 @@ flexran_schedule_ue_spec_default(mid_t mod_id,
|
|||||||
rnti = flexran_get_ue_crnti(mod_id, UE_id);
|
rnti = flexran_get_ue_crnti(mod_id, UE_id);
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
|
|
||||||
|
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (rnti==NOT_A_RNTI) {
|
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);
|
LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id,UE_list->num_UEs);
|
||||||
// mac_xface->macphy_exit("Cannot find rnti for UE_id");
|
// mac_xface->macphy_exit("Cannot find rnti for UE_id");
|
||||||
@@ -840,7 +1160,7 @@ flexran_schedule_ue_spec_default(mid_t mod_id,
|
|||||||
flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round);
|
flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round);
|
||||||
sdu_length_total=0;
|
sdu_length_total=0;
|
||||||
mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)];
|
mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)];
|
||||||
|
mcs = cmin(mcs,flexran_slice_maxmcs(slice_id));
|
||||||
#ifdef EXMIMO
|
#ifdef EXMIMO
|
||||||
|
|
||||||
if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) {
|
if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) {
|
||||||
@@ -1372,10 +1692,18 @@ flexran_schedule_ue_spec_default(mid_t mod_id,
|
|||||||
} // CC_id loop
|
} // CC_id loop
|
||||||
|
|
||||||
// Add all the dl_data elements to the flexran message
|
// Add all the dl_data elements to the flexran message
|
||||||
(*dl_info)->dl_mac_config_msg->n_dl_ue_data = num_ues_added;
|
int offset = (*dl_info)->dl_mac_config_msg->n_dl_ue_data;
|
||||||
(*dl_info)->dl_mac_config_msg->dl_ue_data = (Protocol__FlexDlData **) malloc(sizeof(Protocol__FlexDlData *) * num_ues_added);
|
(*dl_info)->dl_mac_config_msg->n_dl_ue_data += num_ues_added;
|
||||||
for (i = 0; i < num_ues_added; i++) {
|
if ( num_ues_added > 0 ){
|
||||||
(*dl_info)->dl_mac_config_msg->dl_ue_data[i] = dl_data[i];
|
(*dl_info)->dl_mac_config_msg->dl_ue_data = (Protocol__FlexDlData **) realloc( (*dl_info)->dl_mac_config_msg->dl_ue_data,
|
||||||
|
sizeof(Protocol__FlexDlData *) * ((*dl_info)->dl_mac_config_msg->n_dl_ue_data));
|
||||||
|
if ((*dl_info)->dl_mac_config_msg->dl_ue_data == NULL ){
|
||||||
|
LOG_E(MAC, "Request for memory reallocation failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_ues_added; i++) {
|
||||||
|
(*dl_info)->dl_mac_config_msg->dl_ue_data[offset+i] = dl_data[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_meas(&eNB->schedule_dlsch);
|
stop_meas(&eNB->schedule_dlsch);
|
||||||
|
|||||||
Reference in New Issue
Block a user