Commit 2cb87ddd authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch 'origin/feature-slice+restart-w35' into develop_integration_2018_w36

Conflicts:
	openair2/ENB_APP/flexran_agent_common_internal.c
	openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
parents 2c9be8c1 c1359a10
......@@ -871,6 +871,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)
......
......@@ -120,74 +120,115 @@ int ret;
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
{
void *lib_handle;
void *lib_handle = NULL;
initfunc_t fpi;
checkverfunc_t fpc;
getfarrayfunc_t fpg;
char *shlib_path;
char *afname=NULL;
int ret=0;
char *shlib_path = NULL;
char *afname = NULL;
int ret = 0;
int lib_idx = -1;
if (loader_data.shlibpath == NULL) {
if (!modname) {
fprintf(stderr, "[LOADER] load_module_shlib(): no library name given\n");
return -1;
}
if (!loader_data.shlibpath) {
loader_init();
}
shlib_path = loader_format_shlibpath(modname);
ret = 0;
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;
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);
}
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 {
goto load_module_shlib_exit;
}
printf("[LOADER] library %s successfully loaded\n", shlib_path);
afname=malloc(strlen(modname)+15);
afname = malloc(strlen(modname)+15);
if (!afname) {
fprintf(stderr, "[LOADER] unable to allocate memory for library %s\n", shlib_path);
ret = -1;
goto load_module_shlib_exit;
}
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 (fpc) {
int chkver_ret = fpc(loader_data.mainexec_buildversion,
&(loader_data.shlibs[lib_idx].shlib_buildversion));
if (chkver_ret < 0) {
fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname);
exit_fun("[LOADER] unrecoverable error");
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);
if (fpi != NULL ) {
if (fpi) {
fpi(autoinit_arg);
}
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<numf; i++) {
if (farray) {
if (!loader_data.shlibs[lib_idx].funcarray) {
loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t));
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);
if (farray[i].fptr == NULL ) {
fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname);
ret= -1;
} else { /* farray[i].fptr == NULL */
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname);
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr;
loader_data.shlibs[loader_data.numshlibs].numfunc++;
}/* farray[i].fptr != NULL */
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++;
} /* for int i... */
} else { /* farray ! NULL */
sprintf(afname,"%s_getfarray",modname);
fpg = dlsym(lib_handle,afname);
if (fpg != NULL ) {
loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray));
if (fpg) {
loader_data.shlibs[lib_idx].numfunc =
fpg(&(loader_data.shlibs[lib_idx].funcarray));
}
} /* farray ! NULL */
loader_data.shlibs[loader_data.numshlibs].name=strdup(modname);
loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path);
(loader_data.numshlibs)++;
} /* lib_handle != NULL */
if ( shlib_path!= NULL) free(shlib_path);
if ( afname!= NULL) free(afname);
if (lib_handle != NULL) dlclose(lib_handle);
load_module_shlib_exit:
if (shlib_path) free(shlib_path);
if (afname) free(afname);
if (lib_handle) dlclose(lib_handle);
return ret;
}
......
......@@ -995,9 +995,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);
}
......@@ -1014,8 +1015,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);
}
......@@ -1035,9 +1038,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);
}
......@@ -1057,9 +1061,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);
}
......
/*
* 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)
......@@ -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"
......@@ -107,9 +107,15 @@ typedef enum {
CR_HOL = 2,
CR_LC = 3,
CR_CQI = 4,
CR_NUM = 5
CR_LCP = 5,
CR_NUM = 6
} sorting_criterion_t;
typedef enum {
POL_FAIR = 0,
POL_GREEDY = 1,
POL_NUM = 2
} accounting_policy_t;
//-----------------------------------------------------------------------------
// PHY TYPES
//-----------------------------------------------------------------------------
......
......@@ -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
......@@ -107,4 +107,45 @@ 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 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);
/* 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 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);
/* 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_*/
/*
* 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);
......@@ -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);
......
......@@ -80,6 +80,12 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch
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;
......@@ -113,25 +119,19 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch
config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i);
config->has_ue_aggregated_max_bitrate_dl = 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);
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;
......@@ -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) {
......@@ -495,12 +499,15 @@ 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) {
......@@ -511,13 +518,13 @@ 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->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,i);
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,i);
rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id);
rrc_measurements->has_pcell_rsrq = 1 ;
......@@ -529,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;
......@@ -547,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;
......@@ -558,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;
......@@ -625,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]);
}
......
......@@ -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
//
......
......@@ -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
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 = 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 = 4;
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 {
......
......@@ -64,6 +64,8 @@ extern RAN_CONTEXT_t RC;
# define ENB_REGISTER_RETRY_DELAY 10
# endif
#include "targets/RT/USER/lte-softmodem.h"
/*------------------------------------------------------------------------------*/
/*
......@@ -244,6 +246,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),
......@@ -321,3 +327,53 @@ 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];
LOG_I(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);
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_E(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);
}
......@@ -31,11 +31,11 @@
#define ENB_APP_H_
#include <stdint.h>
#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_ */
......@@ -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;
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;
ue_TransmissionMode, ue_multiple_max;
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;
long rxPool_ResourceConfig_subframeBitmap_choice_bs_size;
long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size;
libconfig_int 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;
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;
long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size;
long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size;
libconfig_int 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;
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;
long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size;
long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
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;
......@@ -292,7 +289,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);
}
......
This diff is collapsed.
......@@ -166,4 +166,19 @@ 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);
/* 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
......@@ -31,9 +31,9 @@
#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"
#include "enb_app.h"
void handle_reconfiguration(mid_t mod_id)
{
......@@ -589,3 +589,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(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
}
......@@ -32,6 +32,7 @@
#include <yaml.h>
#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
......@@ -46,9 +46,9 @@ 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_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*/
......@@ -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,7 +250,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 = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti;
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
......@@ -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;
......
This diff is collapsed.
This diff is collapsed.
......@@ -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;
......@@ -852,13 +852,18 @@ 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].lcgidpriority
[logicalChannelIdentity]=
logicalChannelConfig->ul_SpecificParameters->priority;
} else
UE_list->
UE_template[CC_idP][UE_id].lcgidmap
[logicalChannelIdentity] = 0;
......
......@@ -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
......
This diff is collapsed.
......@@ -542,8 +542,9 @@ 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 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];
......@@ -554,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;
......@@ -590,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);
}
}
......@@ -621,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;
......@@ -658,19 +656,22 @@ 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 (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,
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--;
......
......@@ -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;
......@@ -1853,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);
}
......@@ -1963,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_idx[UE_id] = 0;
UE_list->assoc_ul_slice_idx[UE_id] = 0;
UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
......@@ -4536,19 +4537,31 @@ 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);
}
int ue_slice_membership(int UE_id, int slice_id)
int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx)
{
if ((slice_id < 0) || (slice_id > n_active_slices))
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
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_idx[UE_id] == slice_idx;
}
int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx)
{
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_idx[UE_id] == slice_idx;
}
This diff is collapsed.
......@@ -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
......@@ -849,6 +849,9 @@ typedef struct {
/// LCGID mapping
long lcgidmap[11];
///UE logical channel priority
long lcgidpriority[11];
/// phr information
int8_t phr_info;
......@@ -1099,6 +1102,10 @@ 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];
int assoc_dl_slice_idx[MAX_MOBILES_PER_ENB];
int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB];
} UE_list_t;
......@@ -1118,6 +1125,117 @@ 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 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,
int slice_idx,
frame_t frame,
sub_frame_t subframe,
int *mbsfn_flag);
typedef struct {
slice_id_t id;
/// RB share for each slice
float pct;
/// whether this slice is isolated from the others
int isol;
int prio;
/// Frequency ranges for slice positioning
int pos_low;
int pos_high;
// max mcs for each slice
int maxmcs;
/// criteria for sorting policies of the slices
uint32_t sorting;
/// Accounting policy (just greedy(1) or fair(0) setting for now)
int accounting;
/// 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,
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
float pct;
// MAX MCS for each slice
int maxmcs;
/// criteria for sorting policies of the slices
uint32_t sorting;
/// starting RB (RB offset) of UL scheduling
int first_rb;
/// 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;
/// indicates whether remaining RBs after slice allocation will be
/// allocated to UEs of another slice. Isolated slices will be ignored
int interslice_share_active;
/// number of active DL slices
int n_dl;
slice_sched_conf_dl_t dl[MAX_NUM_SLICES];
/// number of active UL slices
int n_ul;
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 */
typedef struct {
int physCellId;
......@@ -1239,6 +1357,9 @@ typedef struct eNB_MAC_INST_s {
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
......
This diff is collapsed.
......@@ -29,6 +29,7 @@
*/
#include <dlfcn.h>
#include "mac.h"
#include "mac_proto.h"
#include "mac_extern.h"
......@@ -45,61 +46,106 @@
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 mac_top_init_eNB(void)
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;
eNB_MAC_INST *mac;
eNB_MAC_INST **mac;
LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n",
RC.nb_macrlc_inst);
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 *));
if (RC.nb_macrlc_inst <= 0) {
RC.mac = NULL;
return;
}
AssertFatal(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++) {
if (RC.mac[i] == NULL) {
RC.mac[i] = (eNB_MAC_INST *) malloc16(sizeof(eNB_MAC_INST));
AssertFatal(RC.mac[i] != NULL,
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, RC.mac);
bzero(RC.mac[i], sizeof(eNB_MAC_INST));
}
RC.mac[i]->Mod_id = i;
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++) {
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];
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++)
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];
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;
}
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;
}
mac[i]->if_inst = IF_Module_init(i);
init_UE_list(&mac[i]->UE_list);
init_slice_info(&mac[i]->slice_info);
}
RC.mac = mac;
AssertFatal(rlc_module_init() == 0,
"Could not initialize RLC layer\n");
......@@ -107,34 +153,6 @@ void mac_top_init_eNB(void)
pdcp_layer_init();
rrc_init_global_param();
} else {
RC.mac = NULL;
}
// Initialize Linked-List for Active UEs
for (i = 0; i < RC.nb_macrlc_inst; i++) {
mac = RC.mac[i];
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++) {
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;
}
}
void mac_init_cell_params(int Mod_idP, int CC_idP)
......
This diff is collapsed.
This diff is collapsed.
......@@ -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;
......
......@@ -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
......
This diff is collapsed.
......@@ -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];
......
......@@ -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"
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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