Jpp  17.3.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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"
17 #include "JLang/JSharedPointer.hh"
19 #include "JLang/JTimeval.hh"
20 #include "JLang/JRedirectStream.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"
27 #include "JLogger/JStreamLogger.hh"
30 #include "JDAQ/JDAQTags.hh"
33 #include "JRuncontrol/JDAQCHSM.hh"
34 
35 
36 /**
37  * \author mdejong
38  */
39 
40 namespace KM3NETDAQ {
41 
42  using namespace JLOGGER;
43  using JNET::JTag;
44  using JNET::JControlHost;
46  using JNET::JSubscription;
48  using JNET::JSelectReader;
51  using JLANG::JTimeval;
53  using JEEP::JArgs;
54  using JEEP::JTimekeeper;
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  event_number(-1)
72  {
73  using namespace std;
74  using namespace JPP;
75 
76  hostname = getHostname();
77  fullname = KM3NETDAQ::getFullName (hostname, chsm->getName());
78  unique_tag = KM3NETDAQ::getUniqueTag(hostname, chsm->getName());
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 
98  JControlHost::Throw(true);
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  */
174  void resetClock()
175  {
176  clock.reset();
177  }
178 
179 
180  /**
181  * Get last event number.
182  *
183  * \return event number
184  */
185  int getEventNumber() const
186  {
187  return event_number;
188  }
189 
190 
191  /**
192  * Set last event number.
193  *
194  * \param event_number event number
195  */
196  void setEventNumber(const int event_number)
197  {
198  this->event_number = event_number;
199  }
200 
201 
202  protected:
203  JEventTable eventTable; //!< event table
207  JTimekeeper clock; //!< central clock
208  int event_number; //!< number of last event
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 be then used to process command messages.\n
224  * The client's state machine will accordingly be updated.\n
225  * For each state transition, a corresponding action method is called
226  * which could be re-implemented in the derived class (see JDAQCHSM).\n
227  * Optionally, a designated action method is repeatedly called in state <tt>Running</tt>.
228  *
229  * The default list of tags includes "RC_CMD" and a client specific tag.\n
230  * The latter is composed of the hexadecimally formatted IP sub-address of the client's host CPU
231  * (see JSYSTEM::getSubaddress(const int)) and the client's name extension
232  * (part following KM3NETDAQ::CLIENTNAME_DELIMETER), if any.\n
233  * The list of tags is maintained in include file JDAQTags.hh.
234  *
235  * For client specific events requiring a different tag,
236  * the corresponding entry in the event table should be replaced.\n
237  * This should be done in the constructor of the derived class using method replaceEvent.
238  *
239  * The virtual method filter() can be re-implemented so that a specific action
240  * is made before the corresponding message is processed.\n
241  * The message is ignored if this method returns true, else it is normally processed.
242  *
243  * The method setSelect() can be used to set the file descriptor mask of the general select call.\n
244  * In conjunction, the method actionSelect() can be used
245  * to take client specific actions following the select call.
246  *
247  * If the clock interval is non-zero, the method actionRunning() is repeatedly called
248  * according the specified interval time when the client is in state <tt>Running</tt>.\n
249  * The clock interval can be set using method setClockInterval().
250  *
251  * Some input can be redefined during operation.\n
252  * For example the debug level can be set via the following command message.
253  * <pre>
254  * JPutMessage -H <host name> -t <tag> -m "debug=<level>;"
255  * </pre>
256  * where
257  * - <tt>host name</tt> is the name of the host of the command message server;
258  * - <tt>tag</tt> the tag; and
259  * - <tt>level</tt> the new debug level.
260  *
261  * In this, the tag "RC_CMD" applies to all applications and the client specific tag to the one-and-only application.
262  *
263  * Additional custom tags can be added to the general list using method addSubscription().\n
264  * The method actionTagged() is then called when a command message is received with the specified tag.
265  *
266  * For tests and possible other setups, the base class can be configured to run stand-alone or forever.\n
267  * In stand-alone mode, the client can be steered from an regular input stream.\n
268  * When the client runs forever, it waits for a connection before going to the normal mode of operation.\n
269  * The primary input should then be sent via this connection.\n
270  * The method addParameter() can be used to add parameters of
271  * the derived class to the list that is parsed in method enter().
272  */
273  class JDAQClient :
274  public JDAQStateMachine,
275  public JDAQClient_t
276  {
277  public:
278  /**
279  * Constructor.
280  *
281  * This constructor should be used in normal mode.\n
282  * The following methods methods should subsequently be called.
283  * - enter();
284  * - run().
285  *
286  * \param name name of client
287  * \param server name of command message server
288  * \param logger pointer to logger
289  * \param level debug level
290  */
292  const std::string& server,
293  JLogger* logger,
294  const int level) :
295  JDAQStateMachine(name),
297  {
298  this->logger = JMessageLogger(logger, name, level);
299 
300  try {
301  this->server.reset(new JControlHost(server));
302  }
303  catch(JControlHostException& error) {
304  JErrorStream(this->logger) << error;
305  }
306 
307  std::string buffer;
308 
309  JControlHost::WhereIs(server, getFullName(), buffer);
310 
311  if (buffer != "") {
312  JErrorStream(this->logger) << "Process with nick name \"" << getFullName() << "\" already running on host(s) " << buffer;
313  }
314  }
315 
316 
317  /**
318  * Constructor.
319  *
320  * This constructor should be used when running stand-alone.\n
321  * The following methods methods should subsequently be called.
322  * - CHSM::machine::enter();
323  * - run(std::istream& in);
324  *
325  * \param name name of client
326  * \param logger pointer to logger
327  * \param level debug level
328  */
330  JLogger* logger,
331  const int level) :
332  JDAQStateMachine(name),
334  {
335  this->logger = JMessageLogger(logger, name, level);
336  }
337 
338 
339  /**
340  * Constructor.
341  *
342  * This constructor should be used when running forever.\n
343  * The following method should subsequently be called.
344  * - run(const int port);
345  *
346  * \param name name of client
347  */
349  JDAQStateMachine(name),
351  {}
352 
353 
354  /**
355  * Enter the state machine.
356  *
357  * This overloaded method enter reproduces the constructor.
358  * All necessary input is parsed from the list of arguments.
359  * In case of an error, the state machine is not entered.
360  *
361  * \param args array of command line arguments
362  * \return true if okay; else false
363  */
364  virtual bool enter(const JArgs& args)
365  {
366  using namespace std;
367 
368  string server;
369  string logger;
370  int level;
371  bool use_cout;
372 
373  try {
374 
375  parser['H'] = make_field(server) = "localhost";
376  parser['M'] = make_field(logger) = "localhost";
377  parser['d'] = make_field(level) = 0;
378  parser['c'] = make_field(use_cout);
379 
380  if (parser.read(args) != 0) {
381  return false;
382  }
383  }
384  catch(const exception &error) {
385  cerr << error.what() << endl;
386  return false;
387  }
388 
389  try {
390 
391  JLogger* out = NULL;
392 
393  if (use_cout)
394  out = new JStreamLogger(cout);
395  else
396  out = new JControlHostLogger(logger);
397 
398  this->logger = JMessageLogger(out, getName(), level);
399 
400  this->server.reset(new JControlHost(server));
401 
402  return enter();
403  }
404  catch(const JControlHostException& error) {
405  cerr << error << endl;
406  return false;
407  }
408  }
409 
410 
411  /**
412  * Enter the state machine.
413  *
414  * This method activates the subscription to JNET::JControlHost messages.
415  * In case of an error, the state machine is not entered.
416  *
417  * \return true if okay; else false
418  */
419  virtual bool enter()
420  {
421  using namespace std;
422  using namespace JPP;
423 
424  if (server.is_valid() && logger.is_valid()) {
425 
426  const JSubscriptionList buffer = getSubscription(eventTable) + subscription;
427 
428  try {
429 
430  server->Subscribe(buffer);
431  server->SendMeAlways();
432  server->MyId(getFullName());
433 
434  JStatusStream(logger) << "Process with nick name \"" << getFullName() << "\" version \"" << getGITVersion() << "\" subscription: " << buffer.toString();
435 
436  return CHSM::machine::enter();
437  }
438  catch(const JControlHostException& error) {
439  JErrorStream(logger) << error;
440  }
441 
442  } else {
443  cerr << "Message server or logger not properly initialised." << endl;
444  }
445 
446  return false;
447  }
448 
449 
450  /**
451  * Exit the state machine.
452  *
453  * This method releases the various resources.
454  *
455  * \return true if okay; else false
456  */
457  virtual bool exit()
458  {
459  try {
460  if (server.is_valid()) { server.reset(NULL); }
461  }
462  catch(const JControlHostException& error) {
463  }
464 
465  try {
466  if (logger.is_valid()) { logger.reset(NULL); }
467  }
468  catch(const JControlHostException& error) {
469  }
470 
471  return CHSM::machine::exit();
472  }
473 
474 
475  /**
476  * Check if this client is in runnig state.
477  *
478  * \return true if running; else false
479  */
480  bool isRunning() const
481  {
482  return Main.RunControl.Operational.Running.active();
483  }
484 
485 
486  /**
487  * Replace tag of given event in event table.
488  *
489  * \param oldTag old tag
490  * \param newTag new tag
491  * \param event event
492  */
493  void replaceEvent(const JTag& oldTag,
494  const JTag& newTag,
495  JDAQEvent_t& event)
496  {
497  eventTable.replace(oldTag, newTag, event);
498  }
499 
500 
501  /**
502  * Find event in event table.
503  *
504  * \param tag tag
505  * \param event_name event name
506  * \return pointer to event or NULL
507  */
508  JDAQEvent_t* findEvent(const JTag& tag, const std::string& event_name)
509  {
510  JEventTable::const_iterator i = eventTable.find(tag, event_name);
511 
512  if (i != eventTable.end())
513  return i->second;
514  else
515  return NULL;
516  }
517 
518 
519  /**
520  * Add custom subscription.
521  *
522  * \param subscription subscription
523  */
524  void addSubscription(const JSubscription& subscription)
525  {
526  this->subscription.add(subscription);
527  }
528 
529 
530  /**
531  * Add parameter to parser used in method enter().
532  *
533  * \param option option
534  * \param parameter parameter
535  */
536  template<class T>
537  void addParameter(const char option, T& parameter)
538  {
539  parser[option] = make_field(parameter);
540  }
541 
542 
543  /**
544  * Add parameter to parser used in method enter().
545  *
546  * \param option option
547  * \param parameter parameter
548  * \param value default value
549  */
550  template<class T>
551  void addParameter(const char option, T& parameter, const T& value)
552  {
553  parser[option] = make_field(parameter) = value;
554  }
555 
556 
557  /**
558  * Set the file descriptor mask for the select call.
559  */
560  void setSelect()
561  {
562  select.reset();
563 
564  setSelect(select.getReaderMask());
565 
566  select.setReaderMask(*server);
567  }
568 
569 
570  /**
571  * Set the file descriptor mask for the select call.
572  * This implementation does nothing but may be redefined by the derived class.
573  *
574  * \param mask file descriptor mask
575  */
576  virtual void setSelect(JFileDescriptorMask& mask) const
577  {}
578 
579 
580  /**
581  * Action method following last select call.
582  * This implementation does nothing but may be redefined by the derived class.
583  *
584  * \param mask file descriptor mask
585  */
586  virtual void actionSelect(const JFileDescriptorMask& mask)
587  {}
588 
589 
590  /**
591  * This method is repeatedly called when this client machine is in state Running
592  * and the clock interval time is non-zero.
593  * This implementation does nothing but may be redefined by the derived class.
594  * Care has to be taken so that the time needed to execute this method should be
595  * less than the specified clock interval time (see method setClockInterval()).
596  */
597  virtual void actionRunning()
598  {}
599 
600 
601  /**
602  * This method is called at <tt>ev_input</tt>.
603  *
604  * \param length length of data
605  * \param buffer pointer to data
606  */
607  virtual void actionInput(int length, const char* buffer)
608  {
609  using namespace std;
610 
611  JProperties properties(JEquationParameters("=", ";", "", ""), 1);
612 
613  int level = this->logger.getLevel();
614 
615  properties["debug"] = level;
616 
617  properties.read(string(buffer, length));
618 
619  this->logger.setLevel(level);
620  }
621 
622 
623  /**
624  * Filter message.
625  * The filter method can be overwritten so that a specific action is made
626  * before the corresponding message is processed by the state machine.
627  * The message is ignored if true is returned, else it is normally processed.
628  *
629  * \param tag tag
630  * \param length number of characters
631  * \param buffer message
632  * \return skip message or not
633  */
634  virtual bool filter(const JTag& tag, int length, const char* buffer)
635  {
636  return false;
637  }
638 
639 
640  /**
641  * This method is called when a custom tag is encountered.
642  *
643  * \param tag tag
644  * \param length length of data
645  * \param buffer pointer to data
646  */
647  virtual void actionTagged(const JTag& tag, int length, const char* buffer)
648  {
649  }
650 
651 
652  /**
653  * Run as run control client following command messages via JNET::JControlHost.
654  * This method can be called once the state machine is entered.
655  * It returns when the state machine is exited.
656  * If the clock interval is non-zero, the method actionRunning() is
657  * repeatedly called when this client machine is in state Running.
658  * The file descriptor mask can be set to interrupt the timeout of
659  * the select call and clock method wait() in this calling sequence
660  * (see methods setSelect() and actionSelect()).
661  */
662  void run()
663  {
664  using namespace std;
665 
666  while (active()) {
667 
668  try {
669 
670  setSelect();
671 
672  if (select(JTimeval(TIMEOUT_S,0)) > 0) {
673 
674  if (select.hasReaderMask(*server)) {
675  update();
676  }
677 
678  actionSelect(select.getReaderMask());
679 
680  } else {
681 
682  continue;
683  }
684 
685 
686  if (isRunning() && clock.getInterval() != 0LL) {
687 
688  long long int numberOfCalls = 0;
689 
690  clock.reset();
691 
692  do {
693 
694  ++numberOfCalls;
695 
696  setSelect();
697 
698  if (clock.wait(select.getReaderMask())) {
699 
700  if (select.hasReaderMask(*server)) {
701  update();
702  }
703 
704  actionSelect(select.getReaderMask());
705 
706  } else {
707 
708  try {
709  actionRunning();
710  }
711  catch(const exception& error) {
712  logger.error(error.what());
713  }
714  }
715 
716  } while (isRunning());
717 
718  if (numberOfCalls != 0) {
719  JNoticeStream(logger) << "Delay per call " << clock.getDelay() / numberOfCalls / 1000 << " ms";
720  }
721  }
722  }
723  catch(const exception& error) {
724  JErrorStream(logger) << "method run(): " << error.what();
725  }
726  }
727  }
728 
729 
730  /**
731  * Run for ever.
732  * This method can be used when the run control client is started before the run control
733  * (e.g.\ at boot time of the host processor).
734  * This method should be called before the state machine is entered.
735  * It launches a server which accepts a JNET::JControlHost connection from
736  * a designated application e.g.\ the JDAQClientStarter.cc program.
737  * The state machine is entered using the available data in the JNET::JControlHost message.
738  * After the state machine is exited, it accepts a new a JNET::JControlHost connection.
739  *
740  * \param port port number
741  */
742  void run(const int port)
743  {
744  JControlHostServer local_server(port);
745 
746  for ( ; ; ) {
747 
748  JControlHost* ps = local_server.AcceptClient();
749 
750  ps->Connected();
751 
752  JNET::JPrefix prefix;
753 
754  ps->WaitHead(prefix);
755 
756  const int length = prefix.getSize();
757 
758  char* buffer = new char[length];
759 
760  ps->GetFullData(buffer, length);
761  ps->PutFullData(prefix.toString(), buffer, length);
762 
763  delete ps;
764 
765  enter(JArgs(std::string(buffer, length)));
766 
767  delete [] buffer;
768 
769  run();
770 
771  exit();
772  }
773  }
774 
775 
776  /**
777  * Run client with commands from input stream (e.g.\ for debugging).
778  *
779  * Example input format:
780  * <pre>
781  * <tag> <event name>[\#data];
782  * <tag> <event name>[\#data];
783  * </pre>
784  *
785  * \param in input stream
786  */
787  void run(std::istream& in)
788  {
789  using namespace std;
790 
791  string tag;
792  string buffer;
793 
794  while (in >> tag && in >> skipws && getline(in, buffer, ';')) {
795  update(tag, buffer.length(), buffer.data());
796  }
797  }
798 
799  protected:
800 
802  JMessageLogger logger; //!< message logger
803 
804  private:
805  /**
806  * Update state machine.
807  * This method waits for a message from JNET::JControlHost server.
808  */
809  void update()
810  {
811  JNET::JPrefix prefix;
812 
813  server->WaitHead(prefix);
814 
815  const int length = prefix.getSize();
816 
817  char* buffer = new char[length];
818 
819  server->GetFullData(buffer, length);
820 
821  update(prefix.getTag(), length, buffer);
822 
823  delete [] buffer;
824  }
825 
826 
827  /**
828  * Update state machine.
829  *
830  * \param tag tag
831  * \param length number of characters
832  * \param buffer message
833  */
834  void update(const JTag& tag, int length, const char* buffer)
835  {
836  using namespace std;
837  using namespace JPP;
838 
839  if (filter(tag, length, buffer)) {
840  return;
841  }
842 
843  if (getSubscription(eventTable)->count(JSubscriptionAny(tag)) == 0 &&
844  getSubscription(eventTable)->count(JSubscriptionAll(tag)) == 0) {
845 
846  actionTagged(tag, length, buffer);
847 
848  return;
849  }
850 
851 
852  string::size_type pos = 0;
853 
854  while (pos != (string::size_type) length && TOKEN_DELIMETER.find(*(buffer + pos)) == string::npos) {
855  ++pos;
856  }
857 
858  const JEvent_t event = JEvent_t::toValue(string(buffer, pos));
859 
860  setEventNumber(event.getNumber());
861 
862  while (pos != (string::size_type) length && TOKEN_DELIMETER.find(*(buffer + pos)) != string::npos) {
863  ++pos;
864  }
865 
866 
867  JEventTable::const_iterator i = eventTable.find(tag, event.getName());
868 
869  if (i != eventTable.end()) {
870 
871  const CHSM::state* const s0 = getState();
872 
873  if (!i->second->active()) {
874 
875  JWarningStream(logger) << "Event " << i->second->name() << " not active (" << (s0 != NULL ? s0->name() : "") << ")";
876 
877  if (server.is_valid() && s0 != NULL) {
878  server->PutFullString(RC_FAIL, getMessage(*s0, *i->second));
879  }
880  }
881 
882  // redirect all I/O
883 
884  {
885  JDebugStream debug(logger);
886  JErrorStream error(logger);
887 
888  JRedirectStream rs_cin (cin, JLANG::null);
889  JRedirectStream rs_cout(cout, debug);
890  JRedirectStream rs_cerr(cerr, error);
891 
892  if (rs_cin &&
893  rs_cout &&
894  rs_cerr) {
895 
896  (*(i->second))(length - pos, buffer + pos);
897  }
898  }
899 
900  const CHSM::state* const s1 = getState();
901 
902  JStatusStream(logger) << "Transition "
903  << (s0 != NULL ? s0->name() : "")
904  << "->(" << i->second->name() << ")->"
905  << (s1 != NULL ? s1->name() : "");
906  } else {
907 
908  JErrorStream(logger) << "Unknown key <" << tag << "," << event.getName() << ">";
909  }
910  }
911 
912 
913  /**
914  * Configure client.
915  * This method is used to setup the event table.
916  */
917  void configure()
918  {
919  }
920 
921 
922  /**
923  * Get event message.
924  *
925  * \param state state
926  * \param event event
927  * \return message
928  */
929  std::string getMessage(const CHSM::state& state, const CHSM::event& event) const
930  {
931  std::ostringstream os;
932 
933  os << getFullName()
934  << getTokenDelimeter()
935  << JEvent_t(event.name(), event_number)
936  << getTokenDelimeter()
937  << getStateName(state.name());
938 
939  return os.str();
940  }
941 
942 
943  /**
944  * Action when entering state.
945  * This method provides for the hand shaking with the run control program.
946  *
947  * \param state entered state
948  * \param event event that triggered transition
949  */
950  virtual void enterState(const CHSM::state& state, const CHSM::event& event)
951  {
952  if (server.is_valid()) {
953  server->PutFullString(RC_REPLY, getMessage(state, event));
954  }
955  }
956 
957 
958  /**
959  * This method is called at <tt>ev_check</tt> and reports a system check by mimicing an enter state action.
960  *
961  * \param length number of characters
962  * \param buffer message
963  */
964  virtual void actionCheck(int length, const char* buffer)
965  {
966  if (Main.RunControl.Error.active()) {
967 
968  enterState(Main.RunControl.Error, ev_check);
969 
970  } else {
971 
972  for (CHSM::parent::iterator state = Main.RunControl.Operational.begin(); state != Main.RunControl.Operational.end(); ++state) {
973 
974  if (state->active()) {
975 
976  // mimic enter state
977 
978  enterState(*state, ev_check);
979  }
980  }
981  }
982  }
983 
984 
985  /**
986  * The method to execute the action.
987  *
988  * \param __action pointer to action method
989  * \param __event event that triggered the action
990  */
991  void execute(action __action, const CHSM::event& __event)
992  {
993  try {
994 
995  const JDAQStateMachine::ev_daq_event& event = dynamic_cast<const JDAQStateMachine::ev_daq_event&>(__event);
996 
997  (this->*__action)(event->length, event->buffer);
998  }
999  catch(const std::exception& error) {
1000  JErrorStream(logger) << "Error at event " << __event.name() << " \"" << error.what() << "\"; trigger ev_error.";
1001  ev_error();
1002  }
1003  }
1004 
1005 
1006  /**
1007  * Get current state.
1008  *
1009  * \return state
1010  */
1011  const CHSM::state* getState() const
1012  {
1013  for (CHSM::parent::const_iterator state = Main.RunControl.Operational.begin(); state != Main.RunControl.Operational.end(); ++state) {
1014  if (state->active()) {
1015  return &(*state);
1016  }
1017  }
1018 
1019  if (Main.RunControl.Error.active()) {
1020  return &Main.RunControl.Error;
1021  }
1022 
1023  return NULL;
1024  }
1025 
1026 
1027  JSelectReader select; //!< select call
1028  JParser<> parser; //!< parser method enter()
1029  JSubscriptionList subscription; //!< custom subscription
1030  };
1031 }
1032 
1033 #endif
set Main(RunControl, Responder) is
Definition: JDAQCHSM.chsm:188
JParser parser
parser method enter()
Definition: JDAQClient.hh:1028
ControlHost prefix.
Definition: JPrefix.hh:31
Utility class to parse command line options.
Definition: JParser.hh:1517
long long int getClockDelay() const
Get total delay time.
Definition: JDAQClient.hh:142
bool read(const JEquation &equation)
Read equation.
Definition: JProperties.hh:677
JDAQStateMachine::ev_start_event ev_start
JDAQEvent_t * findEvent(const JTag &tag, const std::string &event_name)
Find event in event table.
Definition: JDAQClient.hh:508
JDAQStateMachine::ev_configure_event ev_configure
JTimekeeper clock
central clock
Definition: JDAQClient.hh:207
ControlHost class.
void resetClock()
Reset clock.
Definition: JDAQClient.hh:174
JDAQStateMachine::ev_pause_event ev_pause
Message logging based on std::ostream.
JDAQStateMachine::ev_continue_event ev_continue
virtual void setSelect(JFileDescriptorMask &mask) const
Set the file descriptor mask for the select call.
Definition: JDAQClient.hh:576
int Connected()
Send version.
JTag getUniqueTag(const std::string &hostname, const std::string &name)
Get unique tag of run control client.
JDAQStateMachine::ev_reset_event ev_reset
JSelectReader select
select call
Definition: JDAQClient.hh:1027
Message reporting compatible with STL output stream operations.
long long int getClockInterval() const
Get interval time.
Definition: JDAQClient.hh:154
int getEventNumber() const
Get last event number.
Definition: JDAQClient.hh:185
Auxiliary data structure for DAQ client data.
Definition: JDAQClient.hh:60
std::string toString() const
Convert subscription list to string.
Interface for logging messages.
Definition: JLogger.hh:22
Message logging based on ControlHost.
then echo Enter input within $TIMEOUT_S seconds echo n User name
Definition: JCookie.sh:42
Utility class to parse parameter values.
Definition: JProperties.hh:496
void setClockInterval(const long long int interval_us)
Set interval time.
Definition: JDAQClient.hh:165
JDAQClient(const std::string &name)
Constructor.
Definition: JDAQClient.hh:348
exit
Definition: JPizza.sh:36
Simple data structure to support I/O of equations (see class JLANG::JEquation).
Time keeper.
Definition: JTimekeeper.hh:34
then usage $script< detector file >< detectorfile > nIf the range of floors is the first detector file is aligned to the second before the comparison nIn this
Jpp environment information.
virtual void enterState(const CHSM::state &state, const CHSM::event &event)
Action when entering state.
Definition: JDAQClient.hh:950
void configure()
Configure client.
Definition: JDAQClient.hh:917
JSharedPointer< JControlHost > server
message server
Definition: JDAQClient.hh:801
void replaceEvent(const JTag &oldTag, const JTag &newTag, JDAQEvent_t &event)
Replace tag of given event in event table.
Definition: JDAQClient.hh:493
static const std::string TOKEN_DELIMETER
Definition: JDAQTags.hh:36
void execute(action __action, const CHSM::event &__event)
The method to execute the action.
Definition: JDAQClient.hh:991
void run()
Run as run control client following command messages via JNET::JControlHost.
Definition: JDAQClient.hh:662
JDAQStateMachine::ev_init_event ev_init
virtual bool filter(const JTag &tag, int length, const char *buffer)
Filter message.
Definition: JDAQClient.hh:634
bool is_valid() const
Check validity of pointer.
int getSize() const
Get size.
Definition: JPrefix.hh:62
Subscription list.
Utility class to parse parameter values.
JDAQClient_t(JDAQStateMachine *chsm)
Constructor.
Definition: JDAQClient.hh:70
static JEvent_t toValue(const std::string &buffer)
Convert string to event.
Auxiliary class for time values.
Definition: JTimeval.hh:26
void run(const int port)
Run for ever.
Definition: JDAQClient.hh:742
JDAQStateMachine::ev_stop_event ev_stop
std::string getStateName(const std::string &name)
Get name of state.
const CHSM::state * getState() const
Get current state.
Definition: JDAQClient.hh:1011
Scheduling of actions via fixed latency intervals.
std::string getGITVersion(const std::string &tag)
Get GIT version for given GIT tag.
The template JSharedPointer class can be used to share a pointer to an object.
This class can be used to temporarily redirect one output (input) stream to another output (input) st...
static const JNET::JTag RC_REPLY
Definition: JDAQTags.hh:45
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1993
virtual bool enter()
Enter the state machine.
Definition: JDAQClient.hh:419
do set_variable OUTPUT_DIRECTORY $WORKDIR T
virtual void actionRunning()
This method is repeatedly called when this client machine is in state Running and the clock interval ...
Definition: JDAQClient.hh:597
Auxiliary class for method select.
Wrapper class for select call.
Auxiliary class for any subscription.
then awk string
virtual void actionTagged(const JTag &tag, int length, const char *buffer)
This method is called when a custom tag is encountered.
Definition: JDAQClient.hh:647
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
static const JTag DISPTAG_UNDEFINED(0)
Auxiliary class for handling event name and optional number.
Level specific message streamers.
void setEventNumber(const int event_number)
Set last event number.
Definition: JDAQClient.hh:196
Exception for ControlHost.
Definition: JException.hh:468
virtual bool exit()
Exit the state machine.
Definition: JDAQClient.hh:457
Data structure to store command line arguments.
Definition: JArgs.hh:24
char getTokenDelimeter()
Get the token delimeter for command messages.
bool isRunning() const
Check if this client is in runnig state.
Definition: JDAQClient.hh:480
Auxiliary class for all subscription.
Definition: JControlHost.hh:97
void update(const JTag &tag, int length, const char *buffer)
Update state machine.
Definition: JDAQClient.hh:834
JSubscriptionList subscription
custom subscription
Definition: JDAQClient.hh:1029
JControlHost * AcceptClient(JTimeval timeout=JTimeval::max())
Accept new client.
const std::string & getHostname() const
Get hostname.
Definition: JDAQClient.hh:109
const JTag & getTag() const
Get tag.
Definition: JTag.hh:86
std::string getHostname()
Get host name.
Definition: JNetwork.hh:77
void update()
Update state machine.
Definition: JDAQClient.hh:809
JDAQStateMachine::ev_check_event ev_check
int event_number
number of last event
Definition: JDAQClient.hh:208
int WaitHead(JPrefix &prefix)
Wait for header.
void addParameter(const char option, T &parameter, const T &value)
Add parameter to parser used in method enter().
Definition: JDAQClient.hh:551
void addParameter(const char option, T &parameter)
Add parameter to parser used in method enter().
Definition: JDAQClient.hh:537
virtual void actionInput(int length, const char *buffer)
This method is called at ev_input.
Definition: JDAQClient.hh:607
std::string toString() const
Convert tag to string.
Definition: JTag.hh:171
General purpose message reporting.
JEventTable eventTable
event table
Definition: JDAQClient.hh:203
JDAQStateMachine::ev_quit_event ev_quit
int GetFullData(void *buffer, long long int length)
Receive data.
const std::string & getFullName() const
Get full name of this run control client.
Definition: JDAQClient.hh:120
JDAQStateMachine::ev_input_event ev_input
Control unit client base class.
Definition: JDAQClient.hh:273
Utility class to parse command line options.
event< ev_daq > ev_check
Definition: JDAQCHSM.chsm:183
void run(std::istream &in)
Run client with commands from input stream (e.g. for debugging).
Definition: JDAQClient.hh:787
ControlHost subscription.
Definition: JControlHost.hh:50
std::string getMessage(const CHSM::state &state, const CHSM::event &event) const
Get event message.
Definition: JDAQClient.hh:929
JSubscriptionList getSubscription(const JEventTable &event_table)
Convert event table to ControlHost subscription.
Definition: JEventTable.hh:129
virtual bool enter(const JArgs &args)
Enter the state machine.
Definition: JDAQClient.hh:364
const JTag & getUniqueTag() const
Get unique tag of this run control client.
Definition: JDAQClient.hh:131
JDAQClient(const std::string &name, const std::string &server, JLogger *logger, const int level)
Constructor.
Definition: JDAQClient.hh:291
const char * getName()
Get ROOT name of given data type.
Definition: JRootToolkit.hh:57
JMessageLogger logger
message logger
Definition: JDAQClient.hh:802
Fixed parameters andd ControlHost tags for KM3NeT DAQ.
static const JNET::JTag RC_CMD
Definition: JDAQTags.hh:44
static int WhereIs(const std::string &host_name, const std::string &nick_name, std::string &answer)
Locate ControlHost client(s).
ControlHost tag.
Definition: JTag.hh:38
JDAQStateMachine::ev_off_event ev_off
const std::string & getName() const
Get name of state machine.
Definition: JDAQCHSM.chsm:78
std::string getFullName(const std::string &hostname, const std::string &name)
Get full name of run control client.
static JNullStream null
Null I/O stream.
Definition: JNullStream.hh:51
void setSelect()
Set the file descriptor mask for the select call.
Definition: JDAQClient.hh:560
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
static const JNET::JTag RC_FAIL
Definition: JDAQTags.hh:46
int PutFullData(const JTag &tag, const void *buffer, const long long int length)
Send data.
Hostname and IP address functions.
virtual void actionSelect(const JFileDescriptorMask &mask)
Action method following last select call.
Definition: JDAQClient.hh:586
void addSubscription(const JSubscription &subscription)
Add custom subscription.
Definition: JDAQClient.hh:524
virtual void actionCheck(int length, const char *buffer)
This method is called at ev_check and reports a system check by mimicing an enter state action...
Definition: JDAQClient.hh:964
static void Throw(const bool option)
Enable/disable throw option.
Definition: JThrow.hh:37
int debug
debug level
Light-weight wrapper class around server socket.
JDAQStateMachine::ev_recover_event ev_recover
JDAQClient(const std::string &name, JLogger *logger, const int level)
Constructor.
Definition: JDAQClient.hh:329