Jpp test-rotations-new
the software that should make you happy
Loading...
Searching...
No Matches
JDAQClient.hh
Go to the documentation of this file.
1#ifndef __JRUNCONTROL__JDAQCLIENT__
2#define __JRUNCONTROL__JDAQCLIENT__
3
4#include <string>
5#include <iostream>
6#include <sstream>
7#include <iomanip>
8#include <exception>
9#include <typeinfo>
10#include <ctype.h>
11
12#include "JSystem/JNetwork.hh"
13#include "JNet/JControlHost.hh"
15#include "JNet/JSelectReader.hh"
16#include "JLang/Jpp.hh"
19#include "JLang/JTimeval.hh"
21#include "JLang/JNullStream.hh"
22#include "Jeep/JParser.hh"
23#include "Jeep/JProperties.hh"
24#include "Jeep/JArgs.hh"
25#include "Jeep/JTimekeeper.hh"
30#include "JDAQ/JDAQTags.hh"
35
36
37/**
38 * \author mdejong
39 */
40
41namespace KM3NETDAQ {
42
43 using namespace JLOGGER;
44 using JNET::JTag;
52 using JLANG::JTimeval;
54 using JEEP::JArgs;
56
57
58 /**
59 * Auxiliary data structure for DAQ client data.
60 */
61 struct JDAQClient_t {
62
63 static const int TIMEOUT_S = 1; //!< time out of update [s]
64
65
66 /**
67 * Constructor.
68 *
69 * \param chsm state machine
70 */
72 {
73 using namespace std;
74 using namespace JPP;
75
79
80 for (JTag buffer[] = { RC_CMD, unique_tag, DISPTAG_UNDEFINED }, *tag = buffer; *tag != DISPTAG_UNDEFINED; ++tag) {
81
82 eventTable.insert(*tag, chsm->ev_init);
83 eventTable.insert(*tag, chsm->ev_configure);
84 eventTable.insert(*tag, chsm->ev_start);
85 eventTable.insert(*tag, chsm->ev_pause);
86 eventTable.insert(*tag, chsm->ev_continue);
87 eventTable.insert(*tag, chsm->ev_stop);
88 eventTable.insert(*tag, chsm->ev_reset);
89 eventTable.insert(*tag, chsm->ev_quit);
90 eventTable.insert(*tag, chsm->ev_off);
91
92 eventTable.insert(*tag, chsm->ev_check);
93 eventTable.insert(*tag, chsm->ev_input);
94
95 eventTable.insert(*tag, chsm->ev_recover);
96 }
97
99
100 setClockInterval(TIMEOUT_S * 1000000LL);
101 }
102
103
104 /**
105 * Get hostname.
106 *
107 * \return host name
108 */
109 const std::string& getHostname() const
110 {
111 return hostname;
112 }
113
114
115 /**
116 * Get full name of this run control client.
117 *
118 * \return full name
119 */
120 const std::string& getFullName() const
121 {
122 return fullname;
123 }
124
125
126 /**
127 * Get unique tag of this run control client.
128 *
129 * \return unique tag
130 */
131 const JTag& getUniqueTag() const
132 {
133 return unique_tag;
134 }
135
136
137 /**
138 * Get total delay time.
139 *
140 * \return delay time [us]
141 */
142 long long int getClockDelay() const
143 {
144 return clock.getDelay();
145 }
146
147
148
149 /**
150 * Get interval time.
151 *
152 * \return interval time [us]
153 */
154 long long int getClockInterval() const
155 {
156 return clock.getInterval();
157 }
158
159
160 /**
161 * Set interval time.
162 *
163 * \param interval_us interval time [us]
164 */
165 void setClockInterval(const long long int interval_us)
166 {
167 clock.setInterval(interval_us);
168 }
169
170
171 /**
172 * Reset clock.
173 */
175 {
176 clock.reset();
177 }
178
179
180 /**
181 * Get last event information.
182 *
183 * \return event information
184 */
185 const std::string& getEventInfo() const
186 {
187 return event_info;
188 }
189
190
191 /**
192 * Set last event information.
193 *
194 * \param info event information
195 */
196 void setEventInfo(const std::string& info)
197 {
198 this->event_info = info;
199 }
200
201
202 protected:
203 JEventTable eventTable; //!< event table
204 std::string hostname;
205 std::string fullname;
207 JTimekeeper clock; //!< central clock
208 std::string event_info; //!< event information
209 };
210
211
212 /**
213 * Control unit client base class.
214 *
215 * This base class implements the protocol for the communication with the control unit.\n
216 * This protocol is based on ControlHost tags and CHSM event names.\n
217 * Normally, the primary input is provided to the constructor of this base class,
218 * e.g.\ via command line options of the application based on a derived class hereof.\n
219 * By calling the default method enter(),
220 * - the internal parameters will be configured; and
221 * - the client's state machine entered.
222 *
223 * The method run() can then be used to process command messages which will acoordingly update the state machine.\n
224 * For each state transition, a corresponding action method is called
225 * which could be re-implemented in the derived class (see JDAQCHSM).\n
226 * Optionally, a designated action method is repeatedly called in state <tt>Running</tt>.
227 *
228 * A state transition is triggered by a valid command message.\n
229 * The command message consists of a tag and some contents.\n
230 * The tag can be used to address all processes, a group of processes or an individual process.\n
231 * The contents of a command message must start with the name on the event and
232 * can contain additional data (separated by KM3NETDAQ::TOKEN_DELIMETER).\n
233 * A successful transition is certified by a reply message which is sent upon entering the targeted state.\n
234 * The reply message has tag "RC_REPLY" and the contents include the names of the original event as well as that of the final state.\n
235 * Optionally, information can be added to an event (separated by KM3NETDAQ::EVENTNAME_DELIMETER).\n
236 * This information is included in the following reply messages,
237 * until there is a command message with (other) information.
238 *
239 * Following a request for a state transition via a command message,
240 * four scenarios should be anticipated, namely:
241 *
242 * -# the process successfully completed the transition,
243 * a corresponding reply message is then send back;
244 * -# the process couldn't make the transition and goes to error state,
245 * a corresponding reply message is then send back,
246 * -# the process crashed,
247 * the process disappears from the process list and
248 * the server broadcasts a corresponding died message;
249 * -# the process takes longer than foreseen, leading to a timeout.
250 *
251 * The followup action after a timeout should be customised.\n
252 * In case of an invalid command message (e.g.\ request for a state transition that does not exist), no reply message will be sent.\n
253 * Instead, a message with tag "RC_FAIL" is sent.
254 *
255 * The default list of tags includes "RC_CMD" and a client specific tag.\n
256 * The latter is composed of the hexadecimal formatted IP sub-address of the client's host CPU (see JSYSTEM::getSubaddress(const int)) and \n
257 * the client's name extension (part following KM3NETDAQ::CLIENTNAME_DELIMETER), if any.\n
258 * The list of tags and the various delimiters are maintained in include file JDAQTags.hh.
259 *
260 * For client specific events requiring a different tag,
261 * the corresponding entry in the event table should be replaced.\n
262 * This should be done in the constructor of the derived class using method replaceEvent().
263 *
264 * The virtual method filter() can be re-implemented so that a specific action
265 * is made before the corresponding message is processed.\n
266 * The message is ignored if this method returns true, else it is normally processed.
267 *
268 * The method setSelect() can be used to set the file descriptor mask of the general select call.\n
269 * In conjunction, the method actionSelect() can be used
270 * to take client specific actions following the select call.
271 *
272 * If the clock interval is non-zero, the method actionRunning() is repeatedly called
273 * according the specified interval time when the client is in state <tt>Running</tt>.\n
274 * The clock interval can be set using method setClockInterval().
275 *
276 * Some input can be redefined during operation.\n
277 * For example the debug level can be set via the following command message.
278 * <pre>
279 * JPutMessage -H <host name> -t <tag> -m "debug=<level>;"
280 * </pre>
281 * where
282 * - <tt>host name</tt> is the name of the host of the command message server;
283 * - <tt>tag</tt> the tag; and
284 * - <tt>level</tt> the new debug level.
285 *
286 * In this, the tag "RC_CMD" applies to all applications and the client specific tag to an individual application.
287 *
288 * Additional custom tags can be added to the general list using method addSubscription().\n
289 * The method actionTagged() is then called when a command message is received with the specified tag.
290 *
291 * For tests and possible other setups, the base class can be configured to run stand-alone or forever.\n
292 * In stand-alone mode, the client can be steered from an regular input stream.\n
293 * When the client runs forever, it waits for a connection before going to the normal mode of operation.\n
294 * The primary input should then be sent via this connection.\n
295 * The method addParameter() can be used to add parameters of
296 * the derived class to the list that is parsed in method enter().
297 */
299 public JDAQStateMachine,
300 public JDAQClient_t
301 {
302 using CHSM::machine::enter;
303 using CHSM::machine::exit;
304
305 public:
306 /**
307 * Constructor.
308 *
309 * This constructor should be used in normal mode.\n
310 * The following methods methods should subsequently be called.
311 * - enter();
312 * - run().
313 *
314 * \param name name of client
315 * \param server name of command message server
316 * \param logger pointer to logger
317 * \param level debug level
318 */
319 JDAQClient(const std::string& name,
320 const std::string& server,
322 const int level) :
324 JDAQClient_t (this)
325 {
326 this->logger = JMessageLogger(logger, name, level);
327
328 try {
329 this->server.reset(new JControlHost(server));
330 }
331 catch(const std::exception& error) {
332 JErrorStream(this->logger) << error.what();
333 }
334
335 std::string buffer;
336
338
339 if (buffer != "") {
340 JErrorStream(this->logger) << "Process with nick name \"" << getFullName() << "\" already running on host(s) " << buffer;
341 }
342 }
343
344
345 /**
346 * Constructor.
347 *
348 * This constructor should be used when running stand-alone.\n
349 * The following methods methods should subsequently be called.
350 * - CHSM::machine::enter();
351 * - run(std::istream& in);
352 *
353 * \param name name of client
354 * \param logger pointer to logger
355 * \param level debug level
356 */
357 JDAQClient(const std::string& name,
359 const int level) :
361 JDAQClient_t (this)
362 {
363 this->logger = JMessageLogger(logger, name, level);
364 }
365
366
367 /**
368 * Constructor.
369 *
370 * This constructor should be used when running forever.\n
371 * The following method should subsequently be called.
372 * - run(const int port);
373 *
374 * \param name name of client
375 */
376 JDAQClient(const std::string& name) :
378 JDAQClient_t (this)
379 {}
380
381
382 /**
383 * Enter the state machine.
384 *
385 * This overloaded method enter reproduces the constructor.
386 * All necessary input is parsed from the list of arguments.
387 * In case of an error, the state machine is not entered.
388 *
389 * \param args array of command line arguments
390 * \return true if okay; else false
391 */
392 virtual bool enter(const JArgs& args)
393 {
394 using namespace std;
395
396 string server;
397 string logger;
398 int level;
399 bool use_cout;
400
401 try {
402
403 parser['H'] = make_field(server) = "localhost";
404 parser['M'] = make_field(logger) = "localhost";
405 parser['d'] = make_field(level) = 0;
406 parser['c'] = make_field(use_cout);
407
408 if (parser.read(args) != 0) {
409 return false;
410 }
411 }
412 catch(const std::exception &error) {
413 cerr << error.what() << endl;
414 return false;
415 }
416
417 try {
418
419 JLogger* out = NULL;
420
421 if (use_cout)
422 out = new JStreamLogger(cout);
423 else
424 out = new JControlHostLogger(logger);
425
426 this->logger = JMessageLogger(out, getName(), level);
427
428 this->server.reset(new JControlHost(server));
429
430 return enter();
431 }
432 catch(const std::exception& error) {
433 cerr << error.what() << endl;
434 return false;
435 }
436 }
437
438
439 /**
440 * Enter the state machine.
441 *
442 * This method activates the subscription to JNET::JControlHost messages.
443 * In case of an error, the state machine is not entered.
444 *
445 * \return true if okay; else false
446 */
447 virtual bool enter() override
448 {
449 using namespace std;
450 using namespace JPP;
451
452 if (server.is_valid() && logger.is_valid()) {
453
455
456 try {
457
458 server->Subscribe(buffer);
459 server->SendMeAlways();
460 server->MyId(getFullName());
461
462 JStatusStream(logger) << "Process with nick name \"" << getFullName() << "\" version \"" << getGITVersion() << "\" subscription: " << buffer.toString();
463
464 return CHSM::machine::enter();
465 }
466 catch(const std::exception& error) {
467 JErrorStream(logger) << error.what();
468 }
469
470 } else {
471 cerr << "Message server or logger not properly initialised." << endl;
472 }
473
474 return false;
475 }
476
477
478 /**
479 * Exit the state machine.
480 *
481 * This method releases the various resources.
482 *
483 * \return true if okay; else false
484 */
485 virtual bool exit() override
486 {
487 try {
488 if (server.is_valid()) { server.reset(NULL); }
489 }
490 catch(const std::exception& error) {
491 }
492
493 try {
494 if (logger.is_valid()) { logger.reset(NULL); }
495 }
496 catch(const std::exception& error) {
497 }
498
499 return CHSM::machine::exit();
500 }
501
502
503 /**
504 * Check if this client is in runnig state.
505 *
506 * \return true if running; else false
507 */
508 bool isRunning() const
509 {
510 return Main.RunControl.Operational.Running.active();
511 }
512
513
514 /**
515 * Replace tag of given event in event table.
516 *
517 * \param oldTag old tag
518 * \param newTag new tag
519 * \param event event
520 */
521 void replaceEvent(const JTag& oldTag,
522 const JTag& newTag,
523 JDAQEvent_t& event)
524 {
525 eventTable.replace(oldTag, newTag, event);
526 }
527
528
529 /**
530 * Find event in event table.
531 *
532 * \param tag tag
533 * \param event_name event name
534 * \return pointer to event or NULL
535 */
536 JDAQEvent_t* findEvent(const JTag& tag, const std::string& event_name)
537 {
538 JEventTable::const_iterator i = eventTable.find(tag, event_name);
539
540 if (i != eventTable.end())
541 return i->second;
542 else
543 return NULL;
544 }
545
546
547 /**
548 * Add custom subscription.
549 *
550 * \param subscription subscription
551 */
553 {
554 this->subscription.add(subscription);
555 }
556
557
558 /**
559 * Add parameter to parser used in method enter().
560 *
561 * \param option option
562 * \param parameter parameter
563 */
564 template<class T>
565 void addParameter(const char option, T& parameter)
566 {
567 parser[option] = make_field(parameter);
568 }
569
570
571 /**
572 * Add parameter to parser used in method enter().
573 *
574 * \param option option
575 * \param parameter parameter
576 * \param value default value
577 */
578 template<class T>
579 void addParameter(const char option, T& parameter, const T& value)
580 {
581 parser[option] = make_field(parameter) = value;
582 }
583
584
585 /**
586 * Set the file descriptor mask for the select call.
587 */
588 void setSelect()
589 {
590 select.reset();
591
593
595 }
596
597
598 /**
599 * Set the file descriptor mask for the select call.
600 * This implementation does nothing but may be redefined by the derived class.
601 *
602 * \param mask file descriptor mask
603 */
604 virtual void setSelect(JFileDescriptorMask& mask) const
605 {}
606
607
608 /**
609 * Action method following last select call.
610 * This implementation does nothing but may be redefined by the derived class.
611 *
612 * \param mask file descriptor mask
613 */
614 virtual void actionSelect(const JFileDescriptorMask& mask)
615 {}
616
617
618 /**
619 * This method is repeatedly called when this client machine is in state Running
620 * and the clock interval time is non-zero.
621 * This implementation does nothing but may be redefined by the derived class.
622 * Care has to be taken so that the time needed to execute this method should be
623 * less than the specified clock interval time (see method setClockInterval()).
624 */
625 virtual void actionRunning()
626 {}
627
628
629 /**
630 * This method is called at <tt>ev_input</tt>.
631 *
632 * \param length length of data
633 * \param buffer pointer to data
634 */
635 virtual void actionInput(int length, const char* buffer) override
636 {
637 using namespace std;
638
639 JProperties properties(JEquationParameters("=", ";", "", ""), 1);
640
641 int level = this->logger.getLevel();
642
643 properties["debug"] = level;
644
645 properties.read(string(buffer, length));
646
647 this->logger.setLevel(level);
648 }
649
650
651 /**
652 * Filter message.
653 * The filter method can be overwritten so that a specific action is made
654 * before the corresponding message is processed by the state machine.
655 * The message is ignored if true is returned, else it is normally processed.
656 *
657 * \param tag tag
658 * \param length number of characters
659 * \param buffer message
660 * \return skip message or not
661 */
662 virtual bool filter(const JTag& tag, int length, const char* buffer)
663 {
664 return false;
665 }
666
667
668 /**
669 * This method is called when a custom tag is encountered.
670 *
671 * \param tag tag
672 * \param length length of data
673 * \param buffer pointer to data
674 */
675 virtual void actionTagged(const JTag& tag, int length, const char* buffer)
676 {
677 }
678
679
680 /**
681 * Run as run control client following command messages via JNET::JControlHost.
682 * This method can be called once the state machine is entered.
683 * It returns when the state machine is exited.
684 * If the clock interval is non-zero, the method actionRunning() is
685 * repeatedly called when this client machine is in state Running.
686 * The file descriptor mask can be set to interrupt the timeout of
687 * the select call and clock method wait() in this calling sequence
688 * (see methods setSelect() and actionSelect()).
689 */
690 void run()
691 {
692 using namespace std;
693 using namespace JPP;
694
695 while (active()) {
696
697 try {
698
699 setSelect();
700
701 if (select(JTimeval(TIMEOUT_S,0)) > 0) {
702
704 update();
705 }
706
708
709 } else {
710
711 continue;
712 }
713
714
715 if (isRunning() && clock.getInterval() != 0LL) {
716
717 long long int numberOfCalls = 0;
718
719 clock.reset();
720
721 do {
722
723 ++numberOfCalls;
724
725 setSelect();
726
728
730 update();
731 }
732
734
735 } else {
736
737 try {
739 }
740 catch(const std::exception& error) {
741 logger.error(error.what());
742 }
743 }
744
745 } while (isRunning());
746
747 if (numberOfCalls != 0) {
748 JNoticeStream(logger) << "Delay per call " << clock.getDelay() / numberOfCalls / 1000 << " ms";
749 }
750 }
751 }
752 catch(const JPP::JSocketException& error) {
753 JErrorStream(logger) << "method run(): \"" << error.what() << "\" -> trigger ev_error.";
754 ev_error();
755 }
756 catch(const std::exception& error) {
757 JErrorStream(logger) << "method run(): \"" << error.what() << "\"";
758 }
759 }
760 }
761
762
763 /**
764 * Run for ever.
765 * This method can be used when the run control client is started before the run control
766 * (e.g.\ at boot time of the host processor).
767 * This method should be called before the state machine is entered.
768 * It launches a server which accepts a JNET::JControlHost connection from
769 * a designated application e.g.\ the JDAQClientStarter.cc program.
770 * The state machine is entered using the available data in the JNET::JControlHost message.
771 * After the state machine is exited, it accepts a new a JNET::JControlHost connection.
772 *
773 * \param port port number
774 */
775 void run(const int port)
776 {
777 JControlHostServer local_server(port);
778
779 for ( ; ; ) {
780
781 JControlHost* ps = local_server.AcceptClient();
782
783 ps->Connected();
784
785 JNET::JPrefix prefix;
786
787 ps->WaitHead(prefix);
788
789 const int length = prefix.getSize();
790
791 char* buffer = new char[length];
792
793 ps->GetFullData(buffer, length);
794 ps->PutFullData(prefix.toString(), buffer, length);
795
796 delete ps;
797
798 enter(JArgs(std::string(buffer, length)));
799
800 delete [] buffer;
801
802 run();
803
804 exit();
805 }
806 }
807
808
809 /**
810 * Run client with commands from input stream (e.g.\ for debugging).
811 *
812 * Example input format:
813 * <pre>
814 * <tag> <event name>[\#data];
815 * <tag> <event name>[\#data];
816 * </pre>
817 *
818 * \param in input stream
819 */
820 void run(std::istream& in)
821 {
822 using namespace std;
823
824 string tag;
825 string buffer;
826
827 while (in >> tag && in >> skipws && getline(in, buffer, ';')) {
828 update(tag, buffer.length(), buffer.data());
829 }
830 }
831
832 protected:
833
835 JMessageLogger logger; //!< message logger
836
837 private:
838 /**
839 * Update state machine.
840 * This method waits for a message from JNET::JControlHost server.
841 */
842 void update()
843 {
844 JNET::JPrefix prefix;
845
846 server->WaitHead(prefix);
847
848 const int length = prefix.getSize();
849
850 char* buffer = new char[length];
851
852 server->GetFullData(buffer, length);
853
854 update(prefix.getTag(), length, buffer);
855
856 delete [] buffer;
857 }
858
859
860 /**
861 * Update state machine.
862 *
863 * \param tag tag
864 * \param length number of characters
865 * \param buffer message
866 */
867 void update(const JTag& tag, int length, const char* buffer)
868 {
869 using namespace std;
870 using namespace JPP;
871
872 if (filter(tag, length, buffer)) {
873 return;
874 }
875
876 if (getSubscription(eventTable)->count(JSubscriptionAny(tag)) == 0 &&
877 getSubscription(eventTable)->count(JSubscriptionAll(tag)) == 0) {
878
879 actionTagged(tag, length, buffer);
880
881 return;
882 }
883
884
885 string::size_type pos = 0;
886
887 while (pos != (string::size_type) length && TOKEN_DELIMETER.find(*(buffer + pos)) == string::npos) {
888 ++pos;
889 }
890
891 const JEvent_t event = JEvent_t::toValue(string(buffer, pos));
892
893 if (event.hasInfo()) {
894 setEventInfo(event.getInfo());
895 }
896
897 while (pos != (string::size_type) length && TOKEN_DELIMETER.find(*(buffer + pos)) != string::npos) {
898 ++pos;
899 }
900
901
902 JEventTable::const_iterator i = eventTable.find(tag, event.getName());
903
904 if (i != eventTable.end()) {
905
906 const CHSM::state* const s0 = getState();
907
908 if (!i->second->active()) {
909
910 JWarningStream(logger) << "Event " << i->second->name() << " not active (" << (s0 != NULL ? s0->name() : "") << ")";
911
912 if (server.is_valid() && s0 != NULL) {
913 server->PutFullString(RC_FAIL, getMessage(*s0, *i->second));
914 }
915 }
916
917 // redirect all I/O
918
919 {
921 JErrorStream error(logger);
922
923 JRedirectStream rs_cin (cin, JLANG::null);
924 JRedirectStream rs_cout(cout, debug);
925 JRedirectStream rs_cerr(cerr, error);
926
927 if (rs_cin &&
928 rs_cout &&
929 rs_cerr) {
930
931 (*(i->second))(length - pos, buffer + pos);
932 }
933 }
934
935 const CHSM::state* const s1 = getState();
936
937 JStatusStream(logger) << "Transition "
938 << (s0 != NULL ? s0->name() : "")
939 << "->(" << i->second->name() << ")->"
940 << (s1 != NULL ? s1->name() : "");
941 } else {
942
943 JErrorStream(logger) << "Unknown key <" << tag << "," << event.getName() << ">";
944 }
945 }
946
947
948 /**
949 * Configure client.
950 * This method is used to setup the event table.
951 */
953 {
954 }
955
956
957 /**
958 * Get event message.
959 *
960 * \param state state
961 * \param event event
962 * \return message
963 */
964 std::string getMessage(const CHSM::state& state, const CHSM::event& event) const
965 {
966 std::ostringstream os;
967
968 os << getFullName()
970 << (getEventInfo() != "" ?
971 JEvent_t(event.name(), getEventInfo()) :
972 JEvent_t(event.name()))
974 << getStateName(state.name());
975
976 return os.str();
977 }
978
979
980 /**
981 * Action when entering state.
982 * This method provides for the hand shaking with the run control program.
983 *
984 * \param state entered state
985 * \param event event that triggered transition
986 */
987 virtual void enterState(const CHSM::state& state, const CHSM::event& event) override
988 {
989 if (server.is_valid()) {
990 server->PutFullString(RC_REPLY, getMessage(state, event));
991 }
992 }
993
994
995 /**
996 * This method is called at <tt>ev_check</tt> and reports a system check by mimicing an enter state action.
997 *
998 * \param length number of characters
999 * \param buffer message
1000 */
1001 virtual void actionCheck(int length, const char* buffer) override
1002 {
1003 if (Main.RunControl.Error.active()) {
1004
1006
1007 } else {
1008
1009 for (CHSM::parent::iterator state = Main.RunControl.Operational.begin(); state != Main.RunControl.Operational.end(); ++state) {
1010
1011 if (state->active()) {
1012
1013 // mimic enter state
1014
1015 enterState(*state, ev_check);
1016 }
1017 }
1018 }
1019 }
1020
1021
1022 /**
1023 * The method to execute the action.
1024 *
1025 * \param __action pointer to action method
1026 * \param __event event that triggered the action
1027 */
1028 void execute(action __action, const CHSM::event& __event) override
1029 {
1030 try {
1031
1032 const JDAQStateMachine::ev_daq_event& event = dynamic_cast<const JDAQStateMachine::ev_daq_event&>(__event);
1033
1034 (this->*__action)(event->length, event->buffer);
1035 }
1036 catch(const std::exception& error) {
1037 JErrorStream(logger) << "Error at event " << __event.name() << " \"" << error.what() << "\"; trigger ev_error.";
1038 ev_error();
1039 }
1040 }
1041
1042
1043 /**
1044 * Get current state.
1045 *
1046 * \return state
1047 */
1048 const CHSM::state* getState() const
1049 {
1050 for (CHSM::parent::const_iterator state = Main.RunControl.Operational.begin(); state != Main.RunControl.Operational.end(); ++state) {
1051 if (state->active()) {
1052 return &(*state);
1053 }
1054 }
1055
1056 if (Main.RunControl.Error.active()) {
1057 return &Main.RunControl.Error;
1058 }
1059
1060 return NULL;
1061 }
1062
1063
1064 JSelectReader select; //!< select call
1065 JParser<> parser; //!< parser method enter()
1066 JSubscriptionList subscription; //!< custom subscription
1067 };
1068}
1069
1070#endif
Fixed parameters and ControlHost tags for KM3NeT DAQ.
General purpose message reporting.
Message reporting compatible with STL output stream operations.
int debug
debug level
Definition JSirene.cc:72
Hostname and IP address functions.
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Utility class to parse parameter values.
Scheduling of actions via fixed latency intervals.
Jpp environment information.
const std::string & getName() const
Get name of state machine.
Definition JDAQCHSM.hh:89
void(JDAQCHSM::*) action(int, const char *)
Type definition of action method.
Definition JDAQCHSM.hh:152
std::string name
Definition JDAQCHSM.hh:165
JDAQStateMachine::state_Main::state_RunControl::state_Operational Operational
JDAQStateMachine::state_Main::state_RunControl RunControl
JDAQStateMachine::ev_recover_event ev_recover
JDAQStateMachine::ev_continue_event ev_continue
JDAQStateMachine::ev_stop_event ev_stop
JDAQStateMachine::ev_off_event ev_off
JDAQStateMachine::ev_init_event ev_init
JDAQStateMachine::ev_start_event ev_start
JDAQStateMachine::ev_pause_event ev_pause
JDAQStateMachine::ev_check_event ev_check
JDAQStateMachine::ev_error_event ev_error
JDAQStateMachine::ev_reset_event ev_reset
JDAQStateMachine::ev_configure_event ev_configure
JDAQStateMachine::state_Main Main
JDAQStateMachine::ev_input_event ev_input
JDAQStateMachine::ev_quit_event ev_quit
Data structure to store command line arguments.
Definition JArgs.hh:26
Utility class to parse parameter values.
bool read(const JEquation &equation)
Read equation.
Time keeper.
long long int getDelay() const
Get total delay time.
void setInterval(const long long int interval_us)
Set interval time.
void wait() const
Wait until the number of time intervals has elapsed since the last call to the reset method.
void reset(const long long int t0)
Reset time.
long long int getInterval() const
Get interval time.
Exception for ControlHost.
Simple data structure to support I/O of equations (see class JLANG::JEquation).
virtual const char * what() const override
Get error message.
Definition JException.hh:64
Auxiliary class for method select.
This class can be used to temporarily redirect one output (input) stream to another output (input) st...
The template JSharedPointer class can be used to share a pointer to an object.
Exception for socket.
static void Throw(const bool option)
Definition JThrow.hh:37
Auxiliary class for time values.
Definition JTimeval.hh:29
Message logging based on ControlHost.
Interface for logging messages.
Definition JLogger.hh:22
bool is_valid() const
Check validity of logger object.
void error(const JMessage_t &message)
void reset(JLogger *__logger=NULL)
Reset logger.
JLevel_t getLevel()
Get debug level.
void setLevel(const int __level)
Set debug level.
Message logging based on std::ostream.
Light-weight wrapper class around server socket.
JControlHost * AcceptClient(JTimeval timeout=JTimeval::max())
Accept new client.
ControlHost class.
static int WhereIs(const std::string &host_name, const std::string &nick_name, std::string &answer)
Locate ControlHost client(s).
int WaitHead(JPrefix &prefix)
Wait for header.
int GetFullData(void *buffer, long long int length)
Receive data.
int PutFullData(const JTag &tag, const void *buffer, const long long int length)
Send data.
int Connected()
Send version.
ControlHost prefix.
Definition JPrefix.hh:33
int getSize() const
Get size.
Definition JPrefix.hh:62
Wrapper class for select call.
void setReaderMask(const JAbstractFile &file)
Set reader mask.
bool hasReaderMask(const JAbstractFile &file) const
Has reader file.
JFileDescriptorMask & getReaderMask()
Get reader mask.
Subscription list.
std::string toString() const
Convert subscription list to string.
ControlHost subscription.
ControlHost tag.
Definition JTag.hh:38
std::string toString() const
Convert tag to string.
Definition JTag.hh:171
const JTag & getTag() const
Get tag.
Definition JTag.hh:86
Utility class to parse command line options.
Definition JParser.hh:1698
int read(const int argc, const char *const argv[])
Parse the program's command line options.
Definition JParser.hh:1992
Control unit client base class.
virtual void enterState(const CHSM::state &state, const CHSM::event &event) override
Action when entering state.
void update(const JTag &tag, int length, const char *buffer)
Update state machine.
JSharedPointer< JControlHost > server
message server
virtual void actionInput(int length, const char *buffer) override
This method is called at ev_input.
bool isRunning() const
Check if this client is in runnig state.
void update()
Update state machine.
virtual bool filter(const JTag &tag, int length, const char *buffer)
Filter message.
JDAQClient(const std::string &name)
Constructor.
JParser parser
parser method enter()
virtual void actionTagged(const JTag &tag, int length, const char *buffer)
This method is called when a custom tag is encountered.
JDAQClient(const std::string &name, JLogger *logger, const int level)
Constructor.
virtual void actionSelect(const JFileDescriptorMask &mask)
Action method following last select call.
void replaceEvent(const JTag &oldTag, const JTag &newTag, JDAQEvent_t &event)
Replace tag of given event in event table.
void execute(action __action, const CHSM::event &__event) override
The method to execute the action.
std::string getMessage(const CHSM::state &state, const CHSM::event &event) const
Get event message.
virtual bool exit() override
Exit the state machine.
void addParameter(const char option, T &parameter)
Add parameter to parser used in method enter().
void run(std::istream &in)
Run client with commands from input stream (e.g. for debugging).
void run(const int port)
Run for ever.
void run()
Run as run control client following command messages via JNET::JControlHost.
void configure()
Configure client.
virtual void setSelect(JFileDescriptorMask &mask) const
Set the file descriptor mask for the select call.
JSelectReader select
select call
JDAQEvent_t * findEvent(const JTag &tag, const std::string &event_name)
Find event in event table.
const CHSM::state * getState() const
Get current state.
JMessageLogger logger
message logger
virtual void actionRunning()
This method is repeatedly called when this client machine is in state Running and the clock interval ...
void addParameter(const char option, T &parameter, const T &value)
Add parameter to parser used in method enter().
void setSelect()
Set the file descriptor mask for the select call.
virtual bool enter() override
Enter the state machine.
JSubscriptionList subscription
custom subscription
virtual bool enter(const JArgs &args)
Enter the state machine.
JDAQClient(const std::string &name, const std::string &server, JLogger *logger, const int level)
Constructor.
virtual void actionCheck(int length, const char *buffer) override
This method is called at ev_check and reports a system check by mimicing an enter state action.
void addSubscription(const JSubscription &subscription)
Add custom subscription.
void insert(const JTag &tag, JDAQEvent_t &event)
Insert entry in table.
void replace(const JTag &oldTag, const JTag &newTag, JDAQEvent_t &event)
Replace entry in table.
const_iterator find(const JTag &tag, const std::string &event_name) const
Find entry.
static JNullStream null
Null I/O stream.
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition JString.hh:478
const char * getGITVersion()
Get GIT version.
Definition Jpp.cc:9
Message logging.
static const JTag DISPTAG_UNDEFINED(0)
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
const char * getName()
Get ROOT name of given data type.
KM3NeT DAQ data structures and auxiliaries.
Definition DataQueue.cc:39
static const JNET::JTag RC_REPLY
Definition JDAQTags.hh:67
std::string getFullName(const std::string &hostname, const std::string &name)
Get full name of run control client.
JSubscriptionList getSubscription(const JEventTable &event_table)
Convert event table to ControlHost subscription.
static const std::string TOKEN_DELIMETER
Definition JDAQTags.hh:58
JTag getUniqueTag(const std::string &hostname, const std::string &name)
Get unique tag of run control client.
static const JNET::JTag RC_CMD
Definition JDAQTags.hh:66
std::string getStateName(const std::string &name)
Get name of state.
char getTokenDelimeter()
Get the token delimeter for command messages.
static const JNET::JTag RC_FAIL
Definition JDAQTags.hh:68
Level specific message streamers.
Auxiliary class for all subscription.
Auxiliary class for any subscription.
Auxiliary data structure for DAQ client data.
Definition JDAQClient.hh:61
const std::string & getHostname() const
Get hostname.
const JTag & getUniqueTag() const
Get unique tag of this run control client.
JTimekeeper clock
central clock
const std::string & getFullName() const
Get full name of this run control client.
void setEventInfo(const std::string &info)
Set last event information.
void setClockInterval(const long long int interval_us)
Set interval time.
long long int getClockDelay() const
Get total delay time.
void resetClock()
Reset clock.
JEventTable eventTable
event table
const std::string & getEventInfo() const
Get last event information.
JDAQClient_t(JDAQStateMachine *chsm)
Constructor.
Definition JDAQClient.hh:71
std::string event_info
event information
long long int getClockInterval() const
Get interval time.
static const int TIMEOUT_S
time out of update [s]
Definition JDAQClient.hh:63
Auxiliary class for handling event name and optional static information.
Definition JEvent_t.hh:23
static JEvent_t toValue(const std::string &buffer)
Convert string to event.
Definition JEvent_t.hh:99