diff --git a/src/config.cc b/src/config.cc index 3aaf0e57e0468ee2e5136983894533b0e8b02ecc..740efd5112c6e2bd3ece7561d0d5255d24e1cf10 100644 --- a/src/config.cc +++ b/src/config.cc @@ -4,7 +4,19 @@ #include "log.h" -config::config(std::string filename) { +config::config() {} + +config::config(std::string filename) { initialiseFromFile(filename); } + +void config::initialiseFromString(std::string config) { + std::string conf_location{"/tmp/received_scdaq_configuration.conf"}; + std::ofstream out(conf_location); + out << config; + + initialiseFromFile(conf_location); +} + +void config::initialiseFromFile(std::string filename) { bool valid = true; std::ifstream in(filename.c_str(), std::ios_base::in); @@ -46,11 +58,16 @@ config::config(std::string filename) { vmap[key] = value; } + isInitialised_ = valid; if (!valid) { throw std::invalid_argument("Configuration error: Keys with no value detected!"); } + config_filename_ = filename; + + print(); } void config::print() const { + LOG(INFO) << "Config file location: " << config_filename_; for (std::map<std::string, std::string>::const_iterator it = vmap.begin(); it != vmap.end(); it++) { LOG(INFO) << "key " << it->first << " value " << it->second; diff --git a/src/config.h b/src/config.h index cf4eb61ad1725ede07ecf3bb372351cef4452a87..1466924c5f9e83f47d032e871b3499d8fd28cdb8 100644 --- a/src/config.h +++ b/src/config.h @@ -15,10 +15,16 @@ class config { public: enum class InputType { WZDMA, DMA, FILEDMA, MICRONDMA, FILE }; + config(); config(std::string filename); void print() const; + bool isInitialised() const { return isInitialised_; } + + void initialiseFromFile(std::string filename); + void initialiseFromString(std::string config); + InputType getInput() const { const std::string &input = vmap.at("input"); if (input == "wzdma") { @@ -175,5 +181,9 @@ class config { private: std::map<std::string, std::string> vmap; + + std::string config_filename_{""}; + + bool isInitialised_{false}; }; #endif diff --git a/src/scdaq.cc b/src/scdaq.cc index ab98d9b57b99ee27b37e48cc63e9ba91a58fc220..6e0430d1b82d0661783be59dd72edea4bcb58dbb 100644 --- a/src/scdaq.cc +++ b/src/scdaq.cc @@ -125,30 +125,58 @@ int main(int argc, char *argv[]) { return 1; } - if ((std::string(argv[1]) == "-h") || (std::string(argv[1]) == "--help")) { - LOG(DEBUG) << "HELP: expected arguments --config [configfilename]"; + if (argc == 2 && (std::string(argv[1]) == "-h" || std::string(argv[1]) == "--help")) { + LOG(DEBUG) << "HELP: optional arguments: "; + LOG(DEBUG) << " --port [port to listen on]. Default: 8000"; + LOG(DEBUG) << " --config [configfilename]. Default: Configuration via network."; return 1; } - if ((argc != 3)) { - LOG(ERROR) << "error occurred, number of arguments != 2, expected --config " - "[configfilename] , try --help"; - return 1; + int server_port{8000}; + if (argc == 3 && std::string(argv[1]) == "--port") { + server_port = std::stoi(argv[2]); + } else if (argc == 5 && std::string(argv[3]) == "--port") { + server_port = std::stoi(argv[4]); } + LOG(DEBUG) << "Using port number: " << std::to_string(server_port); - if (std::string(argv[1]) == "--config") { + bool configuration_received{false}; + std::string config_file_path{"/etc/scdaq/received_configuration.conf"}; + if (argc == 3 && std::string(argv[1]) == "--config") { + configuration_received = true; LOG(DEBUG) << "scdaq started with conffile: " << std::string(argv[2]); - } else { - LOG(ERROR) << "invalid argument, expected --config, see --help"; - return 1; + config_file_path = argv[2]; + } else if (argc == 5 && std::string(argv[3]) == "--config") { + configuration_received = true; + LOG(DEBUG) << "scdaq started with conffile: " << std::string(argv[4]); + config_file_path = argv[4]; } + // TODO: Currently the configuration class throws an exception, however this should probably be + // changed now that we can load a new one at runtime. try { - config conf(argv[2]); - conf.print(); + config conf; + ctrl control; + boost::asio::io_service io_service; + server s(io_service, server_port, control, conf); + boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); + + if (configuration_received) { + conf.initialiseFromFile(config_file_path); + } + if (!conf.isInitialised()) { + if (configuration_received) { + LOG(ERROR) << "Configuration file could not be parsed!"; + } else { + LOG(INFO) << "Waiting for configuration via network."; + } + } + while (!conf.isInitialised()) { + sleep(1); // TODO: Should probably be solved by a mutex or so. + } + tools::log::set_filter_min_severity(conf.getLogMinSeverity()); LOG(DEBUG) << "Configuration loaded"; - ctrl control; // tbb::tick_count mainStartTime = tbb::tick_count::now(); control.running = false; @@ -167,10 +195,6 @@ int main(int argc, char *argv[]) { return 1; } - boost::asio::io_service io_service; - server s(io_service, conf.getPortNumber(), control); - boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); - int nbThreads = conf.getNumThreads(); retval = 0; diff --git a/src/server.h b/src/server.h index 804da1601f059ea6c09143b0da7f6ba23452b5ce..bf20714f41971ddb99f722a1c26b513bf11b9485 100644 --- a/src/server.h +++ b/src/server.h @@ -3,19 +3,23 @@ #include <boost/asio.hpp> #include <boost/bind.hpp> +#include "config.h" #include "controls.h" #include "session.h" class server { public: - server(boost::asio::io_service &io_service, short port, ctrl &c) - : io_service_(io_service), acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), control(c) { - start_accept(control); + server(boost::asio::io_service &io_service, short port, ctrl &c, config &conf) + : io_service_(io_service), + acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), + control(c), + conf(conf) { + start_accept(control, conf); } private: - void start_accept(ctrl &c) { - session *new_session = new session(io_service_, c); + void start_accept(ctrl &c, config &conf) { + session *new_session = new session(io_service_, c, conf); acceptor_.async_accept( new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)); @@ -28,12 +32,13 @@ class server { delete new_session; } - start_accept(control); + start_accept(control, conf); } boost::asio::io_service &io_service_; tcp::acceptor acceptor_; ctrl &control; + config &conf; }; #endif diff --git a/src/session.h b/src/session.h index cad8aadc97fb20be0f4d7a188c4ddb610b8b2240..26c82fed0ab55254de8f0a6c4b0be938718bc9f5 100644 --- a/src/session.h +++ b/src/session.h @@ -7,6 +7,7 @@ #include <iostream> #include <string> +#include "config.h" #include "controls.h" #include "log.h" @@ -25,7 +26,8 @@ using boost::asio::ip::tcp; class session { public: - session(boost::asio::io_service &io_service, ctrl &c) : socket_(io_service), control(c) {} + session(boost::asio::io_service &io_service, ctrl &c, config &conf) + : socket_(io_service), control(c), conf(conf) {} tcp::socket &socket() { return socket_; } @@ -45,11 +47,27 @@ class session { std::vector<std::string> items; boost::split(items, input, boost::is_any_of(" ,"), boost::token_compress_on); - if (items.size() < 1 || items.size() > 2) { + if (items.size() < 1) { return snprintf(output, size, "ERROR: Wrong number of arguments (%ld).", items.size()); } const std::string &command = items[0]; + // TODO: Currently we apply the configuration even while running. We should instead load it + // first and then apply when the next start signal is issued. + if (command == "config") { + conf.initialiseFromString(std::string(input.substr(command.length() + 1))); + if (conf.isInitialised()) { + return snprintf(output, size, RCINFO("ok")); + } + } else { + return snprintf(output, size, + "unknown command or too many arguments for start and stop command"); + } + + if (items.size() > 2) { + return snprintf(output, size, "ERROR: Wrong number of arguments (%ld).", items.size()); + } + if (command == "start") { if (items.size() != 2) { return snprintf(output, size, "ERROR: Wrong number of arguments (%ld), expecting 2.", @@ -119,6 +137,7 @@ class session { enum { max_length = 1024 }; char data_[max_length]; ctrl &control; + config &conf; static const std::string reply_success; static const std::string reply_failure; };