summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2015-03-06 19:05:01 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2015-03-06 19:05:01 +0100
commit0414d5788090bb6df728d370079e44e95b4ffd20 (patch)
tree4294702d0e38b87f9fa3396a2edd2e2a522c520f /src
parent43635f1d8a96c9711d7004d9bf6114eedb8e6ccd (diff)
downloaddabmux-0414d5788090bb6df728d370079e44e95b4ffd20.tar.gz
dabmux-0414d5788090bb6df728d370079e44e95b4ffd20.tar.bz2
dabmux-0414d5788090bb6df728d370079e44e95b4ffd20.zip
Publish ptree on port 8001
Diffstat (limited to 'src')
-rw-r--r--src/ConfigParser.cpp (renamed from src/ParserConfigfile.cpp)15
-rw-r--r--src/ConfigParser.h (renamed from src/ParserConfigfile.h)13
-rw-r--r--src/ConfigServer.cpp177
-rw-r--r--src/ConfigServer.h120
-rw-r--r--src/DabMux.cpp32
-rw-r--r--src/Makefile.am3
6 files changed, 341 insertions, 19 deletions
diff --git a/src/ParserConfigfile.cpp b/src/ConfigParser.cpp
index 976bbf1..2c4ab63 100644
--- a/src/ParserConfigfile.cpp
+++ b/src/ConfigParser.cpp
@@ -8,8 +8,11 @@
http://www.opendigitalradio.org
- The command-line parser reads settings from a configuration file
- whose definition is given in doc/example.config
+ The Configuration parser sets up the ensemble according
+ to the configuration given in a boost property tree, which
+ is directly derived from a config file.
+
+ The format of the configuration is given in doc/example.mux
*/
/*
This file is part of ODR-DabMux.
@@ -27,14 +30,13 @@
You should have received a copy of the GNU General Public License
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ParserConfigfile.h"
+#include "ConfigParser.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/info_parser.hpp>
#include <exception>
#include <iostream>
#include <vector>
@@ -122,7 +124,7 @@ int hexparse(std::string input)
}
-void parse_configfile(string configuration_file,
+void parse_ptree(boost::property_tree::ptree& pt,
vector<dabOutput*> &outputs,
dabEnsemble* ensemble,
bool* enableTist,
@@ -136,9 +138,6 @@ void parse_configfile(string configuration_file,
{
using boost::property_tree::ptree;
using boost::property_tree::ptree_error;
- ptree pt;
-
- read_info(configuration_file, pt);
/******************** READ GENERAL OPTIONS *****************/
ptree pt_general = pt.get_child("general");
diff --git a/src/ParserConfigfile.h b/src/ConfigParser.h
index 95951d1..16d2146 100644
--- a/src/ParserConfigfile.h
+++ b/src/ConfigParser.h
@@ -6,8 +6,11 @@
Copyright (C) 2014
Matthias P. Braendli, matthias.braendli@mpb.li
- The command-line parser reads settings from a configuration file
- whose definition is given in doc/example.config
+ The Configuration parser sets up the ensemble according
+ to the configuration given in a boost property tree, which
+ is directly derived from a config file.
+
+ The format of the configuration is given in doc/example.mux
*/
/*
This file is part of ODR-DabMux.
@@ -25,8 +28,8 @@
You should have received a copy of the GNU General Public License
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _PARSER_CONFIGFILE
-#define _PARSER_CONFIGFILE
+#ifndef __CONFIG_PARSER_H_
+#define __CONFIG_PARSER_H_
#include <vector>
#include <string>
@@ -34,7 +37,7 @@
#include "DabMux.h"
#include <boost/property_tree/ptree.hpp>
-void parse_configfile(std::string configuration_file,
+void parse_ptree(boost::property_tree::ptree& pt,
std::vector<dabOutput*> &outputs,
dabEnsemble* ensemble,
bool* enableTist,
diff --git a/src/ConfigServer.cpp b/src/ConfigServer.cpp
new file mode 100644
index 0000000..e2eefd4
--- /dev/null
+++ b/src/ConfigServer.cpp
@@ -0,0 +1,177 @@
+/*
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+
+ Copyright (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+ */
+/*
+ This file is part of ODR-DabMux.
+
+ ODR-DabMux is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ ODR-DabMux is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "ConfigServer.h"
+
+#include <errno.h>
+#include <string.h>
+#include <math.h>
+#include <stdint.h>
+#include <limits>
+#include <sstream>
+#include <ctime>
+#include <boost/thread.hpp>
+#include "Log.h"
+
+void ConfigServer::serverThread()
+{
+ m_fault = false;
+
+ try {
+ int accepted_sock;
+ char buffer[256];
+ char welcome_msg[256];
+ struct sockaddr_in serv_addr, cli_addr;
+ int n;
+
+ int welcome_msg_len = snprintf(welcome_msg, 256,
+ "%s %s Config Server\n",
+ PACKAGE_NAME,
+#if defined(GITVERSION)
+ GITVERSION
+#else
+ PACKAGE_VERSION
+#endif
+ );
+
+
+ m_sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (m_sock < 0) {
+ etiLog.level(error) << "Error opening Config Server socket: " <<
+ strerror(errno);
+ m_fault = true;
+ return;
+ }
+
+ memset(&serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = INADDR_ANY; // TODO listen only on 127.0.0.1
+ serv_addr.sin_port = htons(m_listenport);
+
+ if (bind(m_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
+ etiLog.level(error) << "Error binding Config Server socket: " <<
+ strerror(errno);
+ goto end_serverthread;
+ }
+
+ if (listen(m_sock, 5) < 0) {
+ etiLog.level(error) << "Error listening on Config Server socket: " <<
+ strerror(errno);
+ goto end_serverthread;
+ }
+
+ m_running = true;
+
+ while (m_running) {
+ socklen_t cli_addr_len = sizeof(cli_addr);
+
+ /* Accept actual connection from the client */
+ accepted_sock = accept(m_sock,
+ (struct sockaddr *)&cli_addr,
+ &cli_addr_len);
+
+ if (accepted_sock < 0) {
+ etiLog.level(warn) << "Config Server cound not accept connection: " <<
+ strerror(errno);
+ continue;
+ }
+ /* Send welcome message with version */
+ n = write(accepted_sock, welcome_msg, welcome_msg_len);
+ if (n < 0) {
+ etiLog.level(warn) << "Error writing to Config Server socket " <<
+ strerror(errno);
+ close(accepted_sock);
+ continue;
+ }
+
+ /* receive command */
+ memset(buffer, 0, 256);
+ int n = read(accepted_sock, buffer, 255);
+ if (n < 0) {
+ etiLog.level(warn) << "Error reading from Config Server socket " <<
+ strerror(errno);
+ close(accepted_sock);
+ continue;
+ }
+
+ if (strcmp(buffer, "getconfig\n") == 0) {
+ boost::unique_lock<boost::mutex> lock(m_mutex);
+ m_pending_request = "getconfig";
+ m_pending = true;
+
+ while (m_pending) {
+ m_condition.wait(lock);
+ }
+ std::stringstream ss;
+ boost::property_tree::info_parser::write_info(ss, m_pt);
+
+ std::string response = ss.str();
+
+ n = write(accepted_sock, response.c_str(), response.size());
+ }
+ else {
+ int len = snprintf(buffer, 256, "Invalid command\n");
+ n = write(accepted_sock, buffer, len);
+ }
+
+ if (n < 0) {
+ etiLog.level(warn) << "Error writing to Config Server socket " <<
+ strerror(errno);
+ }
+ close(accepted_sock);
+ }
+
+end_serverthread:
+ m_fault = true;
+ close(m_sock);
+
+ }
+ catch (std::exception& e) {
+ etiLog.level(error) << "Config server caught exception: " << e.what();
+ m_fault = true;
+ }
+}
+
+void ConfigServer::restart()
+{
+ m_restarter_thread = boost::thread(&ConfigServer::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 ConfigServer::restart_thread(long)
+{
+ m_running = false;
+
+ if (m_listenport) {
+ m_thread.interrupt();
+ m_thread.join();
+ }
+
+ m_thread = boost::thread(&ConfigServer::serverThread, this);
+}
+
diff --git a/src/ConfigServer.h b/src/ConfigServer.h
new file mode 100644
index 0000000..b51ef32
--- /dev/null
+++ b/src/ConfigServer.h
@@ -0,0 +1,120 @@
+/*
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+
+ Copyright (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+ */
+/*
+ This file is part of ODR-DabMux.
+
+ ODR-DabMux is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ ODR-DabMux is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CONFIG_SERVER_H_
+#define __CONFIG_SERVER_H_
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/info_parser.hpp>
+#include <boost/thread.hpp>
+#include <cstdio>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <cstring>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+class ConfigServer
+{
+ public:
+ ConfigServer() :
+ m_listenport(0),
+ m_running(false),
+ m_fault(false)
+ { }
+
+ ConfigServer(int listen_port) :
+ m_listenport(listen_port),
+ m_running(false),
+ m_fault(false),
+ m_thread(&ConfigServer::serverThread, this)
+ {
+ m_sock = 0;
+ }
+
+ ~ConfigServer()
+ {
+ m_running = false;
+ m_fault = false;
+ if (m_sock) {
+ close(m_sock);
+ }
+ m_thread.join();
+ }
+
+ bool request_pending() {
+ return m_pending;
+ }
+
+ void update_ptree(const boost::property_tree::ptree& pt) {
+ boost::unique_lock<boost::mutex> lock(m_mutex);
+ m_pt = pt;
+ m_pending = false;
+
+ m_condition.notify_one();
+ }
+
+ bool fault_detected() { return m_fault; }
+ void restart(void);
+
+ private:
+ void restart_thread(long);
+
+ /******* TCP Socket Server ******/
+ // no copying (because of the thread)
+ ConfigServer(const ConfigServer& other);
+
+ void serverThread(void);
+
+ int m_listenport;
+
+ // serverThread runs in a separate thread
+ bool m_running;
+ bool m_fault;
+ boost::thread m_thread;
+ boost::thread m_restarter_thread;
+
+ int m_sock;
+
+ bool m_pending;
+ std::string m_pending_request;
+ boost::condition_variable m_condition;
+ boost::mutex m_mutex;
+
+ boost::property_tree::ptree m_pt;
+};
+
+
+#endif
+
diff --git a/src/DabMux.cpp b/src/DabMux.cpp
index d0ec502..950eefe 100644
--- a/src/DabMux.cpp
+++ b/src/DabMux.cpp
@@ -27,6 +27,8 @@
# include "config.h"
#endif
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/info_parser.hpp>
#include <cstdio>
#include <stdlib.h>
#include <iostream>
@@ -124,16 +126,22 @@ typedef DWORD32 uint32_t;
#include "MuxElements.h"
#include "utils.h"
#include "ParserCmdline.h"
-#include "ParserConfigfile.h"
+#include "ConfigParser.h"
#include "StatsServer.h"
+#include "ConfigServer.h"
#include "Log.h"
#include "RemoteControl.h"
using namespace std;
+using boost::property_tree::ptree;
+using boost::property_tree::ptree_error;
+
/* Global stats server */
StatsServer* global_stats;
+ConfigServer config_server(8001);
+
class MuxInitException : public exception
{
public:
@@ -337,6 +345,8 @@ int main(int argc, char *argv[])
edi_conf.dump = false;
edi_conf.enable_pft = false;
+ ptree pt;
+
struct timeval mnsc_time;
@@ -360,7 +370,9 @@ int main(int argc, char *argv[])
}
try {
- parse_configfile(conf_file, outputs, ensemble, &enableTist, &FICL,
+ read_info(conf_file, pt);
+
+ parse_ptree(pt, outputs, ensemble, &enableTist, &FICL,
&factumAnalyzer, &limit, &rc, &statsserverport, &edi_conf);
}
catch (runtime_error &e) {
@@ -525,11 +537,10 @@ int main(int argc, char *argv[])
for (output = outputs.begin(); output != outputs.end() ; ++output) {
+ if (0) {
#if defined(HAVE_OUTPUT_FILE)
- if ((*output)->outputProto == "file") {
+ } else if ((*output)->outputProto == "file") {
(*output)->output = new DabOutputFile();
-#else // !defined(HAVE_OUTPUT_FILE)
- if (0) {
#endif // defined(HAVE_OUTPUT_FILE)
#if defined(HAVE_OUTPUT_FIFO)
} else if ((*output)->outputProto == "fifo") {
@@ -2168,6 +2179,17 @@ int main(int argc, char *argv[])
"Detected Statistics Server fault, restarting it";
global_stats->restart();
}
+
+ if (fc->FCT % 10 == 0) {
+ if (config_server.fault_detected()) {
+ config_server.restart();
+ }
+
+ if (config_server.request_pending()) {
+ config_server.update_ptree(pt);
+ }
+
+ }
}
}
diff --git a/src/Makefile.am b/src/Makefile.am
index b65b9d2..aa1f86a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,7 +79,7 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \
MuxElements.cpp MuxElements.h \
RemoteControl.cpp RemoteControl.h \
ParserCmdline.cpp ParserCmdline.h \
- ParserConfigfile.cpp ParserConfigfile.h \
+ ParserConfig.cpp ParserConfig.h \
Eti.h Eti.cpp \
Log.h Log.cpp \
UdpSocket.h UdpSocket.cpp \
@@ -93,6 +93,7 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \
ReedSolomon.h ReedSolomon.cpp \
mpeg.h mpeg.c \
StatsServer.h StatsServer.cpp \
+ ConfigServer.h ConfigServer.cpp \
TcpServer.h TcpServer.cpp \
TcpSocket.h TcpSocket.cpp \
zmq.hpp