diff options
| -rw-r--r-- | src/DabMux.cpp | 8 | ||||
| -rw-r--r-- | src/ParserConfigfile.cpp | 12 | ||||
| -rw-r--r-- | src/ParserConfigfile.h | 2 | ||||
| -rw-r--r-- | src/RemoteControl.cpp | 35 | ||||
| -rw-r--r-- | src/RemoteControl.h | 52 | ||||
| -rw-r--r-- | src/utils.cpp | 7 | 
6 files changed, 89 insertions, 27 deletions
| diff --git a/src/DabMux.cpp b/src/DabMux.cpp index ca82889..ca5bd08 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -340,7 +340,7 @@ int main(int argc, char *argv[])              string conf_file = argv[2];              parse_configfile(conf_file, outputs, ensemble, &enableTist, &FICL, -                    &factumAnalyzer, &limit, rc, &statsserverport); +                    &factumAnalyzer, &limit, &rc, &statsserverport);          }          catch (runtime_error &e) { @@ -1812,6 +1812,12 @@ int main(int argc, char *argv[])              }          }  #endif + +        /* Check every six seconds if the remote control is still working */ +        if (rc && fc->FCT == 249 && rc->fault_detected()) { +                etiLog.level(warn) << "Detected Remote Control fault, restarting it"; +                rc->restart(); +        }      }  EXIT: diff --git a/src/ParserConfigfile.cpp b/src/ParserConfigfile.cpp index 9f62bdd..74d9588 100644 --- a/src/ParserConfigfile.cpp +++ b/src/ParserConfigfile.cpp @@ -127,7 +127,7 @@ void parse_configfile(string configuration_file,          unsigned* FICL,          bool* factumAnalyzer,          unsigned long* limit, -        BaseRemoteController* rc, +        BaseRemoteController** rc,          int* statsServerPort          )  { @@ -174,10 +174,10 @@ void parse_configfile(string configuration_file,      int telnetport = pt_rc.get<int>("telnetport", 0);      if (telnetport != 0) { -        rc = new RemoteControllerTelnet(telnetport); +        *rc = new RemoteControllerTelnet(telnetport);      }      else { -        rc = new RemoteControllerDummy(); +        *rc = new RemoteControllerDummy();      }      /******************** READ ENSEMBLE PARAMETERS *************/ @@ -240,7 +240,7 @@ void parse_configfile(string configuration_file,          ptree pt_service = it->second;          DabService* service = new DabService(serviceuid);          ensemble->services.push_back(service); -        service->enrol_at(*rc); +        service->enrol_at(**rc);          int success = -5; @@ -312,7 +312,7 @@ void parse_configfile(string configuration_file,          try {              setup_subchannel_from_ptree(subchan, it->second, ensemble, -                    subchanuid, rc); +                    subchanuid, *rc);          }          catch (runtime_error &e) {              etiLog.log(error, @@ -380,7 +380,7 @@ void parse_configfile(string configuration_file,          DabComponent* component = new DabComponent(componentuid); -        component->enrol_at(*rc); +        component->enrol_at(**rc);          component->serviceId = service->id;          component->subchId = subchannel->id; diff --git a/src/ParserConfigfile.h b/src/ParserConfigfile.h index f987542..5c8546f 100644 --- a/src/ParserConfigfile.h +++ b/src/ParserConfigfile.h @@ -40,7 +40,7 @@ void parse_configfile(std::string configuration_file,          unsigned* FICL,          bool* factumAnalyzer,          unsigned long* limit, -        BaseRemoteController* rc, +        BaseRemoteController** rc,          int* statsServerPort);  void setup_subchannel_from_ptree(dabSubchannel* subchan, diff --git a/src/RemoteControl.cpp b/src/RemoteControl.cpp index fb1aa7e..3ce3310 100644 --- a/src/RemoteControl.cpp +++ b/src/RemoteControl.cpp @@ -26,16 +26,38 @@  #include <string>  #include <string>  #include <boost/asio.hpp> +#include <boost/thread.hpp>  #include "Log.h"  #include "RemoteControl.h"  using boost::asio::ip::tcp; -void -RemoteControllerTelnet::process(long) + +void RemoteControllerTelnet::restart() +{ +    m_restarter_thread = boost::thread(&RemoteControllerTelnet::restart_thread, +            this, 0); +} + +// This runs in a separate thread, because +// it would take too long to be done in the main loop +// thread. +void RemoteControllerTelnet::restart_thread(long) +{ +    m_running = false; + +    if (m_port) { +        m_child_thread.interrupt(); +        m_child_thread.join(); +    } + +    m_child_thread = boost::thread(&RemoteControllerTelnet::process, this, 0); +} + +void RemoteControllerTelnet::process(long)  { -    m_welcome = "CRC-DABMUX Remote Control CLI\nWrite 'help' for help.\n**********\n"; +    m_welcome = "ODR-DabMux Remote Control CLI\nWrite 'help' for help.\n**********\n";      m_prompt = "> ";      std::string in_message; @@ -97,11 +119,11 @@ RemoteControllerTelnet::process(long)      catch (std::exception& e)      {          etiLog.level(error) << "Remote control caught exception: " << e.what(); +        m_fault = true;      }  } -void -RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string command) +void RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string command)  {      vector<string> cmd = tokenise_(command); @@ -214,8 +236,7 @@ RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string command)      }  } -void -RemoteControllerTelnet::reply(tcp::socket& socket, string message) +void RemoteControllerTelnet::reply(tcp::socket& socket, string message)  {      boost::system::error_code ignored_error;      stringstream ss; diff --git a/src/RemoteControl.h b/src/RemoteControl.h index e76ba68..c0fec8d 100644 --- a/src/RemoteControl.h +++ b/src/RemoteControl.h @@ -67,11 +67,23 @@ class ParameterError : public std::exception  class RemoteControllable; -/* Remote controllers (that recieve orders from the user) must implement BaseRemoteController */ +/* Remote controllers (that recieve orders from the user) + * must implement BaseRemoteController + */  class BaseRemoteController {      public:          /* Add a new controllable under this controller's command */          virtual void enrol(RemoteControllable* controllable) = 0; + +        /* When this returns one, the remote controller cannot be +         * used anymore, and must be restarted by dabmux +         */ +        virtual bool fault_detected() = 0; + +        /* In case of a fault, the remote controller can be +         * restarted. +         */ +        virtual void restart() = 0;  };  /* Objects that support remote control must implement the following class */ @@ -125,33 +137,41 @@ class RemoteControllable {  class RemoteControllerTelnet : public BaseRemoteController {      public:          RemoteControllerTelnet() -            : m_running(false), m_port(0) {} +            : m_running(false), m_fault(false), +            m_port(0) {}          RemoteControllerTelnet(int port) -            : m_running(true), m_port(port), +            : m_running(false), m_fault(false), +            m_port(port),              m_child_thread(&RemoteControllerTelnet::process, this, 0)          {}          ~RemoteControllerTelnet() {              m_running = false; +            m_fault = false;              if (m_port) {                  m_child_thread.interrupt();                  m_child_thread.join();              }          } -        void process(long); - -        void dispatch_command(tcp::socket& socket, string command); - -        void reply(tcp::socket& socket, string message); -          void enrol(RemoteControllable* controllable) {              m_cohort.push_back(controllable);          } +        virtual bool fault_detected() { return m_fault; }; + +        virtual void restart();      private: +        void restart_thread(long); + +        void process(long); + +        void dispatch_command(tcp::socket& socket, string command); + +        void reply(tcp::socket& socket, string message); +          RemoteControllerTelnet& operator=(const RemoteControllerTelnet& other);          RemoteControllerTelnet(const RemoteControllerTelnet& other); @@ -192,7 +212,8 @@ class RemoteControllerTelnet : public BaseRemoteController {              list< vector<string> > allparams;              list<string> params = controllable->get_supported_parameters(); -            for (list<string>::iterator it = params.begin(); it != params.end(); ++it) { +            for (list<string>::iterator it = params.begin(); +                    it != params.end(); ++it) {                  vector<string> item;                  item.push_back(*it);                  item.push_back(controllable->get_parameter(*it)); @@ -213,6 +234,11 @@ class RemoteControllerTelnet : public BaseRemoteController {          }          bool m_running; + +        /* This is set to true if a fault occurred */ +        bool m_fault; +        boost::thread m_restarter_thread; +          boost::thread m_child_thread;          /* This controller commands the controllables in the cohort */ @@ -225,11 +251,15 @@ class RemoteControllerTelnet : public BaseRemoteController {  }; -/* The Dummy remote controller does nothing +/* The Dummy remote controller does nothing, and never fails   */  class RemoteControllerDummy : public BaseRemoteController {      public:          void enrol(RemoteControllable* controllable) {}; + +        bool fault_detected() { return false; }; + +        virtual void restart() {};  };  #endif diff --git a/src/utils.cpp b/src/utils.cpp index 8422782..1cbd9d5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -306,8 +306,13 @@ void printOutputs(vector<dabOutput*>& outputs)          etiLog.log(info, "Output      %i", index);          etiLog.level(info) << "  protocol: " <<                  (*output)->outputProto; +          etiLog.level(info) << "  name:     " << -                (*output)->outputName; +                (*output)->outputName.c_str(); +        // Daboutputfile mangles with outputName, inserting \0 to +        // cut the string in several parts. That doesn't work +        // with stl strings. Thats why the .c_str() +          ++index;      }  } | 
