From 963805820c9a0b0deff845d44fe116cda5013cc3 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Thu, 8 Mar 2018 10:17:16 +0100
Subject: [PATCH] add a stop_rf function in the RU

When the program exits it has to stop the streaming of the USRP.
The function exit_fun is supposed to do that. When quitting with
control+c (very common case) this function is not called. The
code is very unclear there, so let's add a stop_rf in the RU,
as there is already a start_rf.

If we don't call trx_end_func, then at the next run the USRP
device may be in an unstable state and behave improperly.

If the program crashes then the USRP device may be in an
unstable state. The only solution to this problem is to reset
the USRP device.

Maybe there is a way to clean the state of the device when we
open it, before we start using it. Sort of a cleanup before
use. That could be a better solution to "bad state after program
crash".

What has been tested:
- monolithic eNB only
---
 openair1/PHY/defs.h      |  2 ++
 targets/RT/USER/lte-ru.c | 17 ++++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 46f37e9431..a0f37dd885 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -738,6 +738,8 @@ typedef struct RU_t_s{
   void                 (*fh_south_asynch_in)(struct RU_t_s *ru,int *frame, int *subframe);
   /// function pointer to initialization function for radio interface
   int                  (*start_rf)(struct RU_t_s *ru);
+  /// function pointer to release function for radio interface
+  int                  (*stop_rf)(struct RU_t_s *ru);
   /// function pointer to initialization function for radio interface
   int                  (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB);
   /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL)
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index d909da627f..d9bda6a037 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -1523,7 +1523,13 @@ static void* ru_thread( void* param ) {
   
 
   printf( "Exiting ru_thread \n");
- 
+
+  if (ru->stop_rf != NULL) {
+    if (ru->stop_rf(ru) != 0)
+      LOG_E(HW,"Could not stop the RF device\n");
+    else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
+  }
+
   ru_thread_status = 0;
   return &ru_thread_status;
 
@@ -1617,6 +1623,12 @@ int start_rf(RU_t *ru) {
   return(ru->rfdevice.trx_start_func(&ru->rfdevice));
 }
 
+int stop_rf(RU_t *ru)
+{
+  ru->rfdevice.trx_end_func(&ru->rfdevice);
+  return 0;
+}
+
 extern void fep_full(RU_t *ru);
 extern void ru_fep_full_2thread(RU_t *ru);
 extern void feptx_ofdm(RU_t *ru);
@@ -2082,6 +2094,7 @@ void set_function_spec_param(RU_t *ru)
     ru->fh_south_in            = rx_rf;                               // local synchronous RF RX
     ru->fh_south_out           = tx_rf;                               // local synchronous RF TX
     ru->start_rf               = start_rf;                            // need to start the local RF interface
+    ru->stop_rf                = stop_rf;
     printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf);
 /*
     if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
@@ -2113,6 +2126,7 @@ void set_function_spec_param(RU_t *ru)
       ru->fh_south_asynch_in   = NULL;                // no asynchronous UL
     }
     ru->start_rf               = NULL;                 // no local RF
+    ru->stop_rf                = NULL;
     ru->start_if               = start_if;             // need to start if interface for IF5
     ru->ifdevice.host_type     = RAU_HOST;
     ru->ifdevice.eth_params    = &ru->eth_params;
@@ -2137,6 +2151,7 @@ void set_function_spec_param(RU_t *ru)
     ru->fh_north_out           = NULL;
     ru->fh_north_asynch_in     = NULL;
     ru->start_rf               = NULL;                // no local RF
+    ru->stop_rf                = NULL;
     ru->start_if               = start_if;            // need to start if interface for IF4p5
     ru->ifdevice.host_type     = RAU_HOST;
     ru->ifdevice.eth_params    = &ru->eth_params;
-- 
GitLab