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,75 +120,116 @@ int ret;
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
{
void *lib_handle;
initfunc_t fpi;
checkverfunc_t fpc;
getfarrayfunc_t fpg;
char *shlib_path;
char *afname=NULL;
int ret=0;
if (loader_data.shlibpath == NULL) {
loader_init();
}
void *lib_handle = NULL;
initfunc_t fpi;
checkverfunc_t fpc;
getfarrayfunc_t fpg;
char *shlib_path = NULL;
char *afname = NULL;
int ret = 0;
int lib_idx = -1;
if (!modname) {
fprintf(stderr, "[LOADER] load_module_shlib(): no library name given\n");
return -1;
}
shlib_path = loader_format_shlibpath(modname);
if (!loader_data.shlibpath) {
loader_init();
}
ret = 0;
lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
if (!lib_handle) {
fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror());
shlib_path = loader_format_shlibpath(modname);
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;
} else {
printf("[LOADER] library %s successfully loaded\n", shlib_path);
afname=malloc(strlen(modname)+15);
sprintf(afname,"%s_checkbuildver",modname);
fpc = dlsym(lib_handle,afname);
if (fpc != NULL ){
int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion));
if (chkver_ret < 0) {
fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname);
exit_fun("[LOADER] unrecoverable error");
}
}
sprintf(afname,"%s_autoinit",modname);
fpi = dlsym(lib_handle,afname);
goto load_module_shlib_exit;
}
loader_data.shlibs[lib_idx].name = strdup(modname);
loader_data.shlibs[lib_idx].thisshlib_path = strdup(shlib_path);
}
if (fpi != NULL ) {
fpi(autoinit_arg);
}
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;
goto load_module_shlib_exit;
}
printf("[LOADER] library %s successfully loaded\n", shlib_path);
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) {
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);
ret = -1;
goto load_module_shlib_exit;
}
}
sprintf(afname,"%s_autoinit",modname);
fpi = dlsym(lib_handle,afname);
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++) {
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 */
} /* 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));
}
} /* 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);
return ret;
if (fpi) {
fpi(autoinit_arg);
}
if (farray) {
if (!loader_data.shlibs[lib_idx].funcarray) {
loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t));
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) {
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) {
loader_data.shlibs[lib_idx].numfunc =
fpg(&(loader_data.shlibs[lib_idx].funcarray));
}
} /* farray ! NULL */
load_module_shlib_exit:
if (shlib_path) free(shlib_path);
if (afname) free(afname);
if (lib_handle) dlclose(lib_handle);
return ret;
}
void * get_shlibmodule_fptr(char *modname, char *fname)
......
......@@ -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);
......
......@@ -58,6 +58,87 @@ enum flex_qam {
FLEQ_MOD_64QAM = 1;
}
//
// Slice config related structures and enums
//
enum flex_dl_sorting {
CR_ROUND = 0; // Highest HARQ first
CR_SRB12 = 1; // Highest SRB1+2 first
CR_HOL = 2; // Highest HOL first
CR_LC = 3; // Greatest RLC buffer first
CR_CQI = 4; // Highest CQI first
CR_LCP = 5; // Highest LC priority first
}
enum flex_ul_sorting {
CRU_ROUND = 0; // Highest HARQ first
CRU_BUF = 1; // Highest BSR first
CRU_BTS = 2; // More bytes to schedule first
CRU_MCS = 3; // Highest MCS first
CRU_LCP = 4; // Highest LC priority first
CRU_HOL = 5; // Highest HOL first
}
enum flex_dl_accounting_policy {
POL_FAIR = 0;
POL_GREEDY = 1;
POL_NUM = 2;
}
enum flex_ul_accounting_policy {
POLU_FAIR = 0;
POLU_GREEDY = 1;
POLU_NUM = 2;
}
enum flex_slice_label {
xMBB = 0;
URLLC = 1;
mMTC = 2;
xMTC = 3;
Other = 4;
}
message flex_dl_slice {
optional uint32 id = 1;
optional flex_slice_label label = 2;
// should be between 0 and 100
optional uint32 percentage = 3;
// whether this slice should be exempted form interslice sharing
optional bool isolation = 4;
// increasing value means increasing prio
optional uint32 priority = 5;
// min and max RB to use (in frequency) in the range [0, N_RBG_MAX]
optional uint32 position_low = 6;
optional uint32 position_high = 7;
// maximum MCS to be allowed in this slice
optional uint32 maxmcs = 8;
repeated flex_dl_sorting sorting = 9;
optional flex_dl_accounting_policy accounting = 10;
optional string scheduler_name = 11;
}
message flex_ul_slice {
optional uint32 id = 1;
optional flex_slice_label label = 2;
// should be between 0 and 100
optional uint32 percentage = 3;
// whether this slice should be exempted form interslice sharing
optional bool isolation = 4;
// increasing value means increasing prio
optional uint32 priority = 5;
// RB start to use (in frequency) in the range [0, N_RB_MAX]
optional uint32 first_rb = 6;
// TODO RB number
//optional uint32 length_rb = 7;
// maximum MCS to be allowed in this slice
optional uint32 maxmcs = 8;
repeated flex_ul_sorting sorting = 9;
optional flex_ul_accounting_policy accounting = 10;
optional string scheduler_name = 11;
}
//
// UE config related structures and enums
//
......@@ -177,4 +258,4 @@ enum flex_ue_state_change_type {
FLUESC_ACTIVATED = 1;
FLUESC_DEACTIVATED = 2;
FLUESC_MOVED = 3;
}
\ No newline at end of file
}
......@@ -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;
char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
long rxPool_ResourceConfig_subframeBitmap_choice_bs_size;
long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
//SIB19
//for discRxPool
SL_CP_Len_r12_t discRxPool_cp_Len;
e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPool_discPeriod;
long discRxPool_numRetx;
long discRxPool_numRepetition;
long discRxPool_ResourceConfig_prb_Num;
long discRxPool_ResourceConfig_prb_Start;
long discRxPool_ResourceConfig_prb_End;
SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present;
long discRxPool_ResourceConfig_offsetIndicator_choice;
SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present;
char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size;
long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;