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