135 #include <boost/asio.hpp>
136 #include <boost/program_options.hpp>
138 #include <sys/ioctl.h>
144 #include "structs.hpp"
145 #include "datatypes.hpp"
146 #include "version.hpp"
147 #include "ligier_helper.hpp"
148 #include "consumers.hpp"
149 #include "dom_map.hpp"
153 static bool const is_a_tty = isatty(1);
160 ioctl(1, TIOCGWINSZ, &sz);
165 namespace po = boost::program_options;
176 boost::asio::signal_set& set,
178 boost::system::error_code
const& error,
182 template<
class Consumer>
199 boost::system::error_code
const& error
203 if (error && error != boost::asio::error::operation_aborted) {
206 }
else if (error == boost::asio::error::operation_aborted) {
210 boost::asio::async_read(
216 , boost::asio::placeholders::error
217 , boost::asio::placeholders::bytes_transferred
231 , boost::asio::placeholders::error
239 if (error && error != boost::asio::error::operation_aborted) {
241 m_timer.expires_from_now(boost::posix_time::seconds(1));
247 , boost::asio::placeholders::error
250 }
else if (error == boost::asio::error::operation_aborted) {
254 boost::asio::async_write(
256 , boost::asio::buffer(
m_buffer, size)
260 , boost::asio::placeholders::error
261 , boost::asio::placeholders::bytes_transferred
268 boost::system::error_code
const& error
269 , std::size_t bytes_transferred
271 if (error && error != boost::asio::error::operation_aborted) {
274 }
else if (error == boost::asio::error::operation_aborted) {
276 boost::asio::async_read(
282 , boost::asio::placeholders::error
283 , boost::asio::placeholders::bytes_transferred
290 boost::system::error_code
const& error
291 , std::size_t bytes_transferred
293 if (error && error != boost::asio::error::operation_aborted) {
296 }
else if (error == boost::asio::error::operation_aborted) {
300 boost::asio::async_read(
302 , boost::asio::buffer(
m_buffer + 16, size)
306 , boost::asio::placeholders::error
307 , boost::asio::placeholders::bytes_transferred
315 boost::system::error_code ec;
317 m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
325 , boost::asio::placeholders::error
336 boost::asio::io_service& service
337 , std::string
const& tag
338 , boost::asio::ip::tcp::endpoint
const& endpoint
341 , Consumer
const& consumer
355 , boost::asio::placeholders::error
361 template<
class Consumer>
372 boost::system::error_code
const& error
373 , std::size_t bytes_transferred
386 , boost::asio::placeholders::error
387 , boost::asio::placeholders::bytes_transferred
395 boost::asio::io_service& service
399 , Consumer
const& consumer
402 , boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)
408 boost::asio::ip::udp::socket::receive_buffer_size option(33554432);
416 , boost::asio::placeholders::error
417 , boost::asio::placeholders::bytes_transferred
425 std::string
const& address
427 boost::asio::io_service service;
428 boost::asio::ip::tcp::resolver resolver(service);
430 std::string::size_type
const pos = address.find(
":");
432 std::string
const host = pos == std::string::npos ? address : address.substr(0, pos);
433 std::string
const port = pos == std::string::npos ?
"5553" : address.substr(pos + 1);
435 boost::asio::ip::tcp::resolver::query query(
436 boost::asio::ip::tcp::v4()
441 return *resolver.resolve(query);
444 int main(
int argc,
char* argv[])
447 uint32_t type =
unkn;
448 bool uses_roy =
false;
449 bool use_gui =
false;
450 bool lm_mode =
false;
452 std::string dom_names = std::getenv(
"HOME") + std::string(
"/.doms.csk");
453 dom_map_type dom_names_map;
455 std::ofstream output_file;
457 unsigned int port = 0;
459 std::string filename;
460 std::string roy_setup;
462 std::string lserver =
"localhost:5553";
464 boost::asio::ip::tcp::endpoint endpoint;
466 po::options_description desc(
"Generic options");
468 (
"help,h",
"Print this help and exit.")
469 (
"version,v",
"Print the version and exit.")
472 , po::value<std::string>(&dom_names)->value_name(
"filename")
473 ,
"File that specifies a conversion from DOM IDs to a human readable name."
476 (
"gui,g",
"Use GUI (avalilable in UDP-monitoring and Ligier modes only).")
478 (
"ligier,l",
"Set Ligier mode.")
479 (
"udp,u",
"Force UDP mode (default).");
481 po::options_description lmdesc(
"Ligier-mode options");
485 , po::value<std::string>(&lserver)
486 ->default_value(
"localhost:5553")
487 ->value_name(
"server:[port]")
488 ,
"Set the Ligier server endpoint to read data from."
492 , po::value<std::string>(&tag)
493 ->default_value(
"IO_MONIT")
495 ,
"Set the Ligier tag to read data from."
498 po::options_description umdesc(
"UDP-mode options");
501 po::value<unsigned int>(&port)
503 ->value_name(
"port"),
504 "Set the expected data type to optical. If a port is not \
505 provided the default one is used (56015).")
507 po::value<unsigned int>(&port)
509 ->value_name(
"port"),
510 "Set the expected data type to acoustic. If a port is not \
511 provided the default one is used (56016).")
513 po::value<unsigned int>(&port)
515 ->value_name(
"port"),
516 "Set the expected data type to monitoring. If a port is \
517 not provided the default one is used (56017).")
519 po::value<unsigned int>(&port)->value_name(
"port"),
520 "Listen on the specified port, automatically determining the \
523 po::value<std::string>(&filename)->value_name(
"filename"),
524 "Dumps the acquired data to a file.")
526 po::value<std::string>(&roy_setup)
527 ->implicit_value(
"HR_%n.%c:localhost:9999")
528 ->value_name(
"format:host:port"),
529 "Send the monitoring hit rates to the specified ROyWeb \
530 server. The syntax is format:server_ip:server_port. \
531 The format parameter can contain the following placeholders: %d for \
532 DOM ID, %n for DOM name (if available, otherwise the DOM ID is used) \
533 and %c for channel ID.");
536 std::string roy_server;
540 po::options_description global;
541 global.add(desc).add(lmdesc).add(umdesc);
543 po::variables_map vm;
545 po::command_line_parser(argc, argv).
options(global).run()
549 if (vm.count(
"help")) {
557 if (vm.count(
"version")) {
565 use_gui = vm.count(
"gui");
568 lm_mode = vm.count(
"ligier");
570 if (lm_mode && vm.count(
"udp")) {
571 throw std::runtime_error(
"You can specify only one mode. Both provided.");
574 if (vm.count(
"map")) {
575 std::ifstream
map(dom_names.c_str());
578 throw std::runtime_error(
579 std::string(
"Error reading map file: ")
580 + std::strerror(errno)
586 std::ifstream
map(dom_names.c_str());
592 po::variables_map vm;
593 po::options_description
options;
594 options.add(lmdesc).add(desc);
597 po::command_line_parser(argc, argv).
options(options).run()
607 po::variables_map vm;
608 po::options_description
options;
609 options.add(desc).add(umdesc);
612 po::command_line_parser(argc, argv).
options(options).run()
618 unsigned int counter = 0;
619 if (vm.count(
"port")) {
623 if (vm.count(
"optical")) {
627 if (vm.count(
"acoustic")) {
631 if (vm.count(
"monitoring")) {
638 throw std::runtime_error(
"More than one port provided.");
640 throw std::runtime_error(
"You must specify at least one port.");
644 if (use_gui && type !=
tmch) {
645 throw std::runtime_error(
"GUI is only available in monitoring mode");
648 if (vm.count(
"royweb")) {
650 throw std::runtime_error(
"you can use ROyWeb only with the"
651 " monitoring channel");
655 std::replace(roy_setup.begin(), roy_setup.end(),
':',
' ');
656 std::istringstream ss(roy_setup);
661 if (ss >> roy_server) {
664 if (ss >> roy_port) {
668 if (param_count != 3) {
669 throw std::runtime_error(
"you must specify all the parameters"
670 " or accept all the default one to use with ROyWeb.");
674 if (vm.count(
"dumpfile")) {
675 output_file.open(filename.c_str(), std::ios::binary);
677 throw std::runtime_error(
678 "Unable to open file "
687 }
catch (
const po::error& e) {
689 <<
"CLBSwissKnife: Error: " << e.what() <<
'\n'
695 }
catch (
const std::runtime_error& e) {
696 std::cerr <<
"CLBSwissKnife: Error: " << e.what() << std::endl;
700 boost::asio::io_service io_service;
711 boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
713 boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
715 boost::asio::signal_set window_resize(io_service, SIGWINCH);
718 gui::ScreenInitialiser init;
720 gui::Screen screen(io_service, lserver, stats);
722 keyb.async_read_some(
723 boost::asio::buffer(&key,
sizeof(key)),
729 boost::asio::placeholders::error,
730 boost::asio::placeholders::bytes_transferred
739 boost::asio::placeholders::error
749 , clbsk::consumer::Gui(terminal_width, dom_names_map, stats, screen)
752 window_resize.async_wait(
755 boost::ref(window_resize),
757 boost::asio::placeholders::error,
758 boost::asio::placeholders::signal_number
765 std::cout <<
"Listening from: " << endpoint <<
':' << tag <<
'\n';
766 boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
768 signals_handler.async_wait(
771 boost::ref(signals_handler),
772 boost::ref(terminal_width),
773 boost::asio::placeholders::error,
774 boost::asio::placeholders::signal_number
784 , clbsk::consumer::Scrollback(terminal_width,
tmch, dom_names_map)
790 std::cout <<
"Listening port: " << port <<
'\n' <<
"Data type: ";
793 std::cout <<
"Acoustic\n";
794 }
else if (type ==
ttdc) {
795 std::cout <<
"Optical\n";
796 }
else if (type ==
tmch) {
797 std::cout <<
"Monitoring\n";
799 std::cout <<
"Automatically determined\n";
802 clbsk::consumer::ConsumerSet consumer_set;
804 trm::MonStreamer ms(roy_server, roy_port);
812 <<
") with tag format "
813 << templ << std::endl;
816 clbsk::consumer::Roy(
825 consumer_set.add(clbsk::consumer::File(output_file));
832 boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
834 boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
836 boost::asio::signal_set window_resize(io_service, SIGWINCH);
839 gui::ScreenInitialiser init;
841 std::string
const heading
842 =
"UDP " + boost::lexical_cast<std::string>(port);
844 gui::Screen screen(io_service, heading, stats);
846 keyb.async_read_some(
847 boost::asio::buffer(&key,
sizeof(key)),
853 boost::asio::placeholders::error,
854 boost::asio::placeholders::bytes_transferred
863 boost::asio::placeholders::error
867 window_resize.async_wait(
870 boost::ref(window_resize),
872 boost::asio::placeholders::error,
873 boost::asio::placeholders::signal_number
878 clbsk::consumer::Gui(
898 clbsk::consumer::Scrollback(
905 boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
907 signals_handler.async_wait(
910 , boost::ref(signals_handler)
911 , boost::ref(terminal_width)
912 , boost::asio::placeholders::error
913 , boost::asio::placeholders::signal_number
931 boost::asio::signal_set& set,
933 boost::system::error_code
const& error,
938 if (signum == SIGINT) {
939 set.get_io_service().stop();
941 std::cout <<
"\033]2;thank you for flying with CLBSwissKnife!\007";
942 std::cout <<
"\rBye bye!\n";
945 }
else if (signum == SIGWINCH) {
953 boost::ref(terminal_width),
954 boost::asio::placeholders::error,
955 boost::asio::placeholders::signal_number
static int terminal_width
void data_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
void handle_signal(boost::asio::signal_set &set, int &terminal_width, boost::system::error_code const &error, int signum)
struct __attribute__((__packed__)) InfoWord
void async_win_resize(boost::asio::signal_set &window_resize, gui::Screen &screen, boost::system::error_code const &error, int signum)
TString replace(const TString &target, const TRegexp ®exp, const T &replacement)
Replace regular expression in input by given replacement.
std::size_t m_buffer_size
void timeout_handle(boost::system::error_code const &error)
LigierDataHandler(LigierDataHandler const &)
UdpDataHandler(boost::asio::io_service &service, int port, char *buffer, std::size_t buffer_size, Consumer const &consumer)
std::size_t const m_buffer_size
LigierDataHandler(boost::asio::io_service &service, std::string const &tag, boost::asio::ip::tcp::endpoint const &endpoint, char *buffer, std::size_t buffer_size, Consumer const &consumer)
void data_handle(boost::system::error_code const &error, std::size_t size)
then print u2 $script< option > print u2 Possible options
LigierDataHandler & operator=(LigierDataHandler const &)
static const size_t buffer_size
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
std::size_t prepare_tag(char *buffer, std::size_t max_size, std::string const &tag)
void subscribe_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
void connect_handle(boost::system::error_code const &error)
boost::asio::ip::tcp::endpoint m_endpoint
void header_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
static const unsigned int default_opto_port
int get_terminal_width()
Program name: CLBSwissKnife.
boost::asio::deadline_timer m_timer
boost::asio::ip::tcp::endpoint make_endpoint(const std::string &address)
void async_cin(boost::asio::posix::stream_descriptor &keyb, char &key, gui::Screen &screen, const boost::system::error_code &error, std::size_t bytes_transferred)
std::size_t read_data_size(char const *const buffer)
void async_commit(boost::asio::deadline_timer &timer, gui::Screen &screen, boost::system::error_code const &error)
dom_map_type load_dom_map(std::istream &map)
boost::asio::ip::udp::socket m_socket
boost::asio::ip::tcp::socket m_socket
LigierDataHandler< Consumer > this_type
UdpDataHandler< Consumer > this_type
static const unsigned int default_acou_port
static const unsigned int default_moni_port
int main(int argc, char *argv[])