summaryrefslogtreecommitdiffstats
path: root/src/RemoteControl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/RemoteControl.h')
-rw-r--r--src/RemoteControl.h300
1 files changed, 88 insertions, 212 deletions
diff --git a/src/RemoteControl.h b/src/RemoteControl.h
index deae961..e4345de 100644
--- a/src/RemoteControl.h
+++ b/src/RemoteControl.h
@@ -3,11 +3,12 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2014
+ Copyright (C) 2016
Matthias P. Braendli, matthias.braendli@mpb.li
+ http://www.opendigitalradio.org
+
This module adds remote-control capability to some of the dabmod modules.
- see testremotecontrol/test.cpp for an example of how to use this.
*/
/*
This file is part of ODR-DabMod.
@@ -26,20 +27,21 @@
along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _REMOTECONTROL_H
-#define _REMOTECONTROL_H
+#pragma once
#ifdef HAVE_CONFIG_H
-# include "config.h"
+# include "config.h"
#endif
#if defined(HAVE_ZEROMQ)
-#include "zmq.hpp"
+# include "zmq.hpp"
#endif
#include <list>
#include <map>
+#include <memory>
#include <string>
+#include <atomic>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
@@ -57,7 +59,6 @@
m_parameters.push_back(p); \
}
-
class ParameterError : public std::exception
{
public:
@@ -76,14 +77,8 @@ class RemoteControllable;
*/
class BaseRemoteController {
public:
- /* Add a new controllable under this controller's command */
- virtual void enrol(RemoteControllable* controllable) = 0;
-
- /* Remove a controllable under this controller's command */
- virtual void disengage(RemoteControllable* controllable) = 0;
-
/* When this returns one, the remote controller cannot be
- * used anymore, and must be restarted by dabmux
+ * used anymore, and must be restarted by DabMod
*/
virtual bool fault_detected() = 0;
@@ -95,25 +90,60 @@ class BaseRemoteController {
virtual ~BaseRemoteController() {}
};
-/* Holds all our remote controllers, i.e. we may have more than
- * one type of controller running.
+/* Objects that support remote control must implement the following class */
+class RemoteControllable {
+ public:
+ RemoteControllable(const std::string& name) :
+ m_name(name) {}
+
+ RemoteControllable(const RemoteControllable& other) = delete;
+ RemoteControllable& operator=(const RemoteControllable& other) = delete;
+
+ virtual ~RemoteControllable();
+
+ /* return a short name used to identify the controllable.
+ * It might be used in the commands the user has to type, so keep
+ * it short
+ */
+ virtual std::string get_rc_name() const { return m_name; }
+
+ /* Return a list of possible parameters that can be set */
+ virtual std::list<std::string> get_supported_parameters() const;
+
+ /* Return a mapping of the descriptions of all parameters */
+ virtual std::list< std::vector<std::string> >
+ get_parameter_descriptions() const
+ {
+ return m_parameters;
+ }
+
+ /* Base function to set parameters. */
+ virtual void set_parameter(
+ const std::string& parameter,
+ const std::string& value) = 0;
+
+ /* Getting a parameter always returns a string. */
+ virtual const std::string get_parameter(const std::string& parameter) const = 0;
+
+ protected:
+ std::string m_name;
+ std::list< std::vector<std::string> > m_parameters;
+};
+
+/* Holds all our remote controllers and controlled object.
*/
class RemoteControllers {
public:
- void add_controller(BaseRemoteController *rc) {
+ void add_controller(std::shared_ptr<BaseRemoteController> rc) {
m_controllers.push_back(rc);
}
- void add_controllable(RemoteControllable *rc) {
- for (auto &controller : m_controllers) {
- controller->enrol(rc);
- }
+ void enrol(RemoteControllable *rc) {
+ controllables.push_back(rc);
}
void remove_controllable(RemoteControllable *rc) {
- for (auto &controller : m_controllers) {
- controller->disengage(rc);
- }
+ controllables.remove(rc);
}
void check_faults() {
@@ -126,72 +156,42 @@ class RemoteControllers {
}
}
}
- size_t get_no_controllers() { return m_controllers.size(); }
-
- private:
- std::list<BaseRemoteController*> m_controllers;
-};
-/* Objects that support remote control must implement the following class */
-class RemoteControllable {
- public:
+ std::list< std::vector<std::string> >
+ get_param_list_values(const std::string& name) {
+ RemoteControllable* controllable = get_controllable_(name);
- RemoteControllable(std::string name) :
- m_rcs_enrolled_at(nullptr),
- m_name(name) {}
+ std::list< std::vector<std::string> > allparams;
+ for (auto &param : controllable->get_supported_parameters()) {
+ std::vector<std::string> item;
+ item.push_back(param);
+ item.push_back(controllable->get_parameter(param));
- virtual ~RemoteControllable() {
- if (m_rcs_enrolled_at) {
- m_rcs_enrolled_at->remove_controllable(this);
+ allparams.push_back(item);
}
+ return allparams;
}
- /* return a short name used to identify the controllable.
- * It might be used in the commands the user has to type, so keep
- * it short
- */
- virtual std::string get_rc_name() const { return m_name; }
-
- /* Tell the controllable to enrol at the given controller */
- virtual void enrol_at(RemoteControllers& controllers) {
- if (m_rcs_enrolled_at) {
- throw std::runtime_error("This controllable is already enrolled");
- }
-
- m_rcs_enrolled_at = &controllers;
- controllers.add_controllable(this);
+ std::string get_param(const std::string& name, const std::string& param) {
+ RemoteControllable* controllable = get_controllable_(name);
+ return controllable->get_parameter(param);
}
- /* Return a list of possible parameters that can be set */
- virtual std::list<std::string> get_supported_parameters() const {
- std::list<std::string> parameterlist;
- for (const auto& param : m_parameters) {
- parameterlist.push_back(param[0]);
- }
- return parameterlist;
+ void set_param(const std::string& name, const std::string& param, const std::string& value) {
+ RemoteControllable* controllable = get_controllable_(name);
+ return controllable->set_parameter(param, value);
}
- /* Return a mapping of the descriptions of all parameters */
- virtual std::list< std::vector<std::string> >
- get_parameter_descriptions() const {
- return m_parameters;
- }
+ std::list<RemoteControllable*> controllables;
- /* Base function to set parameters. */
- virtual void set_parameter(const std::string& parameter,
- const std::string& value) = 0;
+ private:
+ RemoteControllable* get_controllable_(const std::string& name);
- /* Getting a parameter always returns a string. */
- virtual const std::string get_parameter(const std::string& parameter) const = 0;
+ std::list<std::shared_ptr<BaseRemoteController> > m_controllers;
+};
- protected:
- RemoteControllers* m_rcs_enrolled_at;
- std::string m_name;
- std::list< std::vector<std::string> > m_parameters;
+extern RemoteControllers rcs;
- RemoteControllable(const RemoteControllable& other) = delete;
- RemoteControllable& operator=(const RemoteControllable& other) = delete;
-};
/* Implements a Remote controller based on a simple telnet CLI
* that listens on localhost
@@ -205,8 +205,10 @@ class RemoteControllerTelnet : public BaseRemoteController {
RemoteControllerTelnet(int port)
: m_running(true), m_fault(false),
m_child_thread(&RemoteControllerTelnet::process, this, 0),
- m_port(port)
- { }
+ m_port(port) { }
+
+ RemoteControllerTelnet& operator=(const RemoteControllerTelnet& other) = delete;
+ RemoteControllerTelnet(const RemoteControllerTelnet& other) = delete;
~RemoteControllerTelnet() {
m_running = false;
@@ -217,14 +219,6 @@ class RemoteControllerTelnet : public BaseRemoteController {
}
}
- void enrol(RemoteControllable* controllable) {
- m_cohort.push_back(controllable);
- }
-
- void disengage(RemoteControllable* controllable) {
- m_cohort.remove(controllable);
- }
-
virtual bool fault_detected() { return m_fault; }
virtual void restart();
@@ -239,9 +233,6 @@ class RemoteControllerTelnet : public BaseRemoteController {
void reply(boost::asio::ip::tcp::socket& socket, std::string message);
- RemoteControllerTelnet& operator=(const RemoteControllerTelnet& other);
- RemoteControllerTelnet(const RemoteControllerTelnet& other);
-
std::vector<std::string> tokenise_(std::string message) {
std::vector<std::string> all_tokens;
@@ -253,64 +244,14 @@ class RemoteControllerTelnet : public BaseRemoteController {
return all_tokens;
}
- RemoteControllable* get_controllable_(std::string name) {
- for (std::list<RemoteControllable*>::iterator it = m_cohort.begin();
- it != m_cohort.end(); ++it) {
- if ((*it)->get_rc_name() == name)
- {
- return *it;
- }
- }
- throw ParameterError("Module name unknown");
- }
-
- std::list< std::vector<std::string> >
- get_parameter_descriptions_(std::string name) {
- RemoteControllable* controllable = get_controllable_(name);
- return controllable->get_parameter_descriptions();
- }
-
- std::list<std::string> get_param_list_(std::string name) {
- RemoteControllable* controllable = get_controllable_(name);
- return controllable->get_supported_parameters();
- }
-
- std::list< std::vector<std::string> >
- get_param_list_values_(std::string name) {
- RemoteControllable* controllable = get_controllable_(name);
-
- std::list< std::vector<std::string> > allparams;
- for (auto &param : controllable->get_supported_parameters()) {
- std::vector<std::string> item;
- item.push_back(param);
- item.push_back(controllable->get_parameter(param));
-
- allparams.push_back(item);
- }
- return allparams;
- }
-
- std::string get_param_(std::string name, std::string param) {
- RemoteControllable* controllable = get_controllable_(name);
- return controllable->get_parameter(param);
- }
-
- void set_param_(std::string name, std::string param, std::string value) {
- RemoteControllable* controllable = get_controllable_(name);
- return controllable->set_parameter(param, value);
- }
-
- bool m_running;
+ std::atomic<bool> m_running;
/* This is set to true if a fault occurred */
- bool m_fault;
+ std::atomic<bool> m_fault;
boost::thread m_restarter_thread;
boost::thread m_child_thread;
- /* This controller commands the controllables in the cohort */
- std::list<RemoteControllable*> m_cohort;
-
int m_port;
};
@@ -325,12 +266,15 @@ class RemoteControllerZmq : public BaseRemoteController {
m_zmqContext(1),
m_endpoint("") { }
- RemoteControllerZmq(std::string endpoint)
+ RemoteControllerZmq(const std::string& endpoint)
: m_running(true), m_fault(false),
m_zmqContext(1),
m_endpoint(endpoint),
m_child_thread(&RemoteControllerZmq::process, this) { }
+ RemoteControllerZmq& operator=(const RemoteControllerZmq& other) = delete;
+ RemoteControllerZmq(const RemoteControllerZmq& other) = delete;
+
~RemoteControllerZmq() {
m_running = false;
m_fault = false;
@@ -340,14 +284,6 @@ class RemoteControllerZmq : public BaseRemoteController {
}
}
- void enrol(RemoteControllable* controllable) {
- m_cohort.push_back(controllable);
- }
-
- void disengage(RemoteControllable* controllable) {
- m_cohort.remove(controllable);
- }
-
virtual bool fault_detected() { return m_fault; }
virtual void restart();
@@ -360,76 +296,16 @@ class RemoteControllerZmq : public BaseRemoteController {
void send_fail_reply(zmq::socket_t &pSocket, const std::string &error);
void process();
-
- RemoteControllerZmq& operator=(const RemoteControllerZmq& other);
- RemoteControllerZmq(const RemoteControllerZmq& other);
-
- RemoteControllable* get_controllable_(std::string name) {
- for (std::list<RemoteControllable*>::iterator it = m_cohort.begin();
- it != m_cohort.end(); ++it) {
- if ((*it)->get_rc_name() == name)
- {
- return *it;
- }
- }
- throw ParameterError("Module name unknown");
- }
-
- std::string get_param_(std::string name, std::string param) {
- RemoteControllable* controllable = get_controllable_(name);
- return controllable->get_parameter(param);
- }
-
- void set_param_(std::string name, std::string param, std::string value) {
- RemoteControllable* controllable = get_controllable_(name);
- return controllable->set_parameter(param, value);
- }
-
- std::list< std::vector<std::string> >
- get_param_list_values_(std::string name) {
- RemoteControllable* controllable = get_controllable_(name);
-
- std::list< std::vector<std::string> > allparams;
-
- for (auto &param : controllable->get_supported_parameters()) {
- std::vector<std::string> item;
- item.push_back(param);
- item.push_back(controllable->get_parameter(param));
-
- allparams.push_back(item);
- }
-
- return allparams;
- }
-
-
- bool m_running;
+ std::atomic<bool> m_running;
/* This is set to true if a fault occurred */
- bool m_fault;
+ std::atomic<bool> m_fault;
boost::thread m_restarter_thread;
zmq::context_t m_zmqContext;
- /* This controller commands the controllables in the cohort */
- std::list<RemoteControllable*> m_cohort;
-
std::string m_endpoint;
boost::thread m_child_thread;
};
#endif
-/* The Dummy remote controller does nothing, and never fails
- */
-class RemoteControllerDummy : public BaseRemoteController {
- public:
- void enrol(RemoteControllable*) {}
- void disengage(RemoteControllable*) {}
-
- bool fault_detected() { return false; }
-
- virtual void restart() {}
-};
-
-#endif
-