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