From 612ab055d7b97e02503f2f1143ba2092c3a1cd9b Mon Sep 17 00:00:00 2001
From: Navid Nikaein <navid.nikaein@eurecom.fr>
Date: Wed, 6 Dec 2017 12:23:16 +0100
Subject: [PATCH] Add control logic to reconfigure and start eNB

---
 openair2/ENB_APP/enb_app.c                    |  34 ++++-
 openair2/ENB_APP/enb_config.c                 |  22 ++-
 openair2/ENB_APP/enb_config.h                 |  11 +-
 .../ENB_APP/flexran_agent_common_internal.c   |   9 +-
 .../LAYER2/MAC/eNB_scheduler_primitives.c     |   4 +
 targets/COMMON/create_tasks.c                 |  19 ++-
 targets/COMMON/create_tasks.h                 |   1 +
 .../CONF/enb.band7.flexran.usrpb210.conf      |   6 +-
 targets/RT/USER/lte-softmodem.c               | 143 ++++++++++++------
 9 files changed, 174 insertions(+), 75 deletions(-)

diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index de0d0490aa..4a5981f509 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -55,6 +55,17 @@
 
 extern unsigned char NB_eNB_INST;
 #endif
+extern volatile int     node_control_state;
+
+static void enb_app_wait_reconfig_cmd (void)
+{
+  LOG_I(ENB_APP, "ENB APP await reconfiguration command\n");
+   
+  while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) {
+    usleep(200000);
+  }
+  sleep(2); // wait for createing other tasks
+}
 
 #if defined(ENABLE_ITTI)
 
@@ -270,7 +281,7 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, con
 /*------------------------------------------------------------------------------*/
 void *eNB_app_task(void *args_p)
 {
-  const Enb_properties_array_t   *enb_properties_p  = NULL;
+  Enb_properties_array_t   *enb_properties_p  = NULL;
 #if defined(ENABLE_ITTI)
   uint32_t                        enb_nb = 1; /* Default number of eNB is 1 */
   uint32_t                        enb_id_start = 0;
@@ -309,19 +320,28 @@ 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);
 
-  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);
-  }
-
 #if defined (FLEXRAN_AGENT_SB_IF)
   
   for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
-    printf("\n start enb agent %d\n", enb_id);
     flexran_agent_start(enb_id, enb_properties_p);
   }
+  // wait for config comd from the controller/network app
+  enb_app_wait_reconfig_cmd();
+  
+  // set again the ran api vars  
+  for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
+    printf("\n set again enb vars %d\n", enb_id);
+    flexran_set_enb_vars(enb_id, RAN_LTE_OAI);
+  }
+
 #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);
+  }
+
+  
 # if defined(ENABLE_USE_MME)
   /* Try to register each eNB */
   registered_enb = 0;
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 09d7495a69..6282523b55 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -197,6 +197,7 @@
 #define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS        "FLEXRAN_AGENT_IPV4_ADDRESS"
 #define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT                "FLEXRAN_AGENT_PORT"
 #define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE               "FLEXRAN_AGENT_CACHE"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_AWAIT_RECONF        "FLEXRAN_AGENT_AWAIT_RECONF"
 
 #define ENB_CONFIG_STRING_RRH_GW_CONFIG                   "rrh_gw_config"
 #define ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME            "local_if_name"
@@ -351,6 +352,8 @@ void enb_config_display(void)
     //    printf( "\tInterface IP Address:     \t%s:\n",enb_properties.properties[i]->flexran_agent_ipv4_address);
     printf( "\tInterface PORT:           \t%d:\n\n",enb_properties.properties[i]->flexran_agent_port);
     printf( "\tCache directory:          \t%s:\n",enb_properties.properties[i]->flexran_agent_cache);
+    printf( "\teNB Control State:        \t%s:\n",(enb_properties.properties[i]->flexran_agent_reconf==0)? "ENB_NORMAL_OPERATION":"ENB_WAIT_RECONFIGURATION_CMD");
+    
     
 #endif 
 
@@ -536,7 +539,7 @@ extern int asn1_xer_print;
 #else
 #define libconfig_int int
 #endif
-const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
+Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
 {
   config_t          cfg;
   config_setting_t *setting                       = NULL;
@@ -689,6 +692,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
   char*             flexran_agent_ipv4_address        = NULL;
   libconfig_int     flexran_agent_port                = 0;
   char*             flexran_agent_cache               = NULL;
+  char*             flexran_agent_reconf              = NULL;
+  
   libconfig_int     otg_ue_id                     = 0;
   char*             otg_app_type                  = NULL;
   char*             otg_bg_traffic                = NULL;
@@ -2580,6 +2585,9 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
                                                 &flexran_agent_port)
 		   && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE,
 						    (const char **)&flexran_agent_cache)
+		   && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_AWAIT_RECONF,
+						    (const char **)&flexran_agent_reconf)
+		   
                  )
               ) {
               enb_properties.properties[enb_properties_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name);
@@ -2590,8 +2598,14 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
                 IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties.properties[enb_properties_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" );
 	      }
 
-              enb_properties.properties[enb_properties_index]->flexran_agent_port = flexran_agent_port;
-	      enb_properties.properties[enb_properties_index]->flexran_agent_cache = strdup(flexran_agent_cache);
+              enb_properties.properties[enb_properties_index]->flexran_agent_port   = flexran_agent_port;
+	      enb_properties.properties[enb_properties_index]->flexran_agent_cache  = strdup(flexran_agent_cache);
+	      if ((strcmp(flexran_agent_reconf, "yes") == 0) || (strcmp(flexran_agent_reconf, "YES") == 0)){
+		enb_properties.properties[enb_properties_index]->flexran_agent_reconf = 1;
+	      } else {
+		enb_properties.properties[enb_properties_index]->flexran_agent_reconf = 0;
+	      }
+	      
             }
           }
 	  
@@ -2885,7 +2899,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
 
 }
 
-const Enb_properties_array_t *enb_config_get(void)
+Enb_properties_array_t *enb_config_get(void)
 {
   return &enb_properties;
 }
diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h
index 094360749b..8e914458bf 100644
--- a/openair2/ENB_APP/enb_config.h
+++ b/openair2/ENB_APP/enb_config.h
@@ -237,6 +237,8 @@ typedef struct Enb_properties_s {
   in_addr_t           flexran_agent_ipv4_address;
   tcp_udp_port_t      flexran_agent_port;
   char               *flexran_agent_cache;
+  int                flexran_agent_reconf;
+  
 
   /* Nb of RRH to connect to */
   uint8_t             nb_rrh_gw;
@@ -276,15 +278,20 @@ typedef struct Enb_properties_s {
 #endif
 } Enb_properties_t;
 
+typedef enum {
+  ENB_NORMAL_OPERATION=0x0,
+  ENB_WAIT_RECONFIGURATION_CMD=0x1
+} ENB_MODULE_STATE;
+
 typedef struct Enb_properties_array_s {
   int                  number;
   Enb_properties_t    *properties[MAX_ENB];
 } Enb_properties_array_t;
 
 void                          enb_config_display(void);
-const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP);
+Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP);
 
-const Enb_properties_array_t *enb_config_get(void);
+Enb_properties_array_t *enb_config_get(void);
 
 #endif /* ENB_CONFIG_H_ */
 /** @} */
diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c
index 839fb4c784..c883523855 100644
--- a/openair2/ENB_APP/flexran_agent_common_internal.c
+++ b/openair2/ENB_APP/flexran_agent_common_internal.c
@@ -31,7 +31,7 @@
 
 #include "flexran_agent_common_internal.h"
 #include "flexran_agent_mac_internal.h"
-extern volatile int             reconfigure_enb;
+extern volatile int    node_control_state;
 
 int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) {
 
@@ -72,8 +72,8 @@ 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 
-      LOG_I(ENB_APP, "Successful parsed config for enb system\n");
-      //reconfigure_enb=RECONF_FREQ;
+	  node_control_state= ENB_NORMAL_OPERATION;
+	  LOG_I(ENB_APP, "Successful parsed config for enb system, entering normal state\n");
 	}
       } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) {
 	LOG_D(ENB_APP, "This is intended for the mac system\n");
@@ -258,6 +258,9 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) {
     yaml_event_delete(&event);
   }
 
+  /* reflect in RAN API */
+  flexran_set_enb_vars(mod_id, RAN_LTE_OAI);
+
   return 0;
   
  error:
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 610700f3e8..a678178435 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -131,6 +131,7 @@ int UE_num_active_CC(UE_list_t *listP,int ue_idP)
 int UE_PCCID(module_id_t mod_idP,int ue_idP)
 //------------------------------------------------------------------------------
 {
+  if (eNB_mac_inst == NULL) return 0;
   return(eNB_mac_inst[mod_idP].UE_list.pCC_id[ue_idP]);
 }
 
@@ -139,6 +140,7 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP)
 //------------------------------------------------------------------------------
 {
 
+  if (eNB_mac_inst == NULL) return 0;
   rnti_t rnti = eNB_mac_inst[mod_idP].UE_list.UE_template[UE_PCCID(mod_idP,ue_idP)][ue_idP].rnti;
 
   if (rnti>0) {
@@ -154,6 +156,7 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP)
 boolean_t is_UE_active(module_id_t mod_idP, int ue_idP)
 //------------------------------------------------------------------------------
 {
+  if (eNB_mac_inst == NULL) return 0;
   return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]);
 }
 
@@ -182,6 +185,7 @@ uint8_t find_active_UEs(module_id_t module_idP,int CC_id){
 
 int UE_BSR (uint8_t mod_id, uint8_t ue_id, uint8_t lcid) {
 
+  if (eNB_mac_inst == NULL) return 0;
   return eNB_mac_inst[mod_id].UE_list.UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid];
 }
 
diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c
index c28b9e839c..1ca55b5926 100644
--- a/targets/COMMON/create_tasks.c
+++ b/targets/COMMON/create_tasks.c
@@ -40,21 +40,24 @@
 # endif
 # include "enb_app.h"
 
-int create_tasks(uint32_t enb_nb, uint32_t ue_nb)
+int create_enb_app_task(uint32_t enb_nb)
 {
-  itti_wait_ready(1);
-  if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
-    LOG_E(PDCP, "Create task for L2L1 failed\n");
-    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;
     }
   }
+  return 0;
+}
+
+int create_tasks(uint32_t enb_nb, uint32_t ue_nb)
+{
+  itti_wait_ready(1);
+  if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
+    LOG_E(PDCP, "Create task for L2L1 failed\n");
+    return -1;
+  }
 
 
 # ifdef OPENAIR2
diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h
index 6545f4b9d9..3455b283b5 100644
--- a/targets/COMMON/create_tasks.h
+++ b/targets/COMMON/create_tasks.h
@@ -27,6 +27,7 @@
 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/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf
index 4ee429f45e..378d932f57 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf
@@ -155,10 +155,11 @@ eNBs =
 
     NETWORK_CONTROLLER :
     {
-        FLEXRAN_AGENT_INTERFACE_NAME            = "eth1";
-        FLEXRAN_AGENT_IPV4_ADDRESS              = "10.0.2.5/30";
+        FLEXRAN_AGENT_INTERFACE_NAME            = "lo";
+        FLEXRAN_AGENT_IPV4_ADDRESS              = "127.0.0.1/30";
         FLEXRAN_AGENT_PORT                      = 2210;
         FLEXRAN_AGENT_CACHE                     = "/mnt/oai_agent_cache";
+        FLEXRAN_AGENT_AWAIT_RECONF              = "no";
     };
 
     log_config :
@@ -177,6 +178,7 @@ eNBs =
       pdcp_log_verbosity                    ="medium";
       rrc_log_level                         ="info";
       rrc_log_verbosity                     ="medium";
+      
    };
   }
 );
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index a1f3bcb57b..042f77eea7 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -174,6 +174,8 @@ 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;
@@ -232,6 +234,12 @@ threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
  */
 uint8_t abstraction_flag=0;
 
+/*  */
+
+/* overrid the enb configuration params*/ 
+static void reconfigure_enb_params(int enb_id);
+
+
 /*---------------------BMC: timespec helpers -----------------------------*/
 
 struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
@@ -1080,11 +1088,20 @@ static void get_options (int argc, char **argv) {
                      "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!",
                      conf_config_file_name, NB_eNB_INST, enb_properties->number);
 
+	NB_eNB_INST=enb_properties->number;
+
         /* Update some simulation parameters */
         for (i=0; i < enb_properties->number; i++) {
             AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
                          "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);
+
+	    if (enb_properties->properties[i]->flexran_agent_reconf == 1) {
+	      node_control_state  = ENB_WAIT_RECONFIGURATION_CMD;
+	    } else {
+	      node_control_state  = ENB_NORMAL_OPERATION;
+	    }
+		
             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));
 
@@ -1133,37 +1150,9 @@ static void get_options (int argc, char **argv) {
 
             }
 
-            for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-
-
-                node_function[CC_id]  = enb_properties->properties[i]->cc_node_function[CC_id];
-                node_timing[CC_id]    = enb_properties->properties[i]->cc_node_timing[CC_id];
-                node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id];
-
-                frame_parms[CC_id]->frame_type =       enb_properties->properties[i]->frame_type[CC_id];
-                frame_parms[CC_id]->tdd_config =       enb_properties->properties[i]->tdd_config[CC_id];
-                frame_parms[CC_id]->tdd_config_S =     enb_properties->properties[i]->tdd_config_s[CC_id];
-                frame_parms[CC_id]->Ncp =              enb_properties->properties[i]->prefix_type[CC_id];
-
-                //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
-                frame_parms[CC_id]->Nid_cell            =  enb_properties->properties[i]->Nid_cell[CC_id];
-                frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
-                frame_parms[CC_id]->N_RB_UL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
-                frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
-                frame_parms[CC_id]->nb_antenna_ports_eNB  =  enb_properties->properties[i]->nb_antenna_ports[CC_id];
-                frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
-
-                frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id];
-                frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset  = enb_properties->properties[i]->prach_freq_offset[CC_id];
-
-                frame_parms[CC_id]->mode1_flag         = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0;
-                frame_parms[CC_id]->threequarter_fs    = threequarter_fs;
+	    reconfigure_enb_params(i);
 
-                //} // j
-            }
-
-
-            init_all_otg(0);
+	    init_all_otg(0);
             g_otg->seed = 0;
             init_seeds(g_otg->seed);
 
@@ -1206,20 +1195,7 @@ static void get_options (int argc, char **argv) {
             osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
 #endif
 
-            // adjust the log
-            for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-                for (k = 0 ; k < 4; k++) {
-                    downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
-                    uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
-                    rx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->rx_gain[CC_id];
-                    tx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->tx_gain[CC_id];
-                }
-
-                printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
-                       enb_properties->properties[i]->downlink_frequency[CC_id],
-                       enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
-
-            } // CC_id
+           
         }// i
 
         //this is needed for phy-test option
@@ -1236,6 +1212,57 @@ static void get_options (int argc, char **argv) {
     }
 }
 
+
+static void reconfigure_enb_params(int enb_id)
+{
+  int CC_id, k;
+  const Enb_properties_array_t *enb_properties=enb_config_get();
+
+  
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+        
+    node_function[CC_id]  = enb_properties->properties[enb_id]->cc_node_function[CC_id];
+    node_timing[CC_id]    = enb_properties->properties[enb_id]->cc_node_timing[CC_id];
+    node_synch_ref[CC_id] = enb_properties->properties[enb_id]->cc_node_synch_ref[CC_id];
+    
+    frame_parms[CC_id]->frame_type   = enb_properties->properties[enb_id]->frame_type[CC_id];
+    frame_parms[CC_id]->tdd_config   = enb_properties->properties[enb_id]->tdd_config[CC_id];
+    frame_parms[CC_id]->tdd_config_S = enb_properties->properties[enb_id]->tdd_config_s[CC_id];
+    frame_parms[CC_id]->Ncp          = enb_properties->properties[enb_id]->prefix_type[CC_id];
+    
+                //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
+    frame_parms[CC_id]->Nid_cell             = enb_properties->properties[enb_id]->Nid_cell[CC_id];
+    frame_parms[CC_id]->N_RB_DL              = enb_properties->properties[enb_id]->N_RB_DL[CC_id];
+    frame_parms[CC_id]->N_RB_UL              = enb_properties->properties[enb_id]->N_RB_DL[CC_id];
+    frame_parms[CC_id]->nb_antennas_tx       = enb_properties->properties[enb_id]->nb_antennas_tx[CC_id];
+    frame_parms[CC_id]->nb_antenna_ports_eNB = enb_properties->properties[enb_id]->nb_antenna_ports[CC_id];
+    frame_parms[CC_id]->nb_antennas_rx       = enb_properties->properties[enb_id]->nb_antennas_rx[CC_id];
+    
+    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[enb_id]->prach_config_index[CC_id];
+    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset  = enb_properties->properties[enb_id]->prach_freq_offset[CC_id];
+    
+    frame_parms[CC_id]->mode1_flag      = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0;
+    frame_parms[CC_id]->threequarter_fs = threequarter_fs;
+
+
+    for (k = 0 ; k < 4; k++) {
+      downlink_frequency[CC_id][k]      =  enb_properties->properties[enb_id]->downlink_frequency[CC_id];
+      uplink_frequency_offset[CC_id][k] =  enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id];
+      rx_gain[CC_id][k]                 =  (double)enb_properties->properties[enb_id]->rx_gain[CC_id];
+      tx_gain[CC_id][k]                 =  (double)enb_properties->properties[enb_id]->tx_gain[CC_id];
+    }
+    
+    printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
+           enb_properties->properties[enb_id]->downlink_frequency[CC_id],
+           enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id]);
+    
+    init_ul_hopping(frame_parms[CC_id]);
+    init_frame_parms(frame_parms[CC_id],1);
+    //   phy_init_top(frame_parms[CC_id]);
+    phy_init_lte_top(frame_parms[CC_id]);
+  } // CC_id
+}
+
 #if T_TRACER
 int T_wait = 1;       /* by default we wait for the tracer */
 int T_port = 2021;    /* default port to listen to to wait for the tracer */
@@ -1395,6 +1422,19 @@ void init_openair0() {
   }
 }
 
+/* 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
+ */
+static 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);
+  }
+}
+
 int main( int argc, char **argv ) {
     int i,j,k,aa,re;
 #if defined (XFORMS)
@@ -1405,6 +1445,8 @@ int main( int argc, char **argv ) {
     uint8_t  abstraction_flag=0;
     uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
 
+    PHY_vars_eNB_g=NULL;
+    
 #if defined (XFORMS)
     int ret;
 #endif
@@ -1570,11 +1612,6 @@ int main( int argc, char **argv ) {
 
       LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx);
     }
-
-    init_ul_hopping(frame_parms[CC_id]);
-    init_frame_parms(frame_parms[CC_id],1);
-    //   phy_init_top(frame_parms[CC_id]);
-    phy_init_lte_top(frame_parms[CC_id]);
   }
 
 
@@ -1586,6 +1623,14 @@ int main( int argc, char **argv ) {
         // N_ZC = (prach_fmt <4)?839:139;
     }
 
+    create_enb_app_task(UE_flag ? 0 : 1);
+    ltesm_wait_reconfig_cmd ();
+    // 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);
+      printf("[ENB_APP] Reconfigured eNB module %d - continue\n", i);
+    }
+    
     if (UE_flag==1) {
         NB_UE_INST=1;
         NB_INST=1;
-- 
GitLab