135 #include <boost/asio.hpp> 
  136 #include <boost/program_options.hpp> 
  138 #include <sys/ioctl.h> 
  144 #if BOOST_VERSION >= 107000 
  145 #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) 
  147 #define GET_IO_SERVICE(s) ((s).get_io_service()) 
  150 #include "structs.hpp" 
  151 #include "datatypes.hpp" 
  152 #include "version.hpp" 
  153 #include "ligier_helper.hpp" 
  154 #include "consumers.hpp" 
  155 #include "dom_map.hpp" 
  159   static bool const is_a_tty = isatty(1);
 
  166     ioctl(1, TIOCGWINSZ, &sz);
 
  171 namespace po = boost::program_options;
 
  182     boost::asio::signal_set& set,
 
  184     boost::system::error_code 
const& error,
 
  188 template<
class Consumer>
 
  205       boost::system::error_code 
const& error
 
  209     if (error && error != boost::asio::error::operation_aborted) {
 
  212     } 
else if (error == boost::asio::error::operation_aborted) {
 
  216       boost::asio::async_read(
 
  222             , boost::asio::placeholders::error
 
  223             , boost::asio::placeholders::bytes_transferred
 
  237             , boost::asio::placeholders::error
 
  245     if (error && error != boost::asio::error::operation_aborted) {
 
  247       m_timer.expires_from_now(boost::posix_time::seconds(1));
 
  253             , boost::asio::placeholders::error
 
  256     } 
else if (error == boost::asio::error::operation_aborted) {
 
  260       boost::asio::async_write(
 
  262         , boost::asio::buffer(
m_buffer, size)
 
  266             , boost::asio::placeholders::error
 
  267             , boost::asio::placeholders::bytes_transferred
 
  274       boost::system::error_code 
const& error
 
  275     , std::size_t bytes_transferred
 
  277     if (error && error != boost::asio::error::operation_aborted) {
 
  280     } 
else if (error == boost::asio::error::operation_aborted) {
 
  282       boost::asio::async_read(
 
  288             , boost::asio::placeholders::error
 
  289             , boost::asio::placeholders::bytes_transferred
 
  296       boost::system::error_code 
const& error
 
  297     , std::size_t bytes_transferred
 
  299     if (error && error != boost::asio::error::operation_aborted) {
 
  302     } 
else if (error == boost::asio::error::operation_aborted) {
 
  306       boost::asio::async_read(
 
  308         , boost::asio::buffer(
m_buffer + 16, size)
 
  312             , boost::asio::placeholders::error
 
  313             , boost::asio::placeholders::bytes_transferred
 
  321     boost::system::error_code ec;
 
  323     m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
 
  331           , boost::asio::placeholders::error
 
  342       boost::asio::io_service& service
 
  344     , boost::asio::ip::tcp::endpoint 
const& endpoint
 
  347     , Consumer 
const& consumer
 
  361           , boost::asio::placeholders::error
 
  367 template<
class Consumer>
 
  378       boost::system::error_code 
const& error
 
  379     , std::size_t bytes_transferred
 
  392           , boost::asio::placeholders::error
 
  393           , boost::asio::placeholders::bytes_transferred
 
  401       boost::asio::io_service& service
 
  405     , Consumer 
const& consumer
 
  408         , boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)
 
  414     boost::asio::ip::udp::socket::receive_buffer_size option(33554432);
 
  422           , boost::asio::placeholders::error
 
  423           , boost::asio::placeholders::bytes_transferred
 
  433   boost::asio::io_service service;
 
  434   boost::asio::ip::tcp::resolver resolver(service);
 
  436   std::string::size_type 
const pos = address.find(
":");
 
  438   std::string const host = pos == std::string::npos ? address : address.substr(0, pos);
 
  439   std::string const port = pos == std::string::npos ? 
"5553"  : address.substr(pos + 1);
 
  441   boost::asio::ip::tcp::resolver::query query(
 
  442       boost::asio::ip::tcp::v4()
 
  447   return *resolver.resolve(query);
 
  450 int main(
int argc, 
char* argv[])
 
  453   uint32_t type = 
unkn;
 
  454   bool uses_roy = 
false;
 
  455   bool use_gui = 
false;
 
  456   bool lm_mode = 
false;
 
  459   dom_map_type dom_names_map;
 
  461   std::ofstream output_file;
 
  463   unsigned int port = 0;
 
  470   boost::asio::ip::tcp::endpoint endpoint;
 
  472   po::options_description desc(
"Generic options");
 
  474     (
"help,h",    
"Print this help and exit.")
 
  475     (
"version,v", 
"Print the version and exit.")
 
  478       , po::value<std::string>(&dom_names)->value_name(
"filename")
 
  479       , 
"File that specifies a conversion from DOM IDs to a human readable name." 
  482     (
"gui,g", 
"Use GUI (avalilable in UDP-monitoring and Ligier modes only).")
 
  484     (
"ligier,l", 
"Set Ligier mode.")
 
  485     (
"udp,u", 
"Force UDP mode (default).");
 
  487   po::options_description lmdesc(
"Ligier-mode options");
 
  491       , po::value<std::string>(&lserver)
 
  492           ->default_value(
"localhost:5553")
 
  493           ->value_name(
"server:[port]")
 
  494       , 
"Set the Ligier server endpoint to read data from." 
  498       , po::value<std::string>(&tag)
 
  499           ->default_value(
"IO_MONIT")
 
  501       , 
"Set the Ligier tag to read data from." 
  504   po::options_description umdesc(
"UDP-mode options");
 
  507           po::value<unsigned int>(&port)
 
  509               ->value_name(
"port"),
 
  510           "Set the expected data type to optical. If a port is not \ 
  511 provided the default one is used (56015).")
 
  513           po::value<unsigned int>(&port)
 
  515               ->value_name(
"port"),
 
  516           "Set the expected data type to acoustic. If a port is not \ 
  517 provided the default one is used (56016).")
 
  519           po::value<unsigned int>(&port)
 
  521               ->value_name(
"port"),
 
  522           "Set the expected data type to monitoring. If a port is \ 
  523 not provided the default one is used (56017).")
 
  525           po::value<unsigned int>(&port)->value_name(
"port"),
 
  526           "Listen on the specified port, automatically determining the \ 
  529           po::value<std::string>(&filename)->value_name(
"filename"),
 
  530           "Dumps the acquired data to a file.")
 
  532           po::value<std::string>(&roy_setup)
 
  533               ->implicit_value(
"HR_%n.%c:localhost:9999")
 
  534               ->value_name(
"format:host:port"),
 
  535           "Send the monitoring hit rates to the specified ROyWeb \ 
  536 server. The syntax is format:server_ip:server_port. \ 
  537 The format parameter can contain the following placeholders: %d for \ 
  538 DOM ID, %n for DOM name (if available, otherwise the DOM ID is used) \ 
  539 and %c for channel ID.");
 
  546     po::options_description global;
 
  547     global.add(desc).add(lmdesc).add(umdesc);
 
  549     po::variables_map vm;
 
  551         po::command_line_parser(argc, argv).
options(global).run()
 
  555     if (vm.count(
"help")) {
 
  563     if (vm.count(
"version")) {
 
  571     use_gui = vm.count(
"gui");
 
  574     lm_mode = vm.count(
"ligier");
 
  576     if (lm_mode && vm.count(
"udp")) {
 
  577       throw std::runtime_error(
"You can specify only one mode. Both provided.");
 
  580     if (vm.count(
"map")) {
 
  581       std::ifstream 
map(dom_names.c_str());
 
  584         throw std::runtime_error(
 
  586             + std::strerror(errno)
 
  592       std::ifstream 
map(dom_names.c_str());
 
  598       po::variables_map vm;
 
  599       po::options_description 
options;
 
  600       options.add(lmdesc).add(desc);
 
  603           po::command_line_parser(argc, argv).
options(options).run()
 
  613       po::variables_map vm;
 
  614       po::options_description 
options;
 
  615       options.add(desc).add(umdesc);
 
  618           po::command_line_parser(argc, argv).
options(options).run()
 
  624       unsigned int counter = 0;
 
  625       if (vm.count(
"port")) {
 
  629       if (vm.count(
"optical")) {
 
  633       if (vm.count(
"acoustic")) {
 
  637       if (vm.count(
"monitoring")) {
 
  644           throw std::runtime_error(
"More than one port provided.");
 
  646           throw std::runtime_error(
"You must specify at least one port.");
 
  650       if (use_gui && type != 
tmch) {
 
  651         throw std::runtime_error(
"GUI is only available in monitoring mode");
 
  654       if (vm.count(
"royweb")) {
 
  656           throw std::runtime_error(
"you can use ROyWeb only with the" 
  657           " monitoring channel");
 
  661         std::replace(roy_setup.begin(), roy_setup.end(), 
':', 
' ');
 
  662         std::istringstream ss(roy_setup);
 
  667         if (ss >> roy_server) {
 
  670         if (ss >> roy_port) {
 
  674         if (param_count != 3) {
 
  675           throw std::runtime_error(
"you must specify all the parameters" 
  676           " or accept all the default one to use with ROyWeb.");
 
  680       if (vm.count(
"dumpfile")) {
 
  681         output_file.open(filename.c_str(), std::ios::binary);
 
  683           throw std::runtime_error(
 
  684               "Unable to open file " 
  693   } 
catch (
const po::error& e) {
 
  695       << 
"CLBSwissKnife: Error: " << e.what() << 
'\n' 
  701   } 
catch (
const std::runtime_error& e) {
 
  702     std::cerr << 
"CLBSwissKnife: Error: " << e.what() << std::endl;
 
  706   boost::asio::io_service io_service;
 
  717       boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
 
  719       boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
 
  721       boost::asio::signal_set window_resize(io_service, SIGWINCH);
 
  724       gui::ScreenInitialiser init;
 
  726       gui::Screen screen(io_service, lserver, stats);
 
  728       keyb.async_read_some(
 
  729           boost::asio::buffer(&key, 
sizeof(key)),
 
  735               boost::asio::placeholders::error,
 
  736               boost::asio::placeholders::bytes_transferred
 
  745               boost::asio::placeholders::error
 
  755         , clbsk::consumer::Gui(terminal_width, dom_names_map, stats, screen)
 
  758       window_resize.async_wait(
 
  761               boost::ref(window_resize),
 
  763               boost::asio::placeholders::error,
 
  764               boost::asio::placeholders::signal_number
 
  771       std::cout << 
"Listening from: " << endpoint << 
':' << tag << 
'\n';
 
  772       boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
 
  774       signals_handler.async_wait(
 
  777               boost::ref(signals_handler),
 
  778               boost::ref(terminal_width),
 
  779               boost::asio::placeholders::error,
 
  780               boost::asio::placeholders::signal_number
 
  790         , clbsk::consumer::Scrollback(terminal_width, 
tmch, dom_names_map)
 
  796     std::cout << 
"Listening port: " << port << 
'\n' << 
"Data type: ";
 
  799       std::cout << 
"Acoustic\n";
 
  800     } 
else if (type == 
ttdc) {
 
  801       std::cout << 
"Optical\n";
 
  802     } 
else if (type == 
tmch) {
 
  803       std::cout << 
"Monitoring\n";
 
  805       std::cout << 
"Automatically determined\n";
 
  808     clbsk::consumer::ConsumerSet consumer_set;
 
  810     trm::MonStreamer ms(roy_server, roy_port);
 
  818         << 
") with tag format " 
  819         << templ << std::endl;
 
  822           clbsk::consumer::Roy(
 
  831       consumer_set.add(clbsk::consumer::File(output_file));
 
  838       boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
 
  840       boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
 
  842       boost::asio::signal_set window_resize(io_service, SIGWINCH);
 
  845       gui::ScreenInitialiser init;
 
  850       gui::Screen screen(io_service, heading, stats);
 
  852       keyb.async_read_some(
 
  853           boost::asio::buffer(&key, 
sizeof(key)),
 
  859               boost::asio::placeholders::error,
 
  860               boost::asio::placeholders::bytes_transferred
 
  869               boost::asio::placeholders::error
 
  873       window_resize.async_wait(
 
  876               boost::ref(window_resize),
 
  878               boost::asio::placeholders::error,
 
  879               boost::asio::placeholders::signal_number
 
  884           clbsk::consumer::Gui(
 
  904           clbsk::consumer::Scrollback(
 
  911       boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
 
  913       signals_handler.async_wait(
 
  916             , boost::ref(signals_handler)
 
  917             , boost::ref(terminal_width)
 
  918             , boost::asio::placeholders::error
 
  919             , boost::asio::placeholders::signal_number
 
  937     boost::asio::signal_set& set,
 
  939     boost::system::error_code 
const& error,
 
  944     if (signum == SIGINT) {
 
  949         std::cout << 
"\033]2;thank you for flying with CLBSwissKnife!\007";
 
  950         std::cout << 
"\rBye bye!\n";
 
  953     } 
else if (signum == SIGWINCH) {
 
  961             boost::ref(terminal_width),
 
  962             boost::asio::placeholders::error,
 
  963             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)
 
int main(int argc, char *argv[])
 
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 usage $script[port]< option > nPossible 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
 
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
 
#define GET_IO_SERVICE(s)
Program name: CLBSwissKnife. 
 
static const unsigned int default_acou_port
 
static const unsigned int default_moni_port