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; ...@@ -57,14 +57,13 @@ extern unsigned char NB_eNB_INST;
#endif #endif
extern volatile int node_control_state; 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"); LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n");
while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) {
usleep(200000); usleep(200000);
} }
sleep(2); // wait for createing other tasks
} }
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
...@@ -202,6 +201,15 @@ static void configure_rrc(uint32_t enb_id, const Enb_properties_array_t *enb_pro ...@@ -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); 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) # 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) 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) ...@@ -325,8 +333,10 @@ void *eNB_app_task(void *args_p)
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
flexran_agent_start(enb_id, enb_properties_p); flexran_agent_start(enb_id, enb_properties_p);
} }
// wait for config comd from the controller/network app // wait for config comd from the controller/network app plus some time so
enb_app_wait_reconfig_cmd(); // that the other Tasks are in place
ltesm_wait_reconfig_cmd();
sleep(2);
// set again the ran api vars // set again the ran api vars
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
...@@ -336,11 +346,7 @@ void *eNB_app_task(void *args_p) ...@@ -336,11 +346,7 @@ void *eNB_app_task(void *args_p)
#endif #endif
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { enb_app_start_phy_rrc(enb_id_start, enb_id_end);
configure_phy(enb_id, enb_properties_p);
configure_rrc(enb_id, enb_properties_p);
}
# if defined(ENABLE_USE_MME) # if defined(ENABLE_USE_MME)
/* Try to register each eNB */ /* Try to register each eNB */
......
...@@ -30,8 +30,15 @@ ...@@ -30,8 +30,15 @@
#ifndef ENB_APP_H_ #ifndef ENB_APP_H_
#define ENB_APP_H_ #define ENB_APP_H_
#include <stdint.h>
void *eNB_app_task(void *args_p); 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_ */ #endif /* ENB_APP_H_ */
...@@ -31,8 +31,33 @@ ...@@ -31,8 +31,33 @@
#include "flexran_agent_common_internal.h" #include "flexran_agent_common_internal.h"
#include "flexran_agent_mac_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; 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) { int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) {
yaml_parser_t parser; yaml_parser_t parser;
...@@ -72,8 +97,7 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy ...@@ -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) { if (parse_enb_id(mod_id, &parser) == -1) {
goto error; goto error;
} else { // succeful parse and setting } else { // succeful parse and setting
node_control_state= ENB_NORMAL_OPERATION; handle_reconfiguration(mod_id);
LOG_I(ENB_APP, "Successful parsed config for enb system, entering normal state\n");
} }
} else if (strcmp((char *) event.data.scalar.value, "mac") == 0) { } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) {
LOG_D(ENB_APP, "This is intended for the mac system\n"); LOG_D(ENB_APP, "This is intended for the mac system\n");
......
...@@ -1487,19 +1487,129 @@ void fill_PHY_vars_eNB_g(uint8_t abstraction_flag, uint8_t beta_ACK, uint8_t bet ...@@ -1487,19 +1487,129 @@ 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 defined(ENABLE_ITTI) && defined(FLEXRAN_AGENT_SB_IF)
* if needed override the current configuration parameters, such as /*
* frequencies, bands, power, bandwidth * 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;
while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { LOG_W(ENB_APP, "stopping lte-softmodem\n");
usleep(200000);
/* 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 */
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 main( int argc, char **argv ) {
int i,aa; int i,aa;
#if defined (XFORMS) #if defined (XFORMS)
...@@ -1689,7 +1799,12 @@ int main( int argc, char **argv ) { ...@@ -1689,7 +1799,12 @@ int main( int argc, char **argv ) {
} }
create_enb_app_task(UE_flag ? 0 : 1); 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 (); ltesm_wait_reconfig_cmd ();
#endif
// reconfigure_enb: 0 for wait, 1 for skip, and other values to reconfigure // 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++){ for (i=0; (i < NB_eNB_INST && node_control_state == ENB_NORMAL_OPERATION ) ; i++){
reconfigure_enb_params(i); reconfigure_enb_params(i);
......
...@@ -89,4 +89,7 @@ extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); ...@@ -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_td_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_te_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 #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