diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2015-03-06 19:05:01 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2015-03-06 19:05:01 +0100 |
commit | 0414d5788090bb6df728d370079e44e95b4ffd20 (patch) | |
tree | 4294702d0e38b87f9fa3396a2edd2e2a522c520f /src | |
parent | 43635f1d8a96c9711d7004d9bf6114eedb8e6ccd (diff) | |
download | dabmux-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.cpp | 177 | ||||
-rw-r--r-- | src/ConfigServer.h | 120 | ||||
-rw-r--r-- | src/DabMux.cpp | 32 | ||||
-rw-r--r-- | src/Makefile.am | 3 |
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 |