Commit 4901daf7 authored by Robert Schmidt's avatar Robert Schmidt

FlexRAN: New protobuf slice structure + Static Slice handling

parent 872cfc03
......@@ -1452,9 +1452,74 @@ void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id,
conf->si_config->has_sfn = 1;
}
/* get a pointer to the config which is maintained in the agent throughout
* its lifetime */
conf->slice_config = flexran_agent_get_slice_config(mod_id);
conf->slice_config = malloc(sizeof(Protocol__FlexSliceConfig));
if (conf->slice_config) {
protocol__flex_slice_config__init(conf->slice_config);
Protocol__FlexSliceConfig *sc = conf->slice_config;
sc->dl = malloc(sizeof(Protocol__FlexSliceDlUlConfig));
DevAssert(sc->dl);
protocol__flex_slice_dl_ul_config__init(sc->dl);
sc->dl->algorithm = flexran_get_dl_slice_algo(mod_id);
sc->dl->has_algorithm = 1;
sc->dl->n_slices = flexran_get_num_dl_slices(mod_id);
if (sc->dl->n_slices > 0) {
sc->dl->slices = calloc(sc->dl->n_slices, sizeof(Protocol__FlexSlice *));
DevAssert(sc->dl->slices);
for (int i = 0; i < sc->dl->n_slices; ++i) {
sc->dl->slices[i] = malloc(sizeof(Protocol__FlexSlice));
DevAssert(sc->dl->slices[i]);
protocol__flex_slice__init(sc->dl->slices[i]);
flexran_get_dl_slice(mod_id, i, sc->dl->slices[i], sc->dl->algorithm);
}
} else {
sc->dl->scheduler = flexran_get_dl_scheduler_name(mod_id);
}
sc->ul = malloc(sizeof(Protocol__FlexSliceDlUlConfig));
DevAssert(sc->ul);
protocol__flex_slice_dl_ul_config__init(sc->ul);
sc->ul->algorithm = flexran_get_ul_slice_algo(mod_id);
sc->ul->has_algorithm = 1;
sc->ul->n_slices = flexran_get_num_ul_slices(mod_id);
if (sc->ul->n_slices > 0) {
sc->ul->slices = calloc(sc->ul->n_slices, sizeof(Protocol__FlexSlice *));
DevAssert(sc->ul->slices);
for (int i = 0; i < sc->ul->n_slices; ++i) {
sc->ul->slices[i] = malloc(sizeof(Protocol__FlexSlice));
DevAssert(sc->ul->slices[i]);
protocol__flex_slice__init(sc->ul->slices[i]);
flexran_get_ul_slice(mod_id, i, sc->ul->slices[i], sc->ul->algorithm);
}
} else {
sc->ul->scheduler = flexran_get_ul_scheduler_name(mod_id);
}
}
}
void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf) {
Protocol__FlexSliceConfig *sc = conf->slice_config;
for (int i = 0; i < sc->dl->n_slices; ++i) {
free(sc->dl->slices[i]);
sc->dl->slices[i] = NULL;
/* scheduler names are not freed: we assume we read them directly from the
* underlying memory and do not dispose it */
}
free(sc->dl->slices);
/* scheduler name is not freed */
free(sc->dl);
sc->dl = NULL;
for (int i = 0; i < sc->ul->n_slices; ++i) {
free(sc->ul->slices[i]);
sc->ul->slices[i] = NULL;
/* scheduler names are not freed */
}
free(sc->ul->slices);
/* scheduler name is not freed */
free(sc->ul);
sc->ul = NULL;
free(conf->slice_config);
conf->slice_config = NULL;
}
void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id,
......@@ -1568,46 +1633,46 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id)
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;
//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]);
}
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 helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) {
if (slice_config->dl) {
if (slice_config->dl->scheduler)
free(slice_config->dl->scheduler);
for (int i = 0; i < slice_config->dl->n_slices; i++)
if (slice_config->dl->slices[i]->scheduler)
free(slice_config->dl->slices[i]->scheduler);
}
if (slice_config->ul) {
if (slice_config->ul->scheduler)
free(slice_config->ul->scheduler);
for (int i = 0; i < slice_config->ul->n_slices; i++)
if (slice_config->ul->slices[i]->scheduler)
free(slice_config->ul->slices[i]->scheduler);
}
Protocol__FlexCellConfig helper;
helper.slice_config = slice_config;
flexran_agent_destroy_mac_slice_config(&helper);
}
void flexran_check_and_remove_slices(mid_t mod_id)
{
}
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) {
if (!*slice_config) return;
Protocol__FlexSliceConfig *sc = *slice_config;
*slice_config = NULL;
void flexran_agent_slice_update(mid_t mod_id)
{
/* TODO handle using lock-free queue */
apply_update_dl_slice_config(mod_id, sc->dl);
apply_update_ul_slice_config(mod_id, sc->ul);
helper_destroy_mac_slice_config(*slice_config);
}
Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id)
{
if (!slice_config[mod_id]) return NULL;
Protocol__FlexSliceConfig *config = NULL;
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config) {
/* TODO handle using lock-free queue */
apply_ue_slice_assoc_update(mod_id, *ue_config);
pthread_mutex_lock(&sc_update_mtx);
if (!config) {
pthread_mutex_unlock(&sc_update_mtx);
return NULL;
}
pthread_mutex_unlock(&sc_update_mtx);
return config;
free(*ue_config);
*ue_config = NULL;
}
void flexran_agent_slice_update(mid_t mod_id) {
}
......@@ -115,7 +115,16 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id);
/* 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);
/* marks slice_config so that it can be applied later. Takes ownership of the
* FlexSliceConfig message */
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice);
/* inserts a new ue_config into the structure keeping ue to slice association
* updates and marks so it can be applied. Takes ownership of the FlexUeConfig message */
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config);
/* free slice_config part of flexCellConfig, filled in
* flexran_agent_fill_mac_cell_config() */
void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf);
#endif
......@@ -1025,60 +1025,166 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) {
}
Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul)
{
Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig));
if (!fsc) return NULL;
protocol__flex_slice_config__init(fsc);
/* TODO */
return fsc;
void update_or_remove_dl(mid_t mod_id, Protocol__FlexSlice *s) {
if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET
&& !s->label && !s->scheduler) {
LOG_I(FLEXRAN_AGENT, "remove DL slice ID %d\n", s->id);
const int rc = flexran_remove_dl_slice(mod_id, s);
if (!rc)
LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id);
} else {
LOG_I(FLEXRAN_AGENT, "updating DL slice ID %d\n", s->id);
const int rc = flexran_create_dl_slice(mod_id, s);
if (rc < 0)
LOG_W(FLEXRAN_AGENT,
"error while update slice ID %d: flexran_create_dl_slice() -> %d\n",
s->id, rc);
}
}
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup)
{
void update_or_remove_ul(mid_t mod_id, Protocol__FlexSlice *s) {
if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET
&& !s->label && !s->scheduler) {
LOG_I(FLEXRAN_AGENT, "remove UL slice ID %d\n", s->id);
const int rc = flexran_remove_ul_slice(mod_id, s);
if (!rc)
LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id);
} else {
LOG_I(FLEXRAN_AGENT, "updating UL slice ID %d\n", s->id);
const int rc = flexran_create_ul_slice(mod_id, s);
if (rc < 0)
LOG_W(FLEXRAN_AGENT,
"error while updating slice ID %d: flexran_create_ul_slice() -> %d)\n",
s->id, rc);
}
}
void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *dl) {
if (!dl)
return;
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config)
{
if (n_ue_slice_assoc_updates == 10) {
Protocol__FlexSliceAlgorithm dl_algo = flexran_get_dl_slice_algo(mod_id);
if (dl->has_algorithm && dl_algo != dl->algorithm) {
LOG_I(FLEXRAN_AGENT, "loading new DL slice algorithm %d\n", dl->algorithm);
dl_algo = dl->algorithm;
flexran_set_dl_slice_algo(mod_id, dl_algo);
}
/* first update existing slices, then create new. Thus, we go through the
* list twice. First round, if a slice exists, handle and mark as such. Then,
* apply all others in the second round */
if (dl->n_slices > 0) {
if (dl_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n");
return;
}
int handled_dl[dl->n_slices];
for (int i = 0; i < dl->n_slices; ++i) {
if (flexran_find_dl_slice(mod_id, dl->slices[i]->id) < 0) {
handled_dl[i] = 0;
continue;
}
update_or_remove_dl(mod_id, dl->slices[i]);
handled_dl[i] = 1;
}
for (int i = 0; i < dl->n_slices; ++i) {
if (handled_dl[i])
continue;
update_or_remove_dl(mod_id, dl->slices[i]);
}
}
if (dl->scheduler) {
if (dl_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n");
return;
}
LOG_I(FLEXRAN_AGENT, "loading DL new scheduling algorithm '%s'\n", dl->scheduler);
const int rc = flexran_set_dl_scheduler(mod_id, dl->scheduler);
if (rc < 0) {
LOG_E(FLEXRAN_AGENT,
"[%d] can not handle flex_ue_config message, buffer is full; try again later\n",
mod_id);
"error while updating scheduling algorithm: "
"flexran_update_dl_sched_algo() -> %d)\n",
rc);
return;
}
if (!ue_config->has_rnti) {
}
}
void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *ul) {
if (!ul)
return;
Protocol__FlexSliceAlgorithm ul_algo = flexran_get_ul_slice_algo(mod_id);
if (ul->has_algorithm && ul_algo != ul->algorithm) {
LOG_I(FLEXRAN_AGENT, "loading new UL slice algorithm %d\n", ul->algorithm);
ul_algo = ul->algorithm;
flexran_set_ul_slice_algo(mod_id, ul_algo);
}
if (ul->n_slices > 0) {
if (ul_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n");
return;
}
int handled_ul[ul->n_slices];
for (int i = 0; i < ul->n_slices; ++i) {
if (flexran_find_ul_slice(mod_id, ul->slices[i]->id) < 0) {
handled_ul[i] = 0;
continue;
}
update_or_remove_ul(mod_id, ul->slices[i]);
handled_ul[i] = 1;
}
for (int i = 0; i < ul->n_slices; ++i) {
if (handled_ul[i])
continue;
update_or_remove_ul(mod_id, ul->slices[i]);
}
}
if (ul->scheduler) {
if (ul_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n");
return;
}
LOG_I(FLEXRAN_AGENT, "loading new UL scheduling algorithm '%s'\n", ul->scheduler);
const int rc = flexran_set_ul_scheduler(mod_id, ul->scheduler);
if (rc < 0) {
LOG_E(FLEXRAN_AGENT,
"[%d] cannot update UE to slice association, no RNTI in flex_ue_config message\n",
mod_id);
"error while updating scheduling algorithm: "
"flexran_update_dl_sched_algo() -> %d)\n",
rc);
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 apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config)
{
int i;
int changes = 0;
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_id < 0 || ue_id > MAX_MOBILES_PER_ENB){
LOG_E(FLEXRAN_AGENT,"UE_id %d is wrong!!\n",ue_id);
continue;
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 0;
}
int UE_id = flexran_get_mac_ue_id_rnti(mod_id, ue_config->rnti);
if (ue_config->has_dl_slice_id) {
if (flexran_get_dl_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "no DL slice algorithm loaded\n");
} else {
LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to DL slice ID %d\n",
mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->dl_slice_id);
flexran_set_ue_dl_slice_id(mod_id, UE_id, ue_config->dl_slice_id);
}
if (ue_slice_assoc_update[i]->has_dl_slice_id) {
}
if (ue_slice_assoc_update[i]->has_ul_slice_id) {
if (ue_config->has_ul_slice_id) {
if (flexran_get_ul_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "no UL slice algorithm loaded\n");
} else {
LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to UL slice ID %d\n",
mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->ul_slice_id);
flexran_set_ue_ul_slice_id(mod_id, UE_id, ue_config->ul_slice_id);
}
}
n_ue_slice_assoc_updates = 0;
return changes;
return 0;
}
......@@ -103,23 +103,11 @@ 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 general slice parameters via RAN into the given
* Protocol__FlexSliceConfig struct */
void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s);
/* 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);
/* 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);
/* Prepare the application of a slicing config */
void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice);
void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice);
/* apply a new association between a UE and a slice (both DL and UL) */
int apply_ue_slice_assoc_update(mid_t mod_id);
int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config);
#endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/
......@@ -61,6 +61,31 @@ enum flex_qam {
//
// Slice config related structures and enums
//
enum flex_slice_algorithm {
None = 0;
Static = 1;
NVS = 2;
}
message flex_slice_static {
optional uint32 posLow = 1;
optional uint32 posHigh = 2;
}
message flex_slice {
optional uint32 id = 1;
optional string label = 2;
optional string scheduler = 3;
oneof params {
flex_slice_static static = 10;
}
}
message flex_slice_dl_ul_config {
optional flex_slice_algorithm algorithm = 1;
repeated flex_slice slices = 2;
optional string scheduler = 3; // if no slicing
}
//
// UE config related structures and enums
......
......@@ -49,6 +49,8 @@ message flex_cell_config {
}
message flex_slice_config {
optional flex_slice_dl_ul_config dl = 6;
optional flex_slice_dl_ul_config ul = 7;
}
message flex_ue_config {
......
......@@ -306,6 +306,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc)
free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
/* si_config is shared between MAC and RRC, free here */
if (reply->cell_config[i]->si_config) {
for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) {
free(reply->cell_config[i]->si_config->si_message[j]);
......@@ -316,8 +317,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
}
if (reply->cell_config[i]->slice_config) {
/* TODO */
free(reply->cell_config[i]->slice_config);
flexran_agent_destroy_mac_slice_config(reply->cell_config[i]);
}
free(reply->cell_config[i]);
......@@ -880,7 +880,7 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot
if (enb_config->n_cell_config > 0) {
if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) {
prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config);
prepare_update_slice_config(mod_id, &enb_config->cell_config[0]->slice_config);
}
if (enb_config->cell_config[0]->has_eutra_band
&& enb_config->cell_config[0]->has_dl_freq
......@@ -921,7 +921,11 @@ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Proto
Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg;
for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++)
prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]);
prepare_ue_slice_assoc_update(mod_id, &ue_config_reply->ue_config[i]);
/* prepare_ue_slice_assoc_update takes ownership of the individual
* FlexUeConfig messages. Therefore, mark zero messages to not accidentally
* free them twice */
ue_config_reply->n_ue_config = 0;
*msg = NULL;
return 0;
......
......@@ -30,6 +30,7 @@
#include "flexran_agent_ran_api.h"
#include "s1ap_eNB_ue_context.h"
#include "s1ap_eNB_management_procedures.h"
#include "openair2/LAYER2/MAC/slicing/slicing.h"
static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) {
return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id];
......@@ -3013,66 +3014,294 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti)
}
/**************************** SLICING ****************************/
Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id) {
if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
switch (RC.mac[mod_id]->pre_processor_dl.algorithm) {
case STATIC_SLICING:
return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
default:
return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
}
}
int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return 0;
eNB_MAC_INST *mac = RC.mac[mod_id];
const int cc_id = 0;
pp_impl_param_t dl = mac->pre_processor_dl;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
mac->pre_processor_dl = static_dl_init(mod_id, cc_id);
break;
default:
mac->pre_processor_dl.algorithm = 0;
mac->pre_processor_dl.dl = dlsch_scheduler_pre_processor;
mac->pre_processor_dl.dl_algo.data = mac->pre_processor_dl.dl_algo.setup();
mac->pre_processor_dl.slices = NULL;
break;
}
if (dl.slices)
dl.destroy(&dl.slices);
if (dl.dl_algo.data)
dl.dl_algo.unset(&dl.dl_algo.data);
return 1;
}
Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id) {
if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
switch (RC.mac[mod_id]->pre_processor_ul.algorithm) {
case STATIC_SLICING:
return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
default:
return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
}
}
int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return 0;
eNB_MAC_INST *mac = RC.mac[mod_id];
const int cc_id = 0;
pp_impl_param_t ul = mac->pre_processor_ul;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
mac->pre_processor_ul = static_ul_init(mod_id, cc_id);
break;
default:
mac->pre_processor_ul.algorithm = 0;
mac->pre_processor_ul.ul = ulsch_scheduler_pre_processor;
mac->pre_processor_ul.ul_algo.data = mac->pre_processor_ul.ul_algo.setup();
mac->pre_processor_ul.slices = NULL;
break;
}
if (ul.slices)
ul.destroy(&ul.slices);
if (ul.ul_algo.data)
ul.ul_algo.unset(&ul.ul_algo.data);
return 1;
}
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
if (!mac_is_present(mod_id)) return -1;
return 0;
slice_info_t *slices = RC.mac[mod_id]->pre_processor_dl.slices;
if (!slices) return -1;
const int idx = slices->UE_assoc_slice[ue_id];
return slices->s[idx]->id;
}
void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
int idx = flexran_find_dl_slice(mod_id, slice_id);
if (idx < 0) return;
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
dl->move_UE(dl->slices, ue_id, idx);
}
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
if (!mac_is_present(mod_id)) return -1;
return 0;
slice_info_t *slices = RC.mac[mod_id]->pre_processor_ul.slices;
if (!slices) return -1;
const int idx = slices->UE_assoc_slice[ue_id];
return slices->s[idx]->id;
}
/* TODO */
int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return -1;
return -1;
void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
int idx = flexran_find_ul_slice(mod_id, slice_id);
if (idx < 0) return;
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
ul->move_UE(ul->slices, ue_id, idx);
}
/* TODO */
int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return -1;
int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return 0;
void *params = NULL;
switch (s->params_case) {
case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
params = malloc(sizeof(static_slice_param_t));
if (!params) return 0;
((static_slice_param_t *)params)->posLow = s->static_->poslow;
((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
break;
default:
break;
}
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
char *l = s->label ? strdup(s->label) : NULL;
void *algo = &dl->dl_algo; // default scheduler
if (s->scheduler) {
algo = dlsym(NULL, s->scheduler);
if (!algo) {
free(params);
LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
return -15;
}
}
return dl->addmod_slice(dl->slices, s->id, l, algo, params);
}
int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return 0;
const int idx = flexran_find_dl_slice(mod_id, s->id);
if (idx < 0) return 0;
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
return dl->remove_slice(dl->slices, idx);
}
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 *si = RC.mac[mod_id]->pre_processor_dl.slices;
for (int i = 0; i < si->num; ++i)
if (si->s[i]->id == slice_id)
return i;
return -1;
}
//int flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) {
//}
void flexran_get_dl_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return;
slice_t *s_ = RC.mac[mod_id]->pre_processor_dl.slices->s[slice_idx];
slice->has_id = 1;
slice->id = s_->id;
slice->label = s_->label;
slice->scheduler = s_->dl_algo.name;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
if (!slice->static_) return;
protocol__flex_slice_static__init(slice->static_);
slice->static_->has_poslow = 1;
slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
slice->static_->has_poshigh = 1;
slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
break;
default:
break;
}
}
int flexran_get_num_dl_slices(mid_t mod_id) {
if (!mac_is_present(mod_id)) return -1;
return 0;
if (!mac_is_present(mod_id)) return 0;
if (!RC.mac[mod_id]->pre_processor_dl.slices) return 0;
return RC.mac[mod_id]->pre_processor_dl.slices->num;
}
/* TODO */
void flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
return;
int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return -1;
void *params = NULL;
switch (s->params_case) {
case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
params = malloc(sizeof(static_slice_param_t));
if (!params) return 0;
((static_slice_param_t *)params)->posLow = s->static_->poslow;
((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
break;
default:
break;
}
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
char *l = s->label ? strdup(s->label) : NULL;
void *algo = &ul->ul_algo; // default scheduler
if (s->scheduler) {
algo = dlsym(NULL, s->scheduler);
if (!algo) {
free(params);
LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
return -15;
}
}
return ul->addmod_slice(ul->slices, s->id, l, algo, params);
}
/* TODO */
int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return -1;
int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return 0;
const int idx = flexran_find_ul_slice(mod_id, s->id);
if (idx < 0) return 0;
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
return ul->remove_slice(ul->slices, idx);
}
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 *si = RC.mac[mod_id]->pre_processor_ul.slices;
for (int i = 0; i < si->num; ++i)
if (si->s[i]->id == slice_id)
return i;
return -1;
}
//int flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) {
//}
void flexran_get_ul_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return;
slice_t *s_ = RC.mac[mod_id]->pre_processor_ul.slices->s[slice_idx];
slice->has_id = 1;
slice->id = s_->id;
slice->label = s_->label;
slice->scheduler = s_->ul_algo.name;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
if (!slice->static_) return;
protocol__flex_slice_static__init(slice->static_);
slice->static_->has_poslow = 1;
slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
slice->static_->has_poshigh = 1;
slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
break;
default:
break;
}
}
int flexran_get_num_ul_slices(mid_t mod_id) {
if (!mac_is_present(mod_id)) return 0;
if (!RC.mac[mod_id]->pre_processor_ul.slices) return 0;
return RC.mac[mod_id]->pre_processor_ul.slices->num;
}
char *flexran_get_dl_scheduler_name(mid_t mod_id) {
if (!mac_is_present(mod_id)) return NULL;
return RC.mac[mod_id]->pre_processor_dl.dl_algo.name;
}
int flexran_set_dl_scheduler(mid_t mod_id, char *sched) {
if (!mac_is_present(mod_id)) return -1;
void *d = dlsym(NULL, sched);
if (!d) return -2;
pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl;
dl_pp->dl_algo.unset(&dl_pp->dl_algo.data);
dl_pp->dl_algo = *(default_sched_dl_algo_t *) d;
dl_pp->dl_algo.data = dl_pp->dl_algo.setup();
return 0;
}
char *flexran_get_ul_scheduler_name(mid_t mod_id) {
if (!mac_is_present(mod_id)) return NULL;
return RC.mac[mod_id]->pre_processor_ul.ul_algo.name;
}
int flexran_set_ul_scheduler(mid_t mod_id, char *sched) {
if (!mac_is_present(mod_id)) return -1;
void *d = dlsym(NULL, sched);
if (!d) return -2;
pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul;
ul_pp->ul_algo.unset(&ul_pp->ul_algo.data);
ul_pp->ul_algo = *(default_sched_ul_algo_t *) d;
ul_pp->ul_algo.data = ul_pp->ul_algo.setup();
return 0;
}
/************************** S1AP **************************/
int flexran_get_s1ap_mme_pending(mid_t mod_id){
......
......@@ -656,41 +656,66 @@ int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index);
uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti);
/************************** Slice configuration **************************/
/* Get the currently active DL slicing algorithm */
Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id);
/* Set the active DL slicing algorithm */
int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo);
/* Get the currently active UL slicing algorithm */
Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id);
/* Set the active UL slicing algorithm */
int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo);
/* 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);
/* Set the DL slice for a UE */
void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
/* 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);
/* Set the UL slice for a UE */
void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
/* Create slice in DL, returns the new slice index */
//int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id);
int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* 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);
int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* 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);
/* Return the parameters of slice at index slice_idx */
//void flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s);
void flexran_get_dl_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo);
/* Get the number of slices in DL */
int flexran_get_num_dl_slices(mid_t mod_id);
/* Create slice in UL, returns the new slice index */
//int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id);
int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* Remove slice in UL */
//int flexran_remove_ul_slice(mid_t mod_id, int slice_idx);
int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* Finds slice in DL with given slice_id and returns slice index */
int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id);
/* Return the parameters of slice at index slice_idx */
//void flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s);
void flexran_get_ul_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo);
/* Get the number of slices in UL */
int flexran_get_num_ul_slices(mid_t mod_id);
/* Get the name of/Set the DL scheduling algorithm. If slicing is active, this
* corresponds to the default algorithm for slices, otherwise the currently
* used one. */
char *flexran_get_dl_scheduler_name(mid_t mod_id);
int flexran_set_dl_scheduler(mid_t mod_id, char *sched);
/* Get the name of/Set the UL scheduler algorithm. Same applies as for the DL
* case */
char *flexran_get_ul_scheduler_name(mid_t mod_id);
int flexran_set_ul_scheduler(mid_t mod_id, char *sched);
/************************** S1AP **************************/
/* Get the number of MMEs to be connected */
......
......@@ -100,6 +100,7 @@ void mac_top_init_eNB(void)
mac[i]->if_inst = IF_Module_init(i);
mac[i]->pre_processor_dl.algorithm = 0;
mac[i]->pre_processor_dl.dl = dlsch_scheduler_pre_processor;
char *s = "round_robin_dl";
void *d = dlsym(NULL, s);
......@@ -107,6 +108,7 @@ void mac_top_init_eNB(void)
mac[i]->pre_processor_dl.dl_algo = *(default_sched_dl_algo_t *) d;
mac[i]->pre_processor_dl.dl_algo.data = mac[i]->pre_processor_dl.dl_algo.setup();
mac[i]->pre_processor_ul.algorithm = 0;
mac[i]->pre_processor_ul.ul = ulsch_scheduler_pre_processor;
s = "round_robin_ul";
d = dlsym(NULL, s);
......
......@@ -258,13 +258,26 @@ int addmod_static_slice_ul(slice_info_t *si,
return si->num - 1;
}
int remove_static_slice(slice_info_t *si, uint8_t slice_idx) {
int remove_static_slice_dl(slice_info_t *si, uint8_t slice_idx) {
if (slice_idx == 0)
return 0;
slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx);
if (!sr)
return 0;
free(sr->algo_data);
sr->dl_algo.unset(&sr->dl_algo.data);
free(sr);
return 1;
}
int remove_static_slice_ul(slice_info_t *si, uint8_t slice_idx) {
if (slice_idx == 0)
return 0;
slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx);
if (!sr)
return 0;
free(sr->algo_data);
sr->ul_algo.unset(&sr->ul_algo.data);
free(sr);
return 1;
}
......@@ -528,6 +541,7 @@ pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) {
dlp->posLow = 0;
dlp->posHigh = to_rbg(RC.mac[mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - 1;
default_sched_dl_algo_t *algo = &RC.mac[mod_id]->pre_processor_dl.dl_algo;
algo->data = NULL;
DevAssert(0 == addmod_static_slice_dl(si, 0, strdup("default"), algo, dlp));
const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id])
......@@ -539,7 +553,7 @@ pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) {
sttc.remove_UE = slicing_remove_UE;
sttc.move_UE = slicing_move_UE;
sttc.addmod_slice = addmod_static_slice_dl;
sttc.remove_slice = remove_static_slice;
sttc.remove_slice = remove_static_slice_dl;
sttc.dl = static_dl;
// current DL algo becomes default scheduler
sttc.dl_algo = *algo;
......@@ -564,6 +578,7 @@ pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) {
ulp->posLow = 0;
ulp->posHigh = to_prb(RC.mac[mod_id]->common_channels[CC_id].ul_Bandwidth) - 1;
default_sched_ul_algo_t *algo = &RC.mac[mod_id]->pre_processor_ul.ul_algo;
algo->data = NULL;
DevAssert(0 == addmod_static_slice_ul(si, 0, strdup("default"), algo, ulp));
const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id])
......@@ -575,7 +590,7 @@ pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) {
sttc.remove_UE = slicing_remove_UE;
sttc.move_UE = slicing_move_UE;
sttc.addmod_slice = addmod_static_slice_ul;
sttc.remove_slice = remove_static_slice;
sttc.remove_slice = remove_static_slice_ul;
sttc.ul = static_ul;
// current DL algo becomes default scheduler
sttc.ul_algo = *algo;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment