From fea641220b7ca7b76715dc933b95fd0a639d8d48 Mon Sep 17 00:00:00 2001
From: Robert Schmidt <robert.schmidt@eurecom.fr>
Date: Tue, 12 Dec 2017 16:54:30 +0100
Subject: [PATCH] Start FlexRAN agent directly, lock with mutex&condition

- lock with mutexes
- don't start ENB_APP task, but Agent directly and wait in case of
  reconfiguration
---
 openair2/ENB_APP/enb_app.c                    | 31 +-------------
 openair2/ENB_APP/enb_app.h                    |  3 --
 .../ENB_APP/flexran_agent_common_internal.c   | 15 +++++--
 targets/COMMON/create_tasks.c                 | 19 ++++-----
 targets/COMMON/create_tasks.h                 |  1 -
 targets/RT/USER/lte-softmodem.c               | 40 ++++++++++++-------
 targets/RT/USER/lte-softmodem.h               |  7 ++++
 7 files changed, 54 insertions(+), 62 deletions(-)

diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index be0b88acff..5fe0f741bf 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -50,21 +50,11 @@
 # endif
 
 #if defined(FLEXRAN_AGENT_SB_IF)
-#   include "flexran_agent.h"
+#   include "targets/RT/USER/lte-softmodem.h"
 #endif
 
 extern unsigned char NB_eNB_INST;
 #endif
-extern volatile int     node_control_state;
-
-void ltesm_wait_reconfig_cmd(void)
-{
-  LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n");
-
-  while (node_control_state ==  ENB_WAIT_RECONFIGURATION_CMD) {
-    usleep(200000);
-  }
-}
 
 #if defined(ENABLE_ITTI)
 
@@ -299,7 +289,6 @@ void *eNB_app_task(void *args_p)
   uint32_t                        registered_enb;
   long                            enb_register_retry_timer_id;
 # endif
-  uint32_t                        enb_id;
   MessageDef                     *msg_p           = NULL;
   const char                     *msg_name        = NULL;
   instance_t                      instance;
@@ -328,24 +317,6 @@ void *eNB_app_task(void *args_p)
                "Number of eNB is greater than eNB defined in configuration file (%d/%d)!",
                enb_nb, enb_properties_p->number);
 
-#if defined (FLEXRAN_AGENT_SB_IF)
-  
-  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 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++) {
-    LOG_I(ENB_APP, "set again enb vars %d\n", enb_id);
-    flexran_set_enb_vars(enb_id, RAN_LTE_OAI);
-  }
-
-#endif 
-
   enb_app_start_phy_rrc(enb_id_start, enb_id_end);
   
 # if defined(ENABLE_USE_MME)
diff --git a/openair2/ENB_APP/enb_app.h b/openair2/ENB_APP/enb_app.h
index be5adfbb34..441693ab31 100644
--- a/openair2/ENB_APP/enb_app.h
+++ b/openair2/ENB_APP/enb_app.h
@@ -38,7 +38,4 @@ 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_ */
diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c
index e77557e9ee..c2bd396e36 100644
--- a/openair2/ENB_APP/flexran_agent_common_internal.c
+++ b/openair2/ENB_APP/flexran_agent_common_internal.c
@@ -36,25 +36,34 @@
 #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 */
+  int do_restart = 0;
 
+  pthread_mutex_lock(&mutex_node_ctrl);
   if (ENB_NORMAL_OPERATION != node_control_state) {
     node_control_state = ENB_NORMAL_OPERATION;
+    pthread_cond_broadcast(&cond_node_ctrl);
   } else {
+    do_restart = 1;
+  }
+  pthread_mutex_unlock(&mutex_node_ctrl);
+
+  if (do_restart) {
+    clock_t start_ms = 1000 * clock();
+    /* operator || enforces sequence points */
     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 diff_ms = (1000 * clock() - start_ms) / CLOCKS_PER_SEC;
+    LOG_I(ENB_APP, "lte-softmodem restart succeeded in %d ms\n", diff_ms);
   }
 }
 
diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c
index 1ca55b5926..c28b9e839c 100644
--- a/targets/COMMON/create_tasks.c
+++ b/targets/COMMON/create_tasks.c
@@ -40,17 +40,6 @@
 # endif
 # include "enb_app.h"
 
-int create_enb_app_task(uint32_t enb_nb)
-{
-  if (enb_nb > 0) {
-    if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) {
-      LOG_E(ENB_APP, "Create task for eNB APP failed\n");
-      return -1;
-    }
-  }
-  return 0;
-}
-
 int create_tasks(uint32_t enb_nb, uint32_t ue_nb)
 {
   itti_wait_ready(1);
@@ -59,6 +48,14 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb)
     return -1;
   }
 
+  if (enb_nb > 0) {
+    /* Last task to create, others task must be ready before its start */
+    if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) {
+      LOG_E(ENB_APP, "Create task for eNB APP failed\n");
+      return -1;
+    }
+  }
+
 
 # ifdef OPENAIR2
   {
diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h
index 3455b283b5..6545f4b9d9 100644
--- a/targets/COMMON/create_tasks.h
+++ b/targets/COMMON/create_tasks.h
@@ -27,7 +27,6 @@
 extern void *l2l1_task(void *arg);
 
 int create_tasks(uint32_t enb_nb, uint32_t ue_nb);
-int create_enb_app_task(uint32_t enb_nb);
 #endif
 
 #endif /* CREATE_TASKS_H_ */
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index f881441cdb..39f40733f2 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -174,8 +174,6 @@ eNB_func_t node_function[MAX_NUM_CCs];
 eNB_timing_t node_timing[MAX_NUM_CCs];
 int16_t   node_synch_ref[MAX_NUM_CCs];
 
-volatile int16_t   node_control_state;
-
 uint32_t target_dl_mcs = 28; //maximum allowed mcs
 uint32_t target_ul_mcs = 20;
 uint32_t timing_advance = 0;
@@ -234,9 +232,7 @@ threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
  */
 uint8_t abstraction_flag=0;
 
-/*  */
-
-/* overrid the enb configuration params*/ 
+/* override the enb configuration parameters */
 static void reconfigure_enb_params(int enb_id);
 
 
@@ -1097,11 +1093,13 @@ static void get_options (int argc, char **argv) {
                          "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!",
                          MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i);
 
+#ifdef FLEXRAN_AGENT_SB_IF
 	    if (enb_properties->properties[i]->flexran_agent_reconf == 1) {
 	      node_control_state  = ENB_WAIT_RECONFIGURATION_CMD;
 	    } else {
 	      node_control_state  = ENB_NORMAL_OPERATION;
 	    }
+#endif
 		
             eth_params = (eth_params_t*)malloc(enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t));
             memset(eth_params, 0, enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t));
@@ -1796,19 +1794,28 @@ int main( int argc, char **argv ) {
         // N_ZC = (prach_fmt <4)?839:139;
     }
 
-    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
+    pthread_mutex_init(&mutex_node_ctrl, NULL);
+    pthread_cond_init(&cond_node_ctrl, NULL);
+
+    for (i = 0; i < NB_eNB_INST; i++) {
+      flexran_agent_start(i, enb_config_get());
+    }
+
+    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);
 
-    // 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 in case FlexRAN controller applied changes */
+    for (i=0; i < NB_eNB_INST; i++){
+      LOG_I(ENB_APP, "Reconfigure eNB module %d and FlexRAN eNB variables\n", i);
       reconfigure_enb_params(i);
-      printf("[ENB_APP] Reconfigured eNB module %d - continue\n", i);
+      flexran_set_enb_vars(i, RAN_LTE_OAI);
     }
-    
+#endif
+
     if (UE_flag==1) {
         NB_UE_INST=1;
         NB_INST=1;
@@ -2175,6 +2182,10 @@ int main( int argc, char **argv ) {
         stop_eNB(1);
     }
 
+#ifdef FLEXRAN_AGENT_SB_IF
+    pthread_cond_destroy(&cond_node_ctrl);
+    pthread_mutex_destroy(&mutex_node_ctrl);
+#endif
 
     pthread_cond_destroy(&sync_cond);
     pthread_mutex_destroy(&sync_mutex);
@@ -2200,5 +2211,6 @@ int main( int argc, char **argv ) {
 
     logClean();
 
+    printf("Bye.\n");
     return 0;
 }
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index a0883c3d59..4dbdd2a40a 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -92,4 +92,11 @@ 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);
 
+#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;
+#endif
+
 #endif
-- 
GitLab