Jpp  17.1.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
337  LigierDataHandler& operator =(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)
353  , m_buffer_size(buffer_size)
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)
411  , m_buffer_size(buffer_size)
412  , m_consumer(consumer)
413  {
414  boost::asio::ip::udp::socket::receive_buffer_size option(33554432);
415  m_socket.set_option(option);
416 
417  m_socket.async_receive(
418  boost::asio::buffer(m_buffer, m_buffer_size)
419  , boost::bind(
421  , this
422  , boost::asio::placeholders::error
423  , boost::asio::placeholders::bytes_transferred
424  )
425  );
426  }
427 };
428 
429 inline
430 boost::asio::ip::tcp::endpoint make_endpoint(
431  std::string const& address
432 ) {
433  boost::asio::io_service service;
434  boost::asio::ip::tcp::resolver resolver(service);
435 
436  std::string::size_type const pos = address.find(":");
437 
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);
440 
441  boost::asio::ip::tcp::resolver::query query(
442  boost::asio::ip::tcp::v4()
443  , host
444  , port
445  );
446 
447  return *resolver.resolve(query);
448 }
449 
450 int main(int argc, char* argv[])
451 {
452  bool dump = false;
453  uint32_t type = unkn;
454  bool uses_roy = false;
455  bool use_gui = false;
456  bool lm_mode = false;
457 
458  std::string dom_names = std::getenv("HOME") + std::string("/.doms.csk");
459  dom_map_type dom_names_map;
460 
461  std::ofstream output_file;
462 
463  unsigned int port = 0;
464 
465  std::string filename;
466  std::string roy_setup;
467 
468  std::string lserver = "localhost:5553";
469  std::string tag;
470  boost::asio::ip::tcp::endpoint endpoint;
471 
472  po::options_description desc("Generic options");
473  desc.add_options()
474  ("help,h", "Print this help and exit.")
475  ("version,v", "Print the version and exit.")
476  (
477  "map"
478  , po::value<std::string>(&dom_names)->value_name("filename")
479  , "File that specifies a conversion from DOM IDs to a human readable name."
480  )
481 #ifdef CURSES_FOUND
482  ("gui,g", "Use GUI (avalilable in UDP-monitoring and Ligier modes only).")
483 #endif
484  ("ligier,l", "Set Ligier mode.")
485  ("udp,u", "Force UDP mode (default).");
486 
487  po::options_description lmdesc("Ligier-mode options");
488  lmdesc.add_options()
489  (
490  "server,s"
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."
495  )
496  (
497  "tag,t"
498  , po::value<std::string>(&tag)
499  ->default_value("IO_MONIT")
500  ->value_name("tag")
501  , "Set the Ligier tag to read data from."
502  );
503 
504  po::options_description umdesc("UDP-mode options");
505  umdesc.add_options()
506  ("optical,o",
507  po::value<unsigned int>(&port)
508  ->implicit_value(default_opto_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).")
512  ("acoustic,a",
513  po::value<unsigned int>(&port)
514  ->implicit_value(default_acou_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).")
518  ("monitoring,m",
519  po::value<unsigned int>(&port)
520  ->implicit_value(default_moni_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).")
524  ("port,p",
525  po::value<unsigned int>(&port)->value_name("port"),
526  "Listen on the specified port, automatically determining the \
527 data type.")
528  ("dumpfile,f",
529  po::value<std::string>(&filename)->value_name("filename"),
530  "Dumps the acquired data to a file.")
531  ("royweb,r",
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.");
540 
541  std::string templ;
542  std::string roy_server;
543  int roy_port = 0;
544 
545  try {
546  po::options_description global;
547  global.add(desc).add(lmdesc).add(umdesc);
548 
549  po::variables_map vm;
550  po::store(
551  po::command_line_parser(argc, argv).options(global).run()
552  , vm
553  );
554 
555  if (vm.count("help")) {
556  std::cout
557  << desc << '\n'
558  << umdesc << '\n'
559  << lmdesc << '\n';
560  return EXIT_SUCCESS;
561  }
562 
563  if (vm.count("version")) {
564  std::cout << clbsk::version::v() << std::endl;
565  return EXIT_SUCCESS;
566  }
567 
568  po::notify(vm);
569 
570 #ifdef CURSES_FOUND
571  use_gui = vm.count("gui");
572 #endif
573 
574  lm_mode = vm.count("ligier");
575 
576  if (lm_mode && vm.count("udp")) {
577  throw std::runtime_error("You can specify only one mode. Both provided.");
578  }
579 
580  if (vm.count("map")) {
581  std::ifstream map(dom_names.c_str());
582 
583  if (! map) {
584  throw std::runtime_error(
585  std::string("Error reading map file: ")
586  + std::strerror(errno)
587  );
588  }
589 
590  dom_names_map = load_dom_map(map);
591  } else {
592  std::ifstream map(dom_names.c_str());
593 
594  dom_names_map = load_dom_map(map);
595  }
596 
597  if (lm_mode) {
598  po::variables_map vm;
599  po::options_description options;
600  options.add(lmdesc).add(desc);
601 
602  po::store(
603  po::command_line_parser(argc, argv).options(options).run()
604  , vm
605  );
606 
607  po::notify(vm);
608 
609  endpoint = make_endpoint(lserver);
610 
611  type = tmch;
612  } else {
613  po::variables_map vm;
614  po::options_description options;
615  options.add(desc).add(umdesc);
616 
617  po::store(
618  po::command_line_parser(argc, argv).options(options).run()
619  , vm
620  );
621 
622  po::notify(vm);
623 
624  unsigned int counter = 0;
625  if (vm.count("port")) {
626  type = unkn;
627  ++counter;
628  }
629  if (vm.count("optical")) {
630  type = ttdc;
631  ++counter;
632  }
633  if (vm.count("acoustic")) {
634  type = taes;
635  ++counter;
636  }
637  if (vm.count("monitoring")) {
638  type = tmch;
639  ++counter;
640  }
641 
642  if (counter != 1) {
643  if (counter) {
644  throw std::runtime_error("More than one port provided.");
645  } else {
646  throw std::runtime_error("You must specify at least one port.");
647  }
648  }
649 
650  if (use_gui && type != tmch) {
651  throw std::runtime_error("GUI is only available in monitoring mode");
652  }
653 
654  if (vm.count("royweb")) {
655  if (type != tmch) {
656  throw std::runtime_error("you can use ROyWeb only with the"
657  " monitoring channel");
658  }
659 
660  uses_roy = true;
661  std::replace(roy_setup.begin(), roy_setup.end(), ':', ' ');
662  std::istringstream ss(roy_setup);
663  int param_count = 0;
664  if (ss >> templ) {
665  ++param_count;
666  }
667  if (ss >> roy_server) {
668  ++param_count;
669  }
670  if (ss >> roy_port) {
671  ++param_count;
672  }
673 
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.");
677  }
678  }
679 
680  if (vm.count("dumpfile")) {
681  output_file.open(filename.c_str(), std::ios::binary);
682  if (! output_file) {
683  throw std::runtime_error(
684  "Unable to open file "
685  + filename
686  + " for writing: "
687  + strerror(errno)
688  );
689  }
690  dump = true;
691  }
692  }
693  } catch (const po::error& e) {
694  std::cerr
695  << "CLBSwissKnife: Error: " << e.what() << '\n'
696  << desc << '\n'
697  << umdesc << '\n'
698  << lmdesc << '\n';
699 
700  return EXIT_FAILURE;
701  } catch (const std::runtime_error& e) {
702  std::cerr << "CLBSwissKnife: Error: " << e.what() << std::endl;
703  return EXIT_FAILURE;
704  }
705 
706  boost::asio::io_service io_service;
707  char buffer[buffer_size] __attribute__((aligned(8)));
708 
709  // Initialise the terminal width
711 
712  if (lm_mode) { // Ligier
713  if (use_gui) { // Ligier-GUI
714  #ifdef CURSES_FOUND
715  ChList stats;
716 
717  boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
718 
719  boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
720 
721  boost::asio::signal_set window_resize(io_service, SIGWINCH);
722 
723  char key = 0;
724  gui::ScreenInitialiser init;
725 
726  gui::Screen screen(io_service, lserver, stats);
727 
728  keyb.async_read_some(
729  boost::asio::buffer(&key, sizeof(key)),
730  boost::bind(
731  async_cin,
732  boost::ref(keyb),
733  boost::ref(key),
734  boost::ref(screen),
735  boost::asio::placeholders::error,
736  boost::asio::placeholders::bytes_transferred
737  )
738  );
739 
740  timer.async_wait(
741  boost::bind(
742  async_commit,
743  boost::ref(timer),
744  boost::ref(screen),
745  boost::asio::placeholders::error
746  )
747  );
748 
750  io_service
751  , tag
752  , endpoint
753  , buffer
754  , buffer_size
755  , clbsk::consumer::Gui(terminal_width, dom_names_map, stats, screen)
756  );
757 
758  window_resize.async_wait(
759  boost::bind(
761  boost::ref(window_resize),
762  boost::ref(screen),
763  boost::asio::placeholders::error,
764  boost::asio::placeholders::signal_number
765  )
766  );
767 
768  io_service.run();
769  #endif
770  } else { // Ligier-Scrollback
771  std::cout << "Listening from: " << endpoint << ':' << tag << '\n';
772  boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
773 
774  signals_handler.async_wait(
775  boost::bind(
777  boost::ref(signals_handler),
778  boost::ref(terminal_width),
779  boost::asio::placeholders::error,
780  boost::asio::placeholders::signal_number
781  )
782  );
783 
785  io_service
786  , tag
787  , endpoint
788  , buffer
789  , buffer_size
790  , clbsk::consumer::Scrollback(terminal_width, tmch, dom_names_map)
791  );
792 
793  io_service.run();
794  }
795  } else { // UDP
796  std::cout << "Listening port: " << port << '\n' << "Data type: ";
797 
798  if (type == taes) {
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";
804  } else {
805  std::cout << "Automatically determined\n";
806  }
807 
808  clbsk::consumer::ConsumerSet consumer_set;
809 
810  trm::MonStreamer ms(roy_server, roy_port);
811 
812  if (uses_roy) {
813  std::cout
814  << "Using ROyWeb ("
815  << roy_server
816  << ", "
817  << roy_port
818  << ") with tag format "
819  << templ << std::endl;
820 
821  consumer_set.add(
822  clbsk::consumer::Roy(
823  dom_names_map
824  , templ
825  , ms
826  )
827  );
828  }
829 
830  if (dump) {
831  consumer_set.add(clbsk::consumer::File(output_file));
832  }
833 
834  if (use_gui) { // UDP-GUI
835  #ifdef CURSES_FOUND
836  ChList stats;
837 
838  boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
839 
840  boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
841 
842  boost::asio::signal_set window_resize(io_service, SIGWINCH);
843 
844  char key = 0;
845  gui::ScreenInitialiser init;
846 
847  std::string const heading
848  = "UDP " + boost::lexical_cast<std::string>(port);
849 
850  gui::Screen screen(io_service, heading, stats);
851 
852  keyb.async_read_some(
853  boost::asio::buffer(&key, sizeof(key)),
854  boost::bind(
855  async_cin,
856  boost::ref(keyb),
857  boost::ref(key),
858  boost::ref(screen),
859  boost::asio::placeholders::error,
860  boost::asio::placeholders::bytes_transferred
861  )
862  );
863 
864  timer.async_wait(
865  boost::bind(
866  async_commit,
867  boost::ref(timer),
868  boost::ref(screen),
869  boost::asio::placeholders::error
870  )
871  );
872 
873  window_resize.async_wait(
874  boost::bind(
876  boost::ref(window_resize),
877  boost::ref(screen),
878  boost::asio::placeholders::error,
879  boost::asio::placeholders::signal_number
880  )
881  );
882 
883  consumer_set.add(
884  clbsk::consumer::Gui(
885  terminal_width
886  , dom_names_map
887  , stats
888  , screen
889  )
890  );
891 
893  io_service
894  , port
895  , buffer
896  , buffer_size
897  , consumer_set
898  );
899 
900  io_service.run();
901  #endif
902  } else { // UDP-Scrollback
903  consumer_set.add(
904  clbsk::consumer::Scrollback(
905  terminal_width
906  , type
907  , dom_names_map
908  )
909  );
910 
911  boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
912 
913  signals_handler.async_wait(
914  boost::bind(
916  , boost::ref(signals_handler)
917  , boost::ref(terminal_width)
918  , boost::asio::placeholders::error
919  , boost::asio::placeholders::signal_number
920  )
921  );
922 
924  io_service
925  , port
926  , buffer
927  , buffer_size
928  , consumer_set
929  );
930 
931  io_service.run();
932  }
933  }
934 }
935 
937  boost::asio::signal_set& set,
938  int& terminal_width,
939  boost::system::error_code const& error,
940  int signum
941 )
942 {
943  if (!error) {
944  if (signum == SIGINT) {
945 
946  GET_IO_SERVICE(set).stop();
947 
948  if (isatty(1)) {
949  std::cout << "\033]2;thank you for flying with CLBSwissKnife!\007";
950  std::cout << "\rBye bye!\n";
951  }
952  return;
953  } else if (signum == SIGWINCH) {
954  terminal_width = get_terminal_width();
955  }
956 
957  set.async_wait(
958  boost::bind(
960  boost::ref(set),
961  boost::ref(terminal_width),
962  boost::asio::placeholders::error,
963  boost::asio::placeholders::signal_number
964  )
965  );
966  }
967 }
static int terminal_width
Definition: daq_parser.cpp:21
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
Definition: infoword.hh:18
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
int main(int argc, char *argv[])
Definition: Main.cc:15
TString replace(const TString &target, const TRegexp &regexp, const T &replacement)
Replace regular expression in input by given replacement.
Definition: JPrintResult.cc:63
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)
unsigned int const tmch
Definition: datatypes.cpp:9
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.
unsigned int const ttdc
Definition: datatypes.cpp:7
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()
boost::asio::deadline_timer m_timer
boost::asio::ip::tcp::endpoint make_endpoint(const std::string &address)
unsigned int const taes
Definition: datatypes.cpp:8
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
std::size_t read_data_size(char const *const buffer)
unsigned int const unkn
Definition: datatypes.cpp:10
void async_commit(boost::asio::deadline_timer &timer, gui::Screen &screen, boost::system::error_code const &error)
Definition: gui.cpp:50
dom_map_type load_dom_map(std::istream &map)
Definition: dom_map.cpp:49
const char * map
Definition: elog.cc:87
data_type v[N+1][M+1]
Definition: JPolint.hh:756
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