Commit c619f6ef authored by Robert Schmidt's avatar Robert Schmidt

Feature: Provide restart for lte-softmodem

- {restart,stop}_L1L2() in lte-softmodem.c
- add function start_phy_rrc() in enb_app.{c,h}, accessible from outside
- will be used to restart PHY and RRC when lte-softmodem is restarted

use only one FlexRAN wait function
parent e88a3cdf
......@@ -57,14 +57,13 @@ extern unsigned char NB_eNB_INST;
#endif
extern volatile int node_control_state;
static void enb_app_wait_reconfig_cmd (void)
void ltesm_wait_reconfig_cmd(void)
{
LOG_I(ENB_APP, "ENB APP await reconfiguration command\n");
while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) {
LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n");
while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) {
usleep(200000);
}
sleep(2); // wait for createing other tasks
}
#if defined(ENABLE_ITTI)
......@@ -202,6 +201,15 @@ static void configure_rrc(uint32_t enb_id, const Enb_properties_array_t *enb_pro
itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
}
void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end)
{
Enb_properties_array_t *enb_properties_p = enb_config_get();
for (uint32_t enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
configure_phy(enb_id, enb_properties_p);
configure_rrc(enb_id, enb_properties_p);
}
}
/*------------------------------------------------------------------------------*/
# if defined(ENABLE_USE_MME)
static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, const Enb_properties_array_t *enb_properties)
......@@ -325,8 +333,10 @@ void *eNB_app_task(void *args_p)
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
flexran_agent_start(enb_id, enb_properties_p);
}
// wait for config comd from the controller/network app
enb_app_wait_reconfig_cmd();
// wait for config comd from the controller/network app plus some time so
// that the other Tasks are in place
ltesm_wait_reconfig_cmd();
sleep(2);
// set again the ran api vars
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
......@@ -336,11 +346,7 @@ void *eNB_app_task(void *args_p)
#endif
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
configure_phy(enb_id, enb_properties_p);
configure_rrc(enb_id, enb_properties_p);
}
enb_app_start_phy_rrc(enb_id_start, enb_id_end);
# if defined(ENABLE_USE_MME)
/* Try to register each eNB */
......
......@@ -30,8 +30,15 @@
#ifndef ENB_APP_H_
#define ENB_APP_H_
#include <stdint.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);
/* wait that FlexRAN left state ENB_WAIT_RECONFIGURATION_CMD */
void ltesm_wait_reconfig_cmd(void);
#endif /* ENB_APP_H_ */
......@@ -31,8 +31,33 @@
#include "flexran_agent_common_internal.h"
#include "flexran_agent_mac_internal.h"
/* the following is needed to soft-restart the lte-softmodem */
#include "targets/RT/USER/lte-softmodem.h"
#include "assertions.h"
#include "enb_app.h"
extern volatile int node_control_state;
void handle_reconfiguration(mid_t mod_id)
{
/* NOTE: this function might be extended by using stop_modem()
* to halt the modem so that it can later be resumed */
if (ENB_NORMAL_OPERATION != node_control_state) {
node_control_state = ENB_NORMAL_OPERATION;
} else {
if (stop_L1L2(mod_id) < 0 || restart_L1L2(mod_id) < 0) {
LOG_E(ENB_APP, "could not restart, killing lte-softmodem\n");
/* shutdown the whole lte-softmodem */
itti_terminate_tasks(TASK_PHY_ENB);
return;
}
enb_app_start_phy_rrc(mod_id, mod_id+1);
LOG_I(ENB_APP, "lte-softmodem restart succeeded\n");
}
}
int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) {
yaml_parser_t parser;
......@@ -72,8 +97,7 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy
if (parse_enb_id(mod_id, &parser) == -1) {
goto error;
} else { // succeful parse and setting
node_control_state= ENB_NORMAL_OPERATION;
LOG_I(ENB_APP, "Successful parsed config for enb system, entering normal state\n");
handle_reconfiguration(mod_id);
}
} else if (strcmp((char *) event.data.scalar.value, "mac") == 0) {
LOG_D(ENB_APP, "This is intended for the mac system\n");
......
......@@ -1487,18 +1487,128 @@ void fill_PHY_vars_eNB_g(uint8_t abstraction_flag, uint8_t beta_ACK, uint8_t bet
}
}
/* check the state : either continue or wait for a command to start/stop the eNB
* if needed override the current configuration parameters, such as
* frequencies, bands, power, bandwidth
#if defined(ENABLE_ITTI) && defined(FLEXRAN_AGENT_SB_IF)
/*
* helper function to terminate a certain ITTI task
*/
static void ltesm_wait_reconfig_cmd(void)
void terminate_task(task_id_t task_id, mid_t mod_id)
{
LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n");
LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id);
MessageDef *msg;
msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE);
itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
}
int stop_L1L2(int enb_id)
{
int CC_id;
LOG_W(ENB_APP, "stopping lte-softmodem\n");
/* stop trx devices */
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_stop_func) {
LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->rfdevice (via trx_stop_func())\n", CC_id);
PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);
}
if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func) {
LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->ifdevice (via trx_stop_func())\n", CC_id);
PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);
}
}
/* these tasks need to pick up new configuration */
terminate_task(TASK_RRC_ENB, enb_id);
terminate_task(TASK_L2L1, enb_id);
oai_exit = 1;
LOG_W(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id);
kill_eNB_proc(enb_id);
/* give some time for all threads */
sleep(1);
return 0;
}
/*
* Restart the lte-softmodem.
* This function checks whether we are in ENB_NORMAL_OPERATION (defined by
* FlexRAN). If yes, first stop L1/L2/L3, then resume.
*/
int restart_L1L2(int enb_id)
{
int i, aa, CC_id;
/* needed for fill_PHY_vars_eNB_g(), defined locally in main();
* abstraction flag is needed too, but defined both globally and in main () */
uint8_t beta_ACK = 0, beta_RI = 0, beta_CQI = 2;
/* needed for macphy_init() */
int eMBMS_active = 0;
LOG_W(ENB_APP, "restarting lte-softmodem\n");
/* block threads */
sync_var = -1;
oai_exit = 0;
reconfigure_enb_params(enb_id); /* set frame parameters from configuration */
/* PHY_vars_eNB_g will be filled by init_lte_eNB(), so free and
* let the data structure be filled again */
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
free(PHY_vars_eNB_g[0][CC_id]);
fill_PHY_vars_eNB_g(abstraction_flag, beta_ACK, beta_RI, beta_CQI);
}
dump_frame_parms(frame_parms[0]);
init_openair0();
/* give MAC interface current cell information, the rest is the same.
* For more info, check l2_init(). Then, initialize it (cf. line 1904). */
mac_xface->frame_parms = frame_parms[0];
mac_xface->macphy_init(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,0,0);
LOG_I(ENB_APP, "attempting to create ITTI tasks\n");
if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC eNB failed\n");
return -1;
} else {
LOG_I(RRC, "Re-created task for RRC eNB successfully\n");
}
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
LOG_E(PDCP, "Create task for L2L1 failed\n");
return -1;
} else {
LOG_I(PDCP, "Re-created task for L2L1 successfully\n");
}
/* TODO XForms here */
while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) {
usleep(200000);
printf("Initializing eNB threads\n");
init_eNB(node_function, node_timing, 1, eth_params, single_thread_flag, wait_for_sync);
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_eNB_g[0][CC_id]->rf_map.card=0;
PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
}
mlockall(MCL_CURRENT | MCL_FUTURE);
printf("Setting eNB buffer to all-RX\n");
// Set LSBs for antenna switch (ExpressMIMO)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_eNB_g[0][CC_id]->hw_timing_advance = 0;
for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001;
}
printf("Sending sync to all threads\n");
pthread_mutex_lock(&sync_mutex);
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
return 0;
}
#endif
int main( int argc, char **argv ) {
int i,aa;
......@@ -1689,7 +1799,12 @@ int main( int argc, char **argv ) {
}
create_enb_app_task(UE_flag ? 0 : 1);
#ifdef FLEXRAN_AGENT_SB_IF
/* wait command for flexran agent: only start when configuration received */
ltesm_wait_reconfig_cmd ();
#endif
// reconfigure_enb: 0 for wait, 1 for skip, and other values to reconfigure
for (i=0; (i < NB_eNB_INST && node_control_state == ENB_NORMAL_OPERATION ) ; i++){
reconfigure_enb_params(i);
......
......@@ -89,4 +89,7 @@ extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern int stop_L1L2(int enb_id);
extern int restart_L1L2(int enb_id);
#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