diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index d2a35c3bd7cd3eb8939c8d1423205c766d2e9174..2056bfaa2775f3a7cff4db5e4e7383de9629a4bb 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -267,7 +267,7 @@ void RCconfig_flexran() RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); // DEFAULT_FLEXRAN_AGENT_CACHE RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); - RC.flexran[i]->await_reconf = strcmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0; + RC.flexran[i]->node_ctrl_state = strcmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION; RC.flexran[i]->enb_id = i; } diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 60239cbbbd4d500727befee8cdf92bb5589f0cca..d32f3e660f4451dfbac12c30339ada0046f257fb 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -180,16 +180,17 @@ pthread_t new_thread(void *(*f)(void *), void *b) { int channel_container_init = 0; int flexran_agent_start(mid_t mod_id) { + flexran_agent_info_t *flexran = RC.flexran[mod_id]; int channel_id; - char *in_ip = RC.flexran[mod_id]->remote_ipv4_addr; - uint16_t in_port = RC.flexran[mod_id]->remote_port; + char *in_ip = flexran->remote_ipv4_addr; + uint16_t in_port = flexran->remote_port; - RC.flexran[mod_id]->enb_id = mod_id; + flexran->enb_id = mod_id; /* assume for the moment the monolithic case, i.e. agent can provide * information for all layers */ - RC.flexran[mod_id]->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1 - | FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2 - | FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC; + flexran->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1 + | FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2 + | FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC; /* * Initialize the channel container @@ -228,7 +229,7 @@ int flexran_agent_start(mid_t mod_id) /*Initialize the continuous stats update mechanism*/ flexran_agent_init_cont_stats_update(mod_id); - new_thread(receive_thread, RC.flexran[mod_id]); + new_thread(receive_thread, flexran); /*Initialize and register the mac xface. Must be modified later *for more flexibility in agent management */ @@ -239,8 +240,8 @@ int flexran_agent_start(mid_t mod_id) AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface)); flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface); - AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface)); - flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); + AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface)); + flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); /* * initilize a timer @@ -257,14 +258,34 @@ int flexran_agent_start(mid_t mod_id) * start the enb agent task for tx and interaction with the underlying network function */ if (!agent_task_created) { - if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, (void *) RC.flexran[mod_id]) < 0) { + if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, flexran) < 0) { LOG_E(FLEXRAN_AGENT, "Create task for FlexRAN Agent failed\n"); return -1; } agent_task_created = 1; } - - LOG_I(FLEXRAN_AGENT,"client ends\n"); + + pthread_mutex_init(&flexran->mutex_node_ctrl, NULL); + pthread_cond_init(&flexran->cond_node_ctrl, NULL); + + if (flexran->node_ctrl_state == ENB_WAIT) { + /* wait three seconds before showing message and waiting "for real". + * This way, the message is (hopefully...) the last one and the user knows + * what is happening. If the controller sends a reconfiguration message in + * the meantime, the softmodem will never wait */ + sleep(3); + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + pthread_mutex_lock(&flexran->mutex_node_ctrl); + 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); + + /* reconfigure RRC again, the agent might have changed the configuration */ + MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[mod_id]->configuration; + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg_p); + } + return 0; error: diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index ed9ee444c375bfc936e4c56014fad73dde78e562..aed8f9eb60dc386700e74fbd1eeb7e7fddd5f96b 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -42,12 +42,8 @@ #include "log.h" #include "assertions.h" -#include "enb_config.h" // for enb properties - - -/* Initiation and termination of the eNodeB agent */ +/* Initiation of the eNodeB agent */ int flexran_agent_start(mid_t mod_id); -int flexran_agent_stop(mid_t mod_id); /* * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 416f13f24168cda24ab978cc58e7560fb48d3182..0e65fe7236ea578a343f216f5fa1f11f9a28cbfe 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -39,13 +39,32 @@ void handle_reconfiguration(mid_t mod_id) { struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); + flexran_agent_info_t *flexran = RC.flexran[mod_id]; + + if (ENB_WAIT == flexran->node_ctrl_state) { + /* this is already waiting, just release */ + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_NORMAL_OPERATION; + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + pthread_cond_signal(&flexran->cond_node_ctrl); + return; + } if (stop_L1L2(mod_id) < 0) { LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); return; } - /* TODO wait state could be here IF IT IS NOT EXECUTED BY THE FLEXRAN THREAD */ + /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not + * executed by the FlexRAN thread */ + if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_WAIT; + while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) + pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + } if (restart_L1L2(mod_id) < 0) { LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index dc86a422c4825935123e047eea365e0bdf8b8b03..fd22b01e61ea0b6f4f416f5fe601772157b75c1c 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -145,17 +145,27 @@ typedef enum { #define FLEXRAN_CAP_PDCP 0x16 #define FLEXRAN_CAP_RRC 0x32 +typedef enum { + ENB_NORMAL_OPERATION = 0x0, + ENB_WAIT = 0x1, + ENB_MAKE_WAIT = 0x2, +} flexran_enb_state_t; + typedef struct { /* general info */ char *interface_name; char *remote_ipv4_addr; uint16_t remote_port; char *cache_name; - uint8_t await_reconf; int enb_id; uint8_t capability_mask; + /* lock for waiting before starting or soft-restart */ + pthread_cond_t cond_node_ctrl; + pthread_mutex_t mutex_node_ctrl; + flexran_enb_state_t node_ctrl_state; + /* stats */ uint32_t total_rx_msg; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index c8db435d4672aaf4646b8e7c660bab9cb9ff09cd..91d626c9d3c62e32abc187307f1a9de3a1e10aeb 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1149,26 +1149,6 @@ int main( int argc, char **argv ) for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { -#ifdef FLEXRAN_AGENT_SB_IF - pthread_mutex_init(&mutex_node_ctrl, NULL); - pthread_cond_init(&cond_node_ctrl, NULL); - - /* create RC.flexran data structure */ - RCconfig_flexran(); - for (i = 0; i < RC.nb_L1_inst; i++) { - flexran_agent_start(i); - } - - /* TODO handle restart/initial blocking */ - //LOG_I(ENB_APP, " * Waiting for FlexRAN RTController command *\n"); - //pthread_mutex_lock(&mutex_node_ctrl); - //while (ENB_NORMAL_OPERATION != node_control_state) - // pthread_cond_wait(&cond_node_ctrl, &mutex_node_ctrl); - //pthread_mutex_unlock(&mutex_node_ctrl); - - /* TODO do eNB reconfiguration (handled implicitly?) */ -#endif - if (UE_flag==1) { NB_UE_INST=1; NB_INST=1; @@ -1291,7 +1271,13 @@ int main( int argc, char **argv ) RCconfig_L1(); } #endif - + +#ifdef FLEXRAN_AGENT_SB_IF + RCconfig_flexran(); + for (i = 0; i < RC.nb_L1_inst; i++) { + flexran_agent_start(i); + } +#endif mlockall(MCL_CURRENT | MCL_FUTURE); @@ -1507,11 +1493,6 @@ int main( int argc, char **argv ) pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); -#ifdef FLEXRAN_AGENT_SB_IF - pthread_cond_destroy(&cond_node_ctrl); - pthread_mutex_destroy(&mutex_node_ctrl); -#endif - // *** Handle per CC_id openair0 if (UE_flag==1) { if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index c6f8d8d54c12157b586399192c0c057fd614f877..dd178c2911e6a0d636f4624d05fe4f3eef995eec 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -272,10 +272,7 @@ extern int stop_L1L2(module_id_t enb_id); extern int restart_L1L2(module_id_t enb_id); #ifdef FLEXRAN_AGENT_SB_IF -#include "flexran_agent.h" // for locking -//volatile ENB_MODULE_STATE node_control_state; -pthread_cond_t cond_node_ctrl; -pthread_mutex_t mutex_node_ctrl; +#include "flexran_agent.h" #endif #endif