aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DabMux.cpp8
-rw-r--r--src/ParserConfigfile.cpp12
-rw-r--r--src/ParserConfigfile.h2
-rw-r--r--src/RemoteControl.cpp35
-rw-r--r--src/RemoteControl.h52
-rw-r--r--src/utils.cpp7
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;
}
}