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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user