Jpp  15.0.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 #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"
150 
152 {
153  static bool const is_a_tty = isatty(1);
154 
155  if (!is_a_tty) {
156  return 80;
157  } else {
158  struct winsize sz;
159 
160  ioctl(1, TIOCGWINSZ, &sz);
161  return sz.ws_col;
162  }
163 }
164 
165 namespace po = boost::program_options;
166 
167 // TODO: use the CLBDataGram instead of a buffer
168 
169 const static size_t buffer_size = 10000;
170 
171 const static unsigned int default_opto_port = 56015;
172 const static unsigned int default_acou_port = 56016;
173 const static unsigned int default_moni_port = 56017;
174 
175 void handle_signal(
176  boost::asio::signal_set& set,
177  int& terminal_width,
178  boost::system::error_code const& error,
179  int signum
180 );
181 
182 template<class Consumer>
184 {
186 
187  boost::asio::ip::tcp::socket m_socket;
188  boost::asio::deadline_timer m_timer;
189 
190  std::string m_tag;
191  boost::asio::ip::tcp::endpoint m_endpoint;
192 
193  char* m_buffer;
194  std::size_t const m_buffer_size;
195 
196  Consumer m_consumer;
197 
199  boost::system::error_code const& error
200  , std::size_t size
201  )
202  {
203  if (error && error != boost::asio::error::operation_aborted) {
204  m_consumer(error, 0, 0);
205  restart();
206  } else if (error == boost::asio::error::operation_aborted) {
207  } else {
208  m_consumer(error, m_buffer + 16, size);
209 
210  boost::asio::async_read(
211  m_socket
212  , boost::asio::buffer(m_buffer, 16)
213  , boost::bind(
215  , this
216  , boost::asio::placeholders::error
217  , boost::asio::placeholders::bytes_transferred
218  )
219  );
220  }
221  }
222 
223  void timeout_handle(boost::system::error_code const& error)
224  {
225  if (!error) {
226  m_socket.async_connect(
227  m_endpoint
228  , boost::bind(
230  , this
231  , boost::asio::placeholders::error
232  )
233  );
234  }
235  }
236 
237  void connect_handle(boost::system::error_code const& error)
238  {
239  if (error && error != boost::asio::error::operation_aborted) {
240  m_consumer(error, 0, 0);
241  m_timer.expires_from_now(boost::posix_time::seconds(1));
242 
243  m_timer.async_wait(
244  boost::bind(
246  , this
247  , boost::asio::placeholders::error
248  )
249  );
250  } else if (error == boost::asio::error::operation_aborted) {
251  } else {
252  std::size_t const size = ligier::prepare_tag(m_buffer, m_buffer_size, m_tag);
253 
254  boost::asio::async_write(
255  m_socket
256  , boost::asio::buffer(m_buffer, size)
257  , boost::bind(
259  , this
260  , boost::asio::placeholders::error
261  , boost::asio::placeholders::bytes_transferred
262  )
263  );
264  }
265  }
266 
268  boost::system::error_code const& error
269  , std::size_t bytes_transferred
270  ) {
271  if (error && error != boost::asio::error::operation_aborted) {
272  m_consumer(error, 0, 0);
273  restart();
274  } else if (error == boost::asio::error::operation_aborted) {
275  } else {
276  boost::asio::async_read(
277  m_socket
278  , boost::asio::buffer(m_buffer, 16)
279  , boost::bind(
281  , this
282  , boost::asio::placeholders::error
283  , boost::asio::placeholders::bytes_transferred
284  )
285  );
286  }
287  }
288 
290  boost::system::error_code const& error
291  , std::size_t bytes_transferred
292  ) {
293  if (error && error != boost::asio::error::operation_aborted) {
294  m_consumer(error, 0, 0);
295  restart();
296  } else if (error == boost::asio::error::operation_aborted) {
297  } else {
298  std::size_t const size = ligier::read_data_size(m_buffer);
299 
300  boost::asio::async_read(
301  m_socket
302  , boost::asio::buffer(m_buffer + 16, size)
303  , boost::bind(
305  , this
306  , boost::asio::placeholders::error
307  , boost::asio::placeholders::bytes_transferred
308  )
309  );
310  }
311  }
312 
313  void restart()
314  {
315  boost::system::error_code ec;
316 
317  m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
318  m_socket.close(ec);
319 
320  m_socket.async_connect(
321  m_endpoint
322  , boost::bind(
324  , this
325  , boost::asio::placeholders::error
326  )
327  );
328  }
329 
330  LigierDataHandler(LigierDataHandler const&); // non-copyable
331  LigierDataHandler& operator =(LigierDataHandler const&); // non-copyable
332 
333  public:
334 
336  boost::asio::io_service& service
337  , std::string const& tag
338  , boost::asio::ip::tcp::endpoint const& endpoint
339  , char* buffer
340  , std::size_t buffer_size
341  , Consumer const& consumer
342  ) : m_socket(service)
343  , m_timer(service)
344  , m_tag(tag)
345  , m_endpoint(endpoint)
346  , m_buffer(buffer)
347  , m_buffer_size(buffer_size)
348  , m_consumer(consumer)
349  {
350  m_socket.async_connect(
351  m_endpoint
352  , boost::bind(
354  , this
355  , boost::asio::placeholders::error
356  )
357  );
358  }
359 };
360 
361 template<class Consumer>
363 {
365 
366  boost::asio::ip::udp::socket m_socket;
367  char* m_buffer;
368  std::size_t m_buffer_size;
369  Consumer m_consumer;
370 
372  boost::system::error_code const& error
373  , std::size_t bytes_transferred
374  ) {
375  if (error) {
376  m_consumer(error, 0, 0);
377  } else {
378  m_consumer(error, m_buffer, bytes_transferred);
379  }
380 
381  m_socket.async_receive(
382  boost::asio::buffer(m_buffer, m_buffer_size)
383  , boost::bind(
385  , this
386  , boost::asio::placeholders::error
387  , boost::asio::placeholders::bytes_transferred
388  )
389  );
390  }
391 
392  public:
393 
395  boost::asio::io_service& service
396  , int port
397  , char* buffer
398  , std::size_t buffer_size
399  , Consumer const& consumer
400  ) : m_socket(
401  service
402  , boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)
403  )
404  , m_buffer(buffer)
405  , m_buffer_size(buffer_size)
406  , m_consumer(consumer)
407  {
408  boost::asio::ip::udp::socket::receive_buffer_size option(33554432);
409  m_socket.set_option(option);
410 
411  m_socket.async_receive(
412  boost::asio::buffer(m_buffer, m_buffer_size)
413  , boost::bind(
415  , this
416  , boost::asio::placeholders::error
417  , boost::asio::placeholders::bytes_transferred
418  )
419  );
420  }
421 };
422 
423 inline
424 boost::asio::ip::tcp::endpoint make_endpoint(
425  std::string const& address
426 ) {
427  boost::asio::io_service service;
428  boost::asio::ip::tcp::resolver resolver(service);
429 
430  std::string::size_type const pos = address.find(":");
431 
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);
434 
435  boost::asio::ip::tcp::resolver::query query(
436  boost::asio::ip::tcp::v4()
437  , host
438  , port
439  );
440 
441  return *resolver.resolve(query);
442 }
443 
444 int main(int argc, char* argv[])
445 {
446  bool dump = false;
447  uint32_t type = unkn;
448  bool uses_roy = false;
449  bool use_gui = false;
450  bool lm_mode = false;
451 
452  std::string dom_names = std::getenv("HOME") + std::string("/.doms.csk");
453  dom_map_type dom_names_map;
454 
455  std::ofstream output_file;
456 
457  unsigned int port = 0;
458 
459  std::string filename;
460  std::string roy_setup;
461 
462  std::string lserver = "localhost:5553";
463  std::string tag;
464  boost::asio::ip::tcp::endpoint endpoint;
465 
466  po::options_description desc("Generic options");
467  desc.add_options()
468  ("help,h", "Print this help and exit.")
469  ("version,v", "Print the version and exit.")
470  (
471  "map"
472  , po::value<std::string>(&dom_names)->value_name("filename")
473  , "File that specifies a conversion from DOM IDs to a human readable name."
474  )
475 #ifdef CURSES_FOUND
476  ("gui,g", "Use GUI (avalilable in UDP-monitoring and Ligier modes only).")
477 #endif
478  ("ligier,l", "Set Ligier mode.")
479  ("udp,u", "Force UDP mode (default).");
480 
481  po::options_description lmdesc("Ligier-mode options");
482  lmdesc.add_options()
483  (
484  "server,s"
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."
489  )
490  (
491  "tag,t"
492  , po::value<std::string>(&tag)
493  ->default_value("IO_MONIT")
494  ->value_name("tag")
495  , "Set the Ligier tag to read data from."
496  );
497 
498  po::options_description umdesc("UDP-mode options");
499  umdesc.add_options()
500  ("optical,o",
501  po::value<unsigned int>(&port)
502  ->implicit_value(default_opto_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).")
506  ("acoustic,a",
507  po::value<unsigned int>(&port)
508  ->implicit_value(default_acou_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).")
512  ("monitoring,m",
513  po::value<unsigned int>(&port)
514  ->implicit_value(default_moni_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).")
518  ("port,p",
519  po::value<unsigned int>(&port)->value_name("port"),
520  "Listen on the specified port, automatically determining the \
521 data type.")
522  ("dumpfile,f",
523  po::value<std::string>(&filename)->value_name("filename"),
524  "Dumps the acquired data to a file.")
525  ("royweb,r",
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.");
534 
535  std::string templ;
536  std::string roy_server;
537  int roy_port = 0;
538 
539  try {
540  po::options_description global;
541  global.add(desc).add(lmdesc).add(umdesc);
542 
543  po::variables_map vm;
544  po::store(
545  po::command_line_parser(argc, argv).options(global).run()
546  , vm
547  );
548 
549  if (vm.count("help")) {
550  std::cout
551  << desc << '\n'
552  << umdesc << '\n'
553  << lmdesc << '\n';
554  return EXIT_SUCCESS;
555  }
556 
557  if (vm.count("version")) {
558  std::cout << clbsk::version::v() << std::endl;
559  return EXIT_SUCCESS;
560  }
561 
562  po::notify(vm);
563 
564 #ifdef CURSES_FOUND
565  use_gui = vm.count("gui");
566 #endif
567 
568  lm_mode = vm.count("ligier");
569 
570  if (lm_mode && vm.count("udp")) {
571  throw std::runtime_error("You can specify only one mode. Both provided.");
572  }
573 
574  if (vm.count("map")) {
575  std::ifstream map(dom_names.c_str());
576 
577  if (! map) {
578  throw std::runtime_error(
579  std::string("Error reading map file: ")
580  + std::strerror(errno)
581  );
582  }
583 
584  dom_names_map = load_dom_map(map);
585  } else {
586  std::ifstream map(dom_names.c_str());
587 
588  dom_names_map = load_dom_map(map);
589  }
590 
591  if (lm_mode) {
592  po::variables_map vm;
593  po::options_description options;
594  options.add(lmdesc).add(desc);
595 
596  po::store(
597  po::command_line_parser(argc, argv).options(options).run()
598  , vm
599  );
600 
601  po::notify(vm);
602 
603  endpoint = make_endpoint(lserver);
604 
605  type = tmch;
606  } else {
607  po::variables_map vm;
608  po::options_description options;
609  options.add(desc).add(umdesc);
610 
611  po::store(
612  po::command_line_parser(argc, argv).options(options).run()
613  , vm
614  );
615 
616  po::notify(vm);
617 
618  unsigned int counter = 0;
619  if (vm.count("port")) {
620  type = unkn;
621  ++counter;
622  }
623  if (vm.count("optical")) {
624  type = ttdc;
625  ++counter;
626  }
627  if (vm.count("acoustic")) {
628  type = taes;
629  ++counter;
630  }
631  if (vm.count("monitoring")) {
632  type = tmch;
633  ++counter;
634  }
635 
636  if (counter != 1) {
637  if (counter) {
638  throw std::runtime_error("More than one port provided.");
639  } else {
640  throw std::runtime_error("You must specify at least one port.");
641  }
642  }
643 
644  if (use_gui && type != tmch) {
645  throw std::runtime_error("GUI is only available in monitoring mode");
646  }
647 
648  if (vm.count("royweb")) {
649  if (type != tmch) {
650  throw std::runtime_error("you can use ROyWeb only with the"
651  " monitoring channel");
652  }
653 
654  uses_roy = true;
655  std::replace(roy_setup.begin(), roy_setup.end(), ':', ' ');
656  std::istringstream ss(roy_setup);
657  int param_count = 0;
658  if (ss >> templ) {
659  ++param_count;
660  }
661  if (ss >> roy_server) {
662  ++param_count;
663  }
664  if (ss >> roy_port) {
665  ++param_count;
666  }
667 
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.");
671  }
672  }
673 
674  if (vm.count("dumpfile")) {
675  output_file.open(filename.c_str(), std::ios::binary);
676  if (! output_file) {
677  throw std::runtime_error(
678  "Unable to open file "
679  + filename
680  + " for writing: "
681  + strerror(errno)
682  );
683  }
684  dump = true;
685  }
686  }
687  } catch (const po::error& e) {
688  std::cerr
689  << "CLBSwissKnife: Error: " << e.what() << '\n'
690  << desc << '\n'
691  << umdesc << '\n'
692  << lmdesc << '\n';
693 
694  return EXIT_FAILURE;
695  } catch (const std::runtime_error& e) {
696  std::cerr << "CLBSwissKnife: Error: " << e.what() << std::endl;
697  return EXIT_FAILURE;
698  }
699 
700  boost::asio::io_service io_service;
701  char buffer[buffer_size] __attribute__((aligned(8)));
702 
703  // Initialise the terminal width
705 
706  if (lm_mode) { // Ligier
707  if (use_gui) { // Ligier-GUI
708  #ifdef CURSES_FOUND
709  ChList stats;
710 
711  boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
712 
713  boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
714 
715  boost::asio::signal_set window_resize(io_service, SIGWINCH);
716 
717  char key = 0;
718  gui::ScreenInitialiser init;
719 
720  gui::Screen screen(io_service, lserver, stats);
721 
722  keyb.async_read_some(
723  boost::asio::buffer(&key, sizeof(key)),
724  boost::bind(
725  async_cin,
726  boost::ref(keyb),
727  boost::ref(key),
728  boost::ref(screen),
729  boost::asio::placeholders::error,
730  boost::asio::placeholders::bytes_transferred
731  )
732  );
733 
734  timer.async_wait(
735  boost::bind(
736  async_commit,
737  boost::ref(timer),
738  boost::ref(screen),
739  boost::asio::placeholders::error
740  )
741  );
742 
744  io_service
745  , tag
746  , endpoint
747  , buffer
748  , buffer_size
749  , clbsk::consumer::Gui(terminal_width, dom_names_map, stats, screen)
750  );
751 
752  window_resize.async_wait(
753  boost::bind(
755  boost::ref(window_resize),
756  boost::ref(screen),
757  boost::asio::placeholders::error,
758  boost::asio::placeholders::signal_number
759  )
760  );
761 
762  io_service.run();
763  #endif
764  } else { // Ligier-Scrollback
765  std::cout << "Listening from: " << endpoint << ':' << tag << '\n';
766  boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
767 
768  signals_handler.async_wait(
769  boost::bind(
771  boost::ref(signals_handler),
772  boost::ref(terminal_width),
773  boost::asio::placeholders::error,
774  boost::asio::placeholders::signal_number
775  )
776  );
777 
779  io_service
780  , tag
781  , endpoint
782  , buffer
783  , buffer_size
784  , clbsk::consumer::Scrollback(terminal_width, tmch, dom_names_map)
785  );
786 
787  io_service.run();
788  }
789  } else { // UDP
790  std::cout << "Listening port: " << port << '\n' << "Data type: ";
791 
792  if (type == taes) {
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";
798  } else {
799  std::cout << "Automatically determined\n";
800  }
801 
802  clbsk::consumer::ConsumerSet consumer_set;
803 
804  trm::MonStreamer ms(roy_server, roy_port);
805 
806  if (uses_roy) {
807  std::cout
808  << "Using ROyWeb ("
809  << roy_server
810  << ", "
811  << roy_port
812  << ") with tag format "
813  << templ << std::endl;
814 
815  consumer_set.add(
816  clbsk::consumer::Roy(
817  dom_names_map
818  , templ
819  , ms
820  )
821  );
822  }
823 
824  if (dump) {
825  consumer_set.add(clbsk::consumer::File(output_file));
826  }
827 
828  if (use_gui) { // UDP-GUI
829  #ifdef CURSES_FOUND
830  ChList stats;
831 
832  boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
833 
834  boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
835 
836  boost::asio::signal_set window_resize(io_service, SIGWINCH);
837 
838  char key = 0;
839  gui::ScreenInitialiser init;
840 
841  std::string const heading
842  = "UDP " + boost::lexical_cast<std::string>(port);
843 
844  gui::Screen screen(io_service, heading, stats);
845 
846  keyb.async_read_some(
847  boost::asio::buffer(&key, sizeof(key)),
848  boost::bind(
849  async_cin,
850  boost::ref(keyb),
851  boost::ref(key),
852  boost::ref(screen),
853  boost::asio::placeholders::error,
854  boost::asio::placeholders::bytes_transferred
855  )
856  );
857 
858  timer.async_wait(
859  boost::bind(
860  async_commit,
861  boost::ref(timer),
862  boost::ref(screen),
863  boost::asio::placeholders::error
864  )
865  );
866 
867  window_resize.async_wait(
868  boost::bind(
870  boost::ref(window_resize),
871  boost::ref(screen),
872  boost::asio::placeholders::error,
873  boost::asio::placeholders::signal_number
874  )
875  );
876 
877  consumer_set.add(
878  clbsk::consumer::Gui(
879  terminal_width
880  , dom_names_map
881  , stats
882  , screen
883  )
884  );
885 
887  io_service
888  , port
889  , buffer
890  , buffer_size
891  , consumer_set
892  );
893 
894  io_service.run();
895  #endif
896  } else { // UDP-Scrollback
897  consumer_set.add(
898  clbsk::consumer::Scrollback(
899  terminal_width
900  , type
901  , dom_names_map
902  )
903  );
904 
905  boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
906 
907  signals_handler.async_wait(
908  boost::bind(
910  , boost::ref(signals_handler)
911  , boost::ref(terminal_width)
912  , boost::asio::placeholders::error
913  , boost::asio::placeholders::signal_number
914  )
915  );
916 
918  io_service
919  , port
920  , buffer
921  , buffer_size
922  , consumer_set
923  );
924 
925  io_service.run();
926  }
927  }
928 }
929 
931  boost::asio::signal_set& set,
932  int& terminal_width,
933  boost::system::error_code const& error,
934  int signum
935 )
936 {
937  if (!error) {
938  if (signum == SIGINT) {
939  set.get_io_service().stop();
940  if (isatty(1)) {
941  std::cout << "\033]2;thank you for flying with CLBSwissKnife!\007";
942  std::cout << "\rBye bye!\n";
943  }
944  return;
945  } else if (signum == SIGWINCH) {
946  terminal_width = get_terminal_width();
947  }
948 
949  set.async_wait(
950  boost::bind(
952  boost::ref(set),
953  boost::ref(terminal_width),
954  boost::asio::placeholders::error,
955  boost::asio::placeholders::signal_number
956  )
957  );
958  }
959 }
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()
Program name: CLBSwissKnife.
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:740
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