Jpp  master_rocky-40-g5f0272dcd
the software that should make you happy
clb_swiss_knife.cpp
Go to the documentation of this file.
1 /**
2 
3  Program name: CLBSwissKnife
4 
5  General description:
6  This program aims to provide a powerful debugging
7  tool for all the kind of data sent by a KM3NeT DOM.
8 
9  It listens to the specified UDP port and prints out to
10  the screen some informations contained in the read
11  CLB datagrams.
12 
13  Since version 5.0, it operates in two main modes:
14 
15  - in UDP mode (available since the first release), the
16  program reads data directly from a UDP port. In this
17  mode it is allowed to perform several tasks, such as
18  read all kind of data, dump data on file and send
19  monitoring data to a RoyWeb server;
20 
21  - in Ligier mode, data are retrieved from a Ligier
22  subscription. Only monitoring data are available and
23  no secondary tasks are allowed.
24 
25  General options:
26  The program is configured via command line parameters.
27  UDP mode is default and can be forced with the -u/--udp
28  command line switch. Ligier mode can be activated with
29  the -l/--ligier switch.
30 
31  In the systems where the ncurses libraries are present,
32  is possible to use the -g/--gui option to display multiple
33  DOMs data via a text gui, in conjunction of the UDP-mode
34  "-m/--monitoring" option or in the Ligier mode.
35  Press the 'h' key to see the help for GUI mode.
36  Arroy keys can be used to select a dom and to scroll
37  the list.
38 
39  With the "--map" option the user can specify a map file to
40  be used to match the DOM IDs of incoming data.
41  The DOM map file is an ASCII file reporting assignments
42  of DOM IDs or MAC addresses with names. Each assignment
43  must be separated by a semicolon. An example of map file
44  follows:
45 
46  08:00:30:BE:B7:A2 = CLB19;
47  817805038 = CLB13;
48 
49  By default, CLBSwissKnife will try to load the file
50 
51  ~/.doms.csk
52 
53  as a map file. The user can write the information about
54  its setup to this file and let CLBSK use it without
55  specifying any "--map" option.
56 
57  Use:
58  $ CLBSwissKnife -h
59  for a detailed help and
60  $ CLBSwissKnife -v
61  for version information.
62 
63  UDP-mode options:
64  The user can specify the port to bind and/or the data
65  type:
66 
67  - if the port is specified using the "-p" or "--port"
68  options the type is automatically determined as
69  data comes;
70 
71  - if the port is specified using one of the other
72  options ("-o/--optical", "-a/--acoustic",
73  "-m/--monitoring"), the program is forced to parse
74  the incoming data with the specified data type;
75  with these options it is not mandatory to specify a
76  port number, since a default value is pre-defined.
77 
78  With the "-f/--dump-file" option is also possible to
79  specify a destination file in which the incoming
80  data will be stored for offline analysis.
81 
82  In the monitoring-mode, with the "-r/--royweb" option
83  it is possible to send the hit rates to a ROyWeb
84  server. This option accept 3 parameters separated by
85  a colon character (":"), which are:
86 
87  - the format of the name of the ROy parameter; the
88  format string allows the use of the following
89  place-holders:
90  + "%d": DOM ID
91  + "%n": DOM name as in the map file (see below);
92  if not present the DOM ID is used.
93  + "%c": channel ID (0-30)
94  - the ROyWeb server address
95  - the ROyWeb server port
96 
97  Es: CLBSwissKnife -m -r HitRates-DOM%d-CH%c:localhost:9999
98 
99  A default HR_%n.%c:localhost:9999 is used, otherwise
100  all three parameters must be set at once.
101 
102  Moreover, the time difference between two consecutive
103  monitoring packets is sent to the ROy server with the
104  tag "Time_difference". This is useful in order to
105  highlight possible packet losses when a single CLB is
106  used.
107 
108  Ligier-mode options:
109  The Ligier mode allows the user to monitor CLB data
110  using a Ligier connection. To be activated a "-l/--ligier"
111  flag must be present in the command line.
112 
113  Ligier endpoint can be set with "-s/--server", while
114  the tag can be set with the "-t/--tag". Proper default
115  values are available and are listed in the on-line
116  help.
117 
118  E-mail: carmelo.pellegrino@bo.infn.it
119  Date: 27 October 2014
120 
121  \author Carmelo Pellegrino
122 */
123 
124 #include <iostream>
125 #include <stdint.h>
126 #include <stddef.h>
127 #include <string>
128 #include <stdexcept>
129 #include <fstream>
130 #include <ctime>
131 #include <cerrno>
132 #include <cstring>
133 #include <cstdlib>
134 
135 #include <boost/asio.hpp>
136 #include <boost/program_options.hpp>
137 
138 #include <sys/ioctl.h>
139 
140 #ifdef CURSES_FOUND
141 # include "gui.hpp"
142 #endif
143 
144 #if BOOST_VERSION >= 107000
145 #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
146 #else
147 #define GET_IO_SERVICE(s) ((s).get_io_service())
148 #endif
149 
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"
156 
158 {
159  static bool const is_a_tty = isatty(1);
160 
161  if (!is_a_tty) {
162  return 80;
163  } else {
164  struct winsize sz;
165 
166  ioctl(1, TIOCGWINSZ, &sz);
167  return sz.ws_col;
168  }
169 }
170 
171 namespace po = boost::program_options;
172 
173 // TODO: use the CLBDataGram instead of a buffer
174 
175 const static size_t buffer_size = 10000;
176 
177 const static unsigned int default_opto_port = 56015;
178 const static unsigned int default_acou_port = 56016;
179 const static unsigned int default_moni_port = 56017;
180 
181 void handle_signal(
182  boost::asio::signal_set& set,
183  int& terminal_width,
184  boost::system::error_code const& error,
185  int signum
186 );
187 
188 template<class Consumer>
190 {
192 
193  boost::asio::ip::tcp::socket m_socket;
194  boost::asio::deadline_timer m_timer;
195 
196  std::string m_tag;
197  boost::asio::ip::tcp::endpoint m_endpoint;
198 
199  char* m_buffer;
200  std::size_t const m_buffer_size;
201 
202  Consumer m_consumer;
203 
205  boost::system::error_code const& error
206  , std::size_t size
207  )
208  {
209  if (error && error != boost::asio::error::operation_aborted) {
210  m_consumer(error, 0, 0);
211  restart();
212  } else if (error == boost::asio::error::operation_aborted) {
213  } else {
214  m_consumer(error, m_buffer + 16, size);
215 
216  boost::asio::async_read(
217  m_socket
218  , boost::asio::buffer(m_buffer, 16)
219  , boost::bind(
221  , this
222  , boost::asio::placeholders::error
223  , boost::asio::placeholders::bytes_transferred
224  )
225  );
226  }
227  }
228 
229  void timeout_handle(boost::system::error_code const& error)
230  {
231  if (!error) {
232  m_socket.async_connect(
233  m_endpoint
234  , boost::bind(
236  , this
237  , boost::asio::placeholders::error
238  )
239  );
240  }
241  }
242 
243  void connect_handle(boost::system::error_code const& error)
244  {
245  if (error && error != boost::asio::error::operation_aborted) {
246  m_consumer(error, 0, 0);
247  m_timer.expires_from_now(boost::posix_time::seconds(1));
248 
249  m_timer.async_wait(
250  boost::bind(
252  , this
253  , boost::asio::placeholders::error
254  )
255  );
256  } else if (error == boost::asio::error::operation_aborted) {
257  } else {
258  std::size_t const size = ligier::prepare_tag(m_buffer, m_buffer_size, m_tag);
259 
260  boost::asio::async_write(
261  m_socket
262  , boost::asio::buffer(m_buffer, size)
263  , boost::bind(
265  , this
266  , boost::asio::placeholders::error
267  , boost::asio::placeholders::bytes_transferred
268  )
269  );
270  }
271  }
272 
274  boost::system::error_code const& error
275  , std::size_t bytes_transferred
276  ) {
277  if (error && error != boost::asio::error::operation_aborted) {
278  m_consumer(error, 0, 0);
279  restart();
280  } else if (error == boost::asio::error::operation_aborted) {
281  } else {
282  boost::asio::async_read(
283  m_socket
284  , boost::asio::buffer(m_buffer, 16)
285  , boost::bind(
287  , this
288  , boost::asio::placeholders::error
289  , boost::asio::placeholders::bytes_transferred
290  )
291  );
292  }
293  }
294 
296  boost::system::error_code const& error
297  , std::size_t bytes_transferred
298  ) {
299  if (error && error != boost::asio::error::operation_aborted) {
300  m_consumer(error, 0, 0);
301  restart();
302  } else if (error == boost::asio::error::operation_aborted) {
303  } else {
304  std::size_t const size = ligier::read_data_size(m_buffer);
305 
306  boost::asio::async_read(
307  m_socket
308  , boost::asio::buffer(m_buffer + 16, size)
309  , boost::bind(
311  , this
312  , boost::asio::placeholders::error
313  , boost::asio::placeholders::bytes_transferred
314  )
315  );
316  }
317  }
318 
319  void restart()
320  {
321  boost::system::error_code ec;
322 
323  m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
324  m_socket.close(ec);
325 
326  m_socket.async_connect(
327  m_endpoint
328  , boost::bind(
330  , this
331  , boost::asio::placeholders::error
332  )
333  );
334  }
335 
336  LigierDataHandler(LigierDataHandler const&); // non-copyable
338 
339  public:
340 
342  boost::asio::io_service& service
343  , std::string const& tag
344  , boost::asio::ip::tcp::endpoint const& endpoint
345  , char* buffer
346  , std::size_t buffer_size
347  , Consumer const& consumer
348  ) : m_socket(service)
349  , m_timer(service)
350  , m_tag(tag)
351  , m_endpoint(endpoint)
352  , m_buffer(buffer)
354  , m_consumer(consumer)
355  {
356  m_socket.async_connect(
357  m_endpoint
358  , boost::bind(
360  , this
361  , boost::asio::placeholders::error
362  )
363  );
364  }
365 };
366 
367 template<class Consumer>
369 {
371 
372  boost::asio::ip::udp::socket m_socket;
373  char* m_buffer;
374  std::size_t m_buffer_size;
375  Consumer m_consumer;
376 
378  boost::system::error_code const& error
379  , std::size_t bytes_transferred
380  ) {
381  if (error) {
382  m_consumer(error, 0, 0);
383  } else {
384  m_consumer(error, m_buffer, bytes_transferred);
385  }
386 
387  m_socket.async_receive(
388  boost::asio::buffer(m_buffer, m_buffer_size)
389  , boost::bind(
391  , this
392  , boost::asio::placeholders::error
393  , boost::asio::placeholders::bytes_transferred
394  )
395  );
396  }
397 
398  public:
399 
401  boost::asio::io_service& service
402  , int port
403  , char* buffer
404  , std::size_t buffer_size
405  , Consumer const& consumer
406  ) : m_socket(
407  service
408  , boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)
409  )
410  , m_buffer(buffer)
412  , m_consumer(consumer)
413  {
414 #if __APPLE__
415  boost::asio::ip::udp::socket::receive_buffer_size option(3554432);
416 #else
417  boost::asio::ip::udp::socket::receive_buffer_size option(33554432);
418 #endif
419  m_socket.set_option(option);
420 
421  m_socket.async_receive(
422  boost::asio::buffer(m_buffer, m_buffer_size)
423  , boost::bind(
425  , this
426  , boost::asio::placeholders::error
427  , boost::asio::placeholders::bytes_transferred
428  )
429  );
430  }
431 };
432 
433 inline
434 boost::asio::ip::tcp::endpoint make_endpoint(
435  std::string const& address
436 ) {
437  boost::asio::io_service service;
438  boost::asio::ip::tcp::resolver resolver(service);
439 
440  std::string::size_type const pos = address.find(":");
441 
442  std::string const host = pos == std::string::npos ? address : address.substr(0, pos);
443  std::string const port = pos == std::string::npos ? "5553" : address.substr(pos + 1);
444 
445  boost::asio::ip::tcp::resolver::query query(
446  boost::asio::ip::tcp::v4()
447  , host
448  , port
449  );
450 
451  return *resolver.resolve(query);
452 }
453 
454 int main(int argc, char* argv[])
455 {
456  bool dump = false;
457  uint32_t type = unkn;
458  bool uses_roy = false;
459  bool use_gui = false;
460  bool lm_mode = false;
461 
462  std::string dom_names = std::getenv("HOME") + std::string("/.doms.csk");
463  dom_map_type dom_names_map;
464 
465  std::ofstream output_file;
466 
467  unsigned int port = 0;
468 
469  std::string filename;
470  std::string roy_setup;
471 
472  std::string lserver = "localhost:5553";
473  std::string tag;
474  boost::asio::ip::tcp::endpoint endpoint;
475 
476  po::options_description desc("Generic options");
477  desc.add_options()
478  ("help,h", "Print this help and exit.")
479  ("version,v", "Print the version and exit.")
480  (
481  "map"
482  , po::value<std::string>(&dom_names)->value_name("filename")
483  , "File that specifies a conversion from DOM IDs to a human readable name."
484  )
485 #ifdef CURSES_FOUND
486  ("gui,g", "Use GUI (avalilable in UDP-monitoring and Ligier modes only).")
487 #endif
488  ("ligier,l", "Set Ligier mode.")
489  ("udp,u", "Force UDP mode (default).");
490 
491  po::options_description lmdesc("Ligier-mode options");
492  lmdesc.add_options()
493  (
494  "server,s"
495  , po::value<std::string>(&lserver)
496  ->default_value("localhost:5553")
497  ->value_name("server:[port]")
498  , "Set the Ligier server endpoint to read data from."
499  )
500  (
501  "tag,t"
502  , po::value<std::string>(&tag)
503  ->default_value("IO_MONIT")
504  ->value_name("tag")
505  , "Set the Ligier tag to read data from."
506  );
507 
508  po::options_description umdesc("UDP-mode options");
509  umdesc.add_options()
510  ("optical,o",
511  po::value<unsigned int>(&port)
512  ->implicit_value(default_opto_port)
513  ->value_name("port"),
514  "Set the expected data type to optical. If a port is not \
515 provided the default one is used (56015).")
516  ("acoustic,a",
517  po::value<unsigned int>(&port)
518  ->implicit_value(default_acou_port)
519  ->value_name("port"),
520  "Set the expected data type to acoustic. If a port is not \
521 provided the default one is used (56016).")
522  ("monitoring,m",
523  po::value<unsigned int>(&port)
524  ->implicit_value(default_moni_port)
525  ->value_name("port"),
526  "Set the expected data type to monitoring. If a port is \
527 not provided the default one is used (56017).")
528  ("port,p",
529  po::value<unsigned int>(&port)->value_name("port"),
530  "Listen on the specified port, automatically determining the \
531 data type.")
532  ("dumpfile,f",
533  po::value<std::string>(&filename)->value_name("filename"),
534  "Dumps the acquired data to a file.")
535  ("royweb,r",
536  po::value<std::string>(&roy_setup)
537  ->implicit_value("HR_%n.%c:localhost:9999")
538  ->value_name("format:host:port"),
539  "Send the monitoring hit rates to the specified ROyWeb \
540 server. The syntax is format:server_ip:server_port. \
541 The format parameter can contain the following placeholders: %d for \
542 DOM ID, %n for DOM name (if available, otherwise the DOM ID is used) \
543 and %c for channel ID.");
544 
545  std::string templ;
546  std::string roy_server;
547  int roy_port = 0;
548 
549  try {
550  po::options_description global;
551  global.add(desc).add(lmdesc).add(umdesc);
552 
553  po::variables_map vm;
554  po::store(
555  po::command_line_parser(argc, argv).options(global).run()
556  , vm
557  );
558 
559  if (vm.count("help")) {
560  std::cout
561  << desc << '\n'
562  << umdesc << '\n'
563  << lmdesc << '\n';
564  return EXIT_SUCCESS;
565  }
566 
567  if (vm.count("version")) {
568  std::cout << clbsk::version::v() << std::endl;
569  return EXIT_SUCCESS;
570  }
571 
572  po::notify(vm);
573 
574 #ifdef CURSES_FOUND
575  use_gui = vm.count("gui");
576 #endif
577 
578  lm_mode = vm.count("ligier");
579 
580  if (lm_mode && vm.count("udp")) {
581  throw std::runtime_error("You can specify only one mode. Both provided.");
582  }
583 
584  if (vm.count("map")) {
585  std::ifstream map(dom_names.c_str());
586 
587  if (! map) {
588  throw std::runtime_error(
589  std::string("Error reading map file: ")
590  + std::strerror(errno)
591  );
592  }
593 
594  dom_names_map = load_dom_map(map);
595  } else {
596  std::ifstream map(dom_names.c_str());
597 
598  dom_names_map = load_dom_map(map);
599  }
600 
601  if (lm_mode) {
602  po::variables_map vm;
603  po::options_description options;
604  options.add(lmdesc).add(desc);
605 
606  po::store(
607  po::command_line_parser(argc, argv).options(options).run()
608  , vm
609  );
610 
611  po::notify(vm);
612 
613  endpoint = make_endpoint(lserver);
614 
615  type = tmch;
616  } else {
617  po::variables_map vm;
618  po::options_description options;
619  options.add(desc).add(umdesc);
620 
621  po::store(
622  po::command_line_parser(argc, argv).options(options).run()
623  , vm
624  );
625 
626  po::notify(vm);
627 
628  unsigned int counter = 0;
629  if (vm.count("port")) {
630  type = unkn;
631  ++counter;
632  }
633  if (vm.count("optical")) {
634  type = ttdc;
635  ++counter;
636  }
637  if (vm.count("acoustic")) {
638  type = taes;
639  ++counter;
640  }
641  if (vm.count("monitoring")) {
642  type = tmch;
643  ++counter;
644  }
645 
646  if (counter != 1) {
647  if (counter) {
648  throw std::runtime_error("More than one port provided.");
649  } else {
650  throw std::runtime_error("You must specify at least one port.");
651  }
652  }
653 
654  if (use_gui && type != tmch) {
655  throw std::runtime_error("GUI is only available in monitoring mode");
656  }
657 
658  if (vm.count("royweb")) {
659  if (type != tmch) {
660  throw std::runtime_error("you can use ROyWeb only with the"
661  " monitoring channel");
662  }
663 
664  uses_roy = true;
665  std::replace(roy_setup.begin(), roy_setup.end(), ':', ' ');
666  std::istringstream ss(roy_setup);
667  int param_count = 0;
668  if (ss >> templ) {
669  ++param_count;
670  }
671  if (ss >> roy_server) {
672  ++param_count;
673  }
674  if (ss >> roy_port) {
675  ++param_count;
676  }
677 
678  if (param_count != 3) {
679  throw std::runtime_error("you must specify all the parameters"
680  " or accept all the default one to use with ROyWeb.");
681  }
682  }
683 
684  if (vm.count("dumpfile")) {
685  output_file.open(filename.c_str(), std::ios::binary);
686  if (! output_file) {
687  throw std::runtime_error(
688  "Unable to open file "
689  + filename
690  + " for writing: "
691  + strerror(errno)
692  );
693  }
694  dump = true;
695  }
696  }
697  } catch (const po::error& e) {
698  std::cerr
699  << "CLBSwissKnife: Error: " << e.what() << '\n'
700  << desc << '\n'
701  << umdesc << '\n'
702  << lmdesc << '\n';
703 
704  return EXIT_FAILURE;
705  } catch (const std::runtime_error& e) {
706  std::cerr << "CLBSwissKnife: Error: " << e.what() << std::endl;
707  return EXIT_FAILURE;
708  }
709 
710  boost::asio::io_service io_service;
711  char buffer[buffer_size] __attribute__((aligned(8)));
712 
713  // Initialise the terminal width
715 
716  if (lm_mode) { // Ligier
717  if (use_gui) { // Ligier-GUI
718  #ifdef CURSES_FOUND
719  ChList stats;
720 
721  boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
722 
723  boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
724 
725  boost::asio::signal_set window_resize(io_service, SIGWINCH);
726 
727  char key = 0;
728  gui::ScreenInitialiser init;
729 
730  gui::Screen screen(io_service, lserver, stats);
731 
732  keyb.async_read_some(
733  boost::asio::buffer(&key, sizeof(key)),
734  boost::bind(
735  async_cin,
736  boost::ref(keyb),
737  boost::ref(key),
738  boost::ref(screen),
739  boost::asio::placeholders::error,
740  boost::asio::placeholders::bytes_transferred
741  )
742  );
743 
744  timer.async_wait(
745  boost::bind(
746  async_commit,
747  boost::ref(timer),
748  boost::ref(screen),
749  boost::asio::placeholders::error
750  )
751  );
752 
754  io_service
755  , tag
756  , endpoint
757  , buffer
758  , buffer_size
759  , clbsk::consumer::Gui(terminal_width, dom_names_map, stats, screen)
760  );
761 
762  window_resize.async_wait(
763  boost::bind(
765  boost::ref(window_resize),
766  boost::ref(screen),
767  boost::asio::placeholders::error,
768  boost::asio::placeholders::signal_number
769  )
770  );
771 
772  io_service.run();
773  #endif
774  } else { // Ligier-Scrollback
775  std::cout << "Listening from: " << endpoint << ':' << tag << '\n';
776  boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
777 
778  signals_handler.async_wait(
779  boost::bind(
781  boost::ref(signals_handler),
782  boost::ref(terminal_width),
783  boost::asio::placeholders::error,
784  boost::asio::placeholders::signal_number
785  )
786  );
787 
789  io_service
790  , tag
791  , endpoint
792  , buffer
793  , buffer_size
794  , clbsk::consumer::Scrollback(terminal_width, tmch, dom_names_map)
795  );
796 
797  io_service.run();
798  }
799  } else { // UDP
800  std::cout << "Listening port: " << port << '\n' << "Data type: ";
801 
802  if (type == taes) {
803  std::cout << "Acoustic\n";
804  } else if (type == ttdc) {
805  std::cout << "Optical\n";
806  } else if (type == tmch) {
807  std::cout << "Monitoring\n";
808  } else {
809  std::cout << "Automatically determined\n";
810  }
811 
812  clbsk::consumer::ConsumerSet consumer_set;
813 
814  trm::MonStreamer ms(roy_server, roy_port);
815 
816  if (uses_roy) {
817  std::cout
818  << "Using ROyWeb ("
819  << roy_server
820  << ", "
821  << roy_port
822  << ") with tag format "
823  << templ << std::endl;
824 
825  consumer_set.add(
826  clbsk::consumer::Roy(
827  dom_names_map
828  , templ
829  , ms
830  )
831  );
832  }
833 
834  if (dump) {
835  consumer_set.add(clbsk::consumer::File(output_file));
836  }
837 
838  if (use_gui) { // UDP-GUI
839  #ifdef CURSES_FOUND
840  ChList stats;
841 
842  boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
843 
844  boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
845 
846  boost::asio::signal_set window_resize(io_service, SIGWINCH);
847 
848  char key = 0;
849  gui::ScreenInitialiser init;
850 
851  std::string const heading
852  = "UDP " + boost::lexical_cast<std::string>(port);
853 
854  gui::Screen screen(io_service, heading, stats);
855 
856  keyb.async_read_some(
857  boost::asio::buffer(&key, sizeof(key)),
858  boost::bind(
859  async_cin,
860  boost::ref(keyb),
861  boost::ref(key),
862  boost::ref(screen),
863  boost::asio::placeholders::error,
864  boost::asio::placeholders::bytes_transferred
865  )
866  );
867 
868  timer.async_wait(
869  boost::bind(
870  async_commit,
871  boost::ref(timer),
872  boost::ref(screen),
873  boost::asio::placeholders::error
874  )
875  );
876 
877  window_resize.async_wait(
878  boost::bind(
880  boost::ref(window_resize),
881  boost::ref(screen),
882  boost::asio::placeholders::error,
883  boost::asio::placeholders::signal_number
884  )
885  );
886 
887  consumer_set.add(
888  clbsk::consumer::Gui(
890  , dom_names_map
891  , stats
892  , screen
893  )
894  );
895 
897  io_service
898  , port
899  , buffer
900  , buffer_size
901  , consumer_set
902  );
903 
904  io_service.run();
905  #endif
906  } else { // UDP-Scrollback
907  consumer_set.add(
908  clbsk::consumer::Scrollback(
910  , type
911  , dom_names_map
912  )
913  );
914 
915  boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
916 
917  signals_handler.async_wait(
918  boost::bind(
920  , boost::ref(signals_handler)
921  , boost::ref(terminal_width)
922  , boost::asio::placeholders::error
923  , boost::asio::placeholders::signal_number
924  )
925  );
926 
928  io_service
929  , port
930  , buffer
931  , buffer_size
932  , consumer_set
933  );
934 
935  io_service.run();
936  }
937  }
938 }
939 
941  boost::asio::signal_set& set,
942  int& terminal_width,
943  boost::system::error_code const& error,
944  int signum
945 )
946 {
947  if (!error) {
948  if (signum == SIGINT) {
949 
950  GET_IO_SERVICE(set).stop();
951 
952  if (isatty(1)) {
953  std::cout << "\033]2;thank you for flying with CLBSwissKnife!\007";
954  std::cout << "\rBye bye!\n";
955  }
956  return;
957  } else if (signum == SIGWINCH) {
959  }
960 
961  set.async_wait(
962  boost::bind(
964  boost::ref(set),
965  boost::ref(terminal_width),
966  boost::asio::placeholders::error,
967  boost::asio::placeholders::signal_number
968  )
969  );
970  }
971 }
TString replace(const TString &target, const TRegexp &regexp, const T &replacement)
Replace regular expression in input by given replacement.
Definition: JPrintResult.cc:63
void header_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
LigierDataHandler & operator=(LigierDataHandler const &)
LigierDataHandler(LigierDataHandler const &)
void subscribe_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
boost::asio::ip::tcp::endpoint m_endpoint
void connect_handle(boost::system::error_code const &error)
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)
boost::asio::deadline_timer m_timer
void data_handle(boost::system::error_code const &error, std::size_t size)
LigierDataHandler< Consumer > this_type
std::size_t const m_buffer_size
boost::asio::ip::tcp::socket m_socket
void timeout_handle(boost::system::error_code const &error)
std::size_t m_buffer_size
boost::asio::ip::udp::socket m_socket
UdpDataHandler< Consumer > this_type
UdpDataHandler(boost::asio::io_service &service, int port, char *buffer, std::size_t buffer_size, Consumer const &consumer)
void data_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
static const unsigned int default_moni_port
int main(int argc, char *argv[])
static const unsigned int default_acou_port
int get_terminal_width()
static const size_t buffer_size
void handle_signal(boost::asio::signal_set &set, int &terminal_width, boost::system::error_code const &error, int signum)
static const unsigned int default_opto_port
#define GET_IO_SERVICE(s)
Program name: CLBSwissKnife.
boost::asio::ip::tcp::endpoint make_endpoint(std::string const &address)
static int terminal_width
Definition: daq_parser.cpp:21
unsigned int const unkn
Definition: datatypes.cpp:10
unsigned int const ttdc
Definition: datatypes.cpp:7
unsigned int const tmch
Definition: datatypes.cpp:9
unsigned int const taes
Definition: datatypes.cpp:8
dom_map_type load_dom_map(std::istream &map)
Definition: dom_map.cpp:49
const char * map
Definition: elog.cc:87
void async_commit(boost::asio::deadline_timer &timer, gui::Screen &screen, boost::system::error_code const &error)
Definition: gui.cpp:50
void async_win_resize(boost::asio::signal_set &window_resize, gui::Screen &screen, boost::system::error_code const &error, int signum)
Definition: gui.cpp:106
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)
Definition: gui.cpp:68
struct __attribute__((__packed__)) InfoWord
Definition: infoword.hh:18
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
data_type v[N+1][M+1]
Definition: JPolint.hh:866
std::size_t read_data_size(char const *const buffer)
std::size_t prepare_tag(char *buffer, std::size_t max_size, std::string const &tag)