Jpp test-rotations-new
the software that should make you happy
Loading...
Searching...
No Matches
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
171namespace po = boost::program_options;
172
173// TODO: use the CLBDataGram instead of a buffer
174
175const static size_t buffer_size = 10000;
176
177const static unsigned int default_opto_port = 56015;
178const static unsigned int default_acou_port = 56016;
179const static unsigned int default_moni_port = 56017;
180
181void handle_signal(
182 boost::asio::signal_set& set,
183 int& terminal_width,
184 boost::system::error_code const& error,
185 int signum
186);
187
188template<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(
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(
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(
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(
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(
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(
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(
358 , boost::bind(
360 , this
361 , boost::asio::placeholders::error
362 )
363 );
364 }
365};
366
367template<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
433inline
434boost::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
454int 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 \
515provided 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 \
521provided 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 \
527not 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 \
531data 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 \
540server. The syntax is format:server_ip:server_port. \
541The format parameter can contain the following placeholders: %d for \
542DOM ID, %n for DOM name (if available, otherwise the DOM ID is used) \
543and %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(
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
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
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(
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
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
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}
void header_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
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
LigierDataHandler & operator=(LigierDataHandler const &)
LigierDataHandler< Consumer > this_type
void data_handle(boost::system::error_code const &error, std::size_t size)
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
UdpDataHandler< Consumer > this_type
boost::asio::ip::udp::socket m_socket
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
unsigned int const unkn
Definition datatypes.cpp:10
static const unsigned int taes
static const unsigned int ttdc
static const unsigned int tmch
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
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)