Commit 3f043c7d authored by Robert Schmidt's avatar Robert Schmidt

FlexRAN: implement possibilty to await a configuration

Through configuration, the lte-softmodem can be halted to await a
reconfiguration from the lte-softmodem. A mutex and condition variable are used
to implement this.

Furthermore, the dependance of lte-softmodem.c on FlexRAN has been reduced to
one include and the flexran_agent_start() call.
parent 811ada24
...@@ -267,7 +267,7 @@ void RCconfig_flexran() ...@@ -267,7 +267,7 @@ void RCconfig_flexran()
RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr);
// DEFAULT_FLEXRAN_AGENT_CACHE // DEFAULT_FLEXRAN_AGENT_CACHE
RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); 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; RC.flexran[i]->enb_id = i;
} }
......
...@@ -180,16 +180,17 @@ pthread_t new_thread(void *(*f)(void *), void *b) { ...@@ -180,16 +180,17 @@ pthread_t new_thread(void *(*f)(void *), void *b) {
int channel_container_init = 0; int channel_container_init = 0;
int flexran_agent_start(mid_t mod_id) int flexran_agent_start(mid_t mod_id)
{ {
flexran_agent_info_t *flexran = RC.flexran[mod_id];
int channel_id; int channel_id;
char *in_ip = RC.flexran[mod_id]->remote_ipv4_addr; char *in_ip = flexran->remote_ipv4_addr;
uint16_t in_port = RC.flexran[mod_id]->remote_port; 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 /* assume for the moment the monolithic case, i.e. agent can provide
* information for all layers */ * information for all layers */
RC.flexran[mod_id]->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1 flexran->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1
| FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2 | FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2
| FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC; | FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC;
/* /*
* Initialize the channel container * Initialize the channel container
...@@ -228,7 +229,7 @@ int flexran_agent_start(mid_t mod_id) ...@@ -228,7 +229,7 @@ int flexran_agent_start(mid_t mod_id)
/*Initialize the continuous stats update mechanism*/ /*Initialize the continuous stats update mechanism*/
flexran_agent_init_cont_stats_update(mod_id); 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 /*Initialize and register the mac xface. Must be modified later
*for more flexibility in agent management */ *for more flexibility in agent management */
...@@ -239,8 +240,8 @@ int flexran_agent_start(mid_t mod_id) ...@@ -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)); AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface));
flexran_agent_register_rrc_xface(mod_id, rrc_agent_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)); AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface));
flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface);
/* /*
* initilize a timer * initilize a timer
...@@ -257,14 +258,34 @@ int flexran_agent_start(mid_t mod_id) ...@@ -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 * start the enb agent task for tx and interaction with the underlying network function
*/ */
if (!agent_task_created) { 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"); LOG_E(FLEXRAN_AGENT, "Create task for FlexRAN Agent failed\n");
return -1; return -1;
} }
agent_task_created = 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; return 0;
error: error:
......
...@@ -42,12 +42,8 @@ ...@@ -42,12 +42,8 @@
#include "log.h" #include "log.h"
#include "assertions.h" #include "assertions.h"
#include "enb_config.h" // for enb properties /* Initiation of the eNodeB agent */
/* Initiation and termination of the eNodeB agent */
int flexran_agent_start(mid_t mod_id); 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 * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller
......
...@@ -39,13 +39,32 @@ void handle_reconfiguration(mid_t mod_id) ...@@ -39,13 +39,32 @@ void handle_reconfiguration(mid_t mod_id)
{ {
struct timespec start, end; struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start); 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) { if (stop_L1L2(mod_id) < 0) {
LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n");
return; 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) { if (restart_L1L2(mod_id) < 0) {
LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n");
......
...@@ -145,17 +145,27 @@ typedef enum { ...@@ -145,17 +145,27 @@ typedef enum {
#define FLEXRAN_CAP_PDCP 0x16 #define FLEXRAN_CAP_PDCP 0x16
#define FLEXRAN_CAP_RRC 0x32 #define FLEXRAN_CAP_RRC 0x32
typedef enum {
ENB_NORMAL_OPERATION = 0x0,
ENB_WAIT = 0x1,
ENB_MAKE_WAIT = 0x2,
} flexran_enb_state_t;
typedef struct { typedef struct {
/* general info */ /* general info */
char *interface_name; char *interface_name;
char *remote_ipv4_addr; char *remote_ipv4_addr;
uint16_t remote_port; uint16_t remote_port;
char *cache_name; char *cache_name;
uint8_t await_reconf;
int enb_id; int enb_id;
uint8_t capability_mask; 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 */ /* stats */
uint32_t total_rx_msg; uint32_t total_rx_msg;
......
...@@ -1149,26 +1149,6 @@ int main( int argc, char **argv ) ...@@ -1149,26 +1149,6 @@ int main( int argc, char **argv )
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { 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) { if (UE_flag==1) {
NB_UE_INST=1; NB_UE_INST=1;
NB_INST=1; NB_INST=1;
...@@ -1291,7 +1271,13 @@ int main( int argc, char **argv ) ...@@ -1291,7 +1271,13 @@ int main( int argc, char **argv )
RCconfig_L1(); RCconfig_L1();
} }
#endif #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); mlockall(MCL_CURRENT | MCL_FUTURE);
...@@ -1507,11 +1493,6 @@ int main( int argc, char **argv ) ...@@ -1507,11 +1493,6 @@ int main( int argc, char **argv )
pthread_cond_destroy(&sync_cond); pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex); 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 // *** Handle per CC_id openair0
if (UE_flag==1) { if (UE_flag==1) {
if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func)
......
...@@ -272,10 +272,7 @@ extern int stop_L1L2(module_id_t enb_id); ...@@ -272,10 +272,7 @@ extern int stop_L1L2(module_id_t enb_id);
extern int restart_L1L2(module_id_t enb_id); extern int restart_L1L2(module_id_t enb_id);
#ifdef FLEXRAN_AGENT_SB_IF #ifdef FLEXRAN_AGENT_SB_IF
#include "flexran_agent.h" // for locking #include "flexran_agent.h"
//volatile ENB_MODULE_STATE node_control_state;
pthread_cond_t cond_node_ctrl;
pthread_mutex_t mutex_node_ctrl;
#endif #endif
#endif #endif
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