otsdaq  v2_04_01
FEVInterface.h
1 #ifndef _ots_FEVInterface_h_
2 #define _ots_FEVInterface_h_
3 
4 #define TRACE_NAME "FEVInterface"
5 #include "artdaq/DAQdata/Globals.hh"
6 
7 #include "otsdaq-core/Configurable/Configurable.h"
8 #include "otsdaq-core/FECore/FESlowControlsWorkLoop.h"
9 #include "otsdaq-core/FiniteStateMachine/VStateMachine.h"
10 #include "otsdaq-core/WorkLoopManager/WorkLoop.h"
11 
12 #include "otsdaq-core/CoreSupervisors/CoreSupervisorBase.h"
13 
14 #include "otsdaq-core/SupervisorInfo/AllSupervisorInfo.h" //to send errors to Gateway, e.g.
15 
16 #include "otsdaq-core/CoreSupervisors/FESupervisor.h"
17 
18 #include "otsdaq-core/FECore/FESlowControlsChannel.h"
19 #include "otsdaq-core/SOAPUtilities/SOAPMessenger.h" //for xdaq::ApplicationDescriptor communication
20 
21 #include <array>
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 
26 #include "otsdaq-core/Macros/CoutMacros.h"
27 
28 #define __ARGS__ \
29  const frontEndMacroStruct_t & feMacroStruct, \
30  FEVInterface::frontEndMacroConstArgs_t argsIn, \
31  FEVInterface::frontEndMacroArgs_t argsOut
32 
33 #define __GET_ARG_IN__(X, Y) getFEMacroConstArgumentValue<Y>(argsIn, X)
34 #define __GET_ARG_OUT__(X, Y) getFEMacroArgumentValue<Y>(argsOut, X)
35 
36 #define __SET_ARG_IN__(X, Y) FEVInterface::emplaceFEMacroArgumentValue(argsIn, X, Y)
37 #define __SET_ARG_OUT__(X, Y) FEVInterface::setFEMacroArgumentValue(argsOut, X, Y)
38 
39 namespace ots
40 {
41 // class SlowControlsChannelInfo;
42 class FEVInterfacesManager;
43 
44 // FEVInterface
45 // This class is a virtual class defining the features of front-end interface plugin
46 // class. The features include configuration hooks, finite state machine handlers,
47 // Front-end Macros for web accessible C++ handlers, slow controls hooks, as well as
48 // universal write and read for Macro Maker compatibility.
49 //
50 // It inherits workloop as 'public virtual' for the case that other classes like
51 // DataProducer will also be inherited by child class and only one workloop is
52 // desired.
53 class FEVInterface : public VStateMachine, public WorkLoop, public Configurable
54 {
55  friend class FEVInterfacesManager;
56 
57  public:
58  FEVInterface(const std::string& interfaceUID,
59  const ConfigurationTree& theXDAQContextConfigTree,
60  const std::string& configurationPath);
61 
62  virtual ~FEVInterface(void);
63 
64  FEVInterfacesManager* parentInterfaceManager_;
65 
66  const std::string& getInterfaceUID(void) const { return interfaceUID_; }
67  virtual std::string getInterfaceType(void) const
68  {
69  return theXDAQContextConfigTree_.getBackNode(theConfigurationPath_)
70  .getNode("FEInterfacePluginName")
71  .getValue<std::string>();
72  } // interfaceType_;}
73 
74  virtual void universalRead(
75  char* address,
76  char* returnValue) = 0; // throw std::runtime_error exception on error/timeout
77  virtual void universalWrite(char* address, char* writeValue) = 0;
78  const unsigned int& getUniversalAddressSize(void) { return universalAddressSize_; }
79  const unsigned int& getUniversalDataSize(void) { return universalDataSize_; }
80 
81  void runSequenceOfCommands(const std::string& treeLinkName);
82 
83  static void sendAsyncErrorToGateway(FEVInterface* fe,
84  const std::string& errMsg,
85  bool isSoftError);
86 
88  // start State Machine handlers
89  void configure(void)
90  {
91  __COUT__ << "\t Configure" << std::endl;
92  runSequenceOfCommands(
93  "LinkToConfigureSequence"); /*Run Configure Sequence Commands*/
94  }
95  void start(std::string runNumber)
96  {
97  __COUT__ << "\t Start" << std::endl;
98  runSequenceOfCommands("LinkToStartSequence"); /*Run Start Sequence Commands*/
99  }
100  void stop(void)
101  {
102  __COUT__ << "\t Stop" << std::endl;
103  runSequenceOfCommands("LinkToStopSequence"); /*Run Stop Sequence Commands*/
104  }
105  void halt(void) { stop(); }
106  void pause(void) { stop(); }
107  void resume(void) { start(""); }
108  bool running(void) { /*while(WorkLoop::continueWorkLoop_){;}*/ return false; }
109  // end State Machine handlers
111 
113  // start Slow Controls
114  void configureSlowControls(void);
115  bool slowControlsRunning(void); // slow controls workloop calls this
116  void startSlowControlsWorkLooop(void) { slowControlsWorkLoop_.startWorkLoop(); }
117  void stopSlowControlsWorkLooop(void) { slowControlsWorkLoop_.stopWorkLoop(); }
118  // end Slow Controls
120 
122  // start FE Macros
123 
124  // public types and functions for map of FE macros
125  using frontEndMacroArg_t =
126  std::pair<const std::string /* arg name */, std::string /* arg return value */>;
127  using frontEndMacroArgs_t = std::vector<frontEndMacroArg_t>&;
128  using frontEndMacroConstArgs_t = const std::vector<frontEndMacroArg_t>&;
129  struct frontEndMacroStruct_t; // declare name for __ARGS__
130  using frontEndMacroFunction_t = void (ots::FEVInterface::*)(
131  __ARGS__); // void function (vector-of-inputs, vector-of-outputs)
132  struct frontEndMacroStruct_t // members fully define a front-end macro function
133  {
135  const std::string& feMacroName,
136  const frontEndMacroFunction_t& feMacroFunction,
137  const std::vector<std::string>& namesOfInputArgs,
138  const std::vector<std::string>& namesOfOutputArgs,
139  const uint8_t requiredUserPermissions = 1 /*1:=user,255:=admin*/,
140  const std::string& allowedCallingFrontEnds =
141  "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/)
142  : feMacroName_(feMacroName)
143  , macroFunction_(feMacroFunction)
144  , namesOfInputArguments_(namesOfInputArgs)
145  , namesOfOutputArguments_(namesOfOutputArgs)
146  , requiredUserPermissions_(requiredUserPermissions)
147  , allowedCallingFrontEnds_(allowedCallingFrontEnds)
148  {
149  }
150 
151  const std::string feMacroName_;
152  const frontEndMacroFunction_t
153  macroFunction_; // Note: must be called using this instance
154  const std::vector<std::string> namesOfInputArguments_, namesOfOutputArguments_;
155  const uint8_t requiredUserPermissions_;
156  const std::string allowedCallingFrontEnds_;
157  };
158  const std::map<std::string, frontEndMacroStruct_t>& getMapOfFEMacroFunctions(void)
159  {
160  return mapOfFEMacroFunctions_;
161  }
162  void runSelfFrontEndMacro(
163  const std::string& feMacroName,
164  const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs,
165  std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs);
166  // end FE Macros
168 
170  // start Macros
172  {
173  macroStruct_t(const std::string& macroString);
174 
175  enum
176  {
177  OP_TYPE_READ,
178  OP_TYPE_WRITE,
179  OP_TYPE_DELAY,
180  };
181 
182  struct readOp_t
183  {
184  uint64_t address_;
185  bool addressIsVar_;
186  std::string addressVarName_;
187  bool dataIsVar_;
188  std::string dataVarName_;
189  }; // end macroStruct_t::writeOp_t declaration
190 
191  struct writeOp_t
192  {
193  uint64_t address_;
194  bool addressIsVar_;
195  std::string addressVarName_;
196  uint64_t data_;
197  bool dataIsVar_;
198  std::string dataVarName_;
199  }; // end macroStruct_t::writeOp_t declaration
200 
201  struct delayOp_t
202  {
203  uint64_t delay_; // milliseconds
204  bool delayIsVar_;
205  std::string delayVarName_;
206  }; // end macroStruct_t::writeOp_t declaration
207 
208  std::string macroName_;
209  std::vector<std::pair<unsigned int /*op type*/,
210  unsigned int /*index in specific type vector*/> >
211  operations_;
212  std::vector<macroStruct_t::readOp_t> readOps_;
213  std::vector<macroStruct_t::writeOp_t> writeOps_;
214  std::vector<macroStruct_t::delayOp_t> delayOps_;
215  std::set<std::string> namesOfInputArguments_, namesOfOutputArguments_;
216  bool lsbf_; // least significant byte first
217  }; // end macroStruct_t declaration
218  protected:
219  void runMacro(FEVInterface::macroStruct_t& macro,
220  std::map<std::string /*name*/, uint64_t /*value*/>& variableMap);
221 
222  public:
223  // end FE Macros
225 
227  // start FE communication helpers
228 
229  template<class T>
230  void sendToFrontEnd(const std::string& targetInterfaceID, const T& value) const;
231  void runFrontEndMacro(
232  const std::string& targetInterfaceID,
233  const std::string& feMacroName,
234  const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs,
235  std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs) const;
236 
238  // receiveFromFrontEnd
239  // * can be used for source interface ID to accept a message from any front-end
240  // NOTE: can not overload functions based on return type, so T& passed as value
241  template<class T>
242  void receiveFromFrontEnd(const std::string& requester,
243  T& retValue,
244  unsigned int timeoutInSeconds = 1) const;
245  // specialized template function for T=std::string
246  void receiveFromFrontEnd(const std::string& requester,
247  std::string& retValue,
248  unsigned int timeoutInSeconds = 1) const;
249  // NOTE: can not overload functions based on return type, so calls function with T&
250  // passed as value
251  template<class T>
252  T receiveFromFrontEnd(const std::string& requester = "*",
253  unsigned int timeoutInSeconds = 1) const;
254  // specialized template function for T=std::string
255  std::string receiveFromFrontEnd(const std::string& requester = "*",
256  unsigned int timeoutInSeconds = 1) const;
257 
258  // end FE Communication helpers
260 
261  protected:
262  bool workLoopThread(toolbox::task::WorkLoop* workLoop);
263  std::string interfaceUID_;
264 
265  unsigned int universalAddressSize_ = 0;
266  unsigned int universalDataSize_ = 0;
267 
268  // Controls members
269  std::map<std::string, FESlowControlsChannel> mapOfSlowControlsChannels_;
270  FESlowControlsWorkLoop slowControlsWorkLoop_;
271 
272  // FE Macro Function members and helper functions:
273 
274  std::map<std::string, frontEndMacroStruct_t>
275  mapOfFEMacroFunctions_; // Map of FE Macro functions members
276  void registerFEMacroFunction(
277  const std::string& feMacroName,
278  frontEndMacroFunction_t feMacroFunction,
279  const std::vector<std::string>& namesOfInputArgs,
280  const std::vector<std::string>& namesOfOutputArgs,
281  uint8_t requiredUserPermissions = 1 /*1:=user,255:=admin*/,
282  const std::string& allowedCallingFEs =
283  "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/);
284 
285  public: // for external specialized template access
286  static const std::string& getFEMacroConstArgument(frontEndMacroConstArgs_t args,
287  const std::string& argName);
288  static std::string& getFEMacroArgument(frontEndMacroArgs_t args,
289  const std::string& argName);
290 
291  protected:
292  template<class T>
293  std::string& setFEMacroArgumentValue(frontEndMacroArgs_t args,
294  const std::string& argName,
295  const T& value) const;
296  // {
297  // //modify existing pair
298  // std::string& arg = getFEMacroArgument(args,argName);
299  // std::stringstream ss; ss << value;
300  // arg = ss.str();
301  // return arg;
302  // }
303  template<class T>
304  std::string& emplaceFEMacroArgumentValue(frontEndMacroArgs_t args,
305  const std::string& argName,
306  const T& value) const;
307  // {
308  // //insert new pair
309  // std::stringstream ss; ss << value;
310  // args.push_back(frontEndMacroArg_t(argName, ss.str()));
311  // return args.back().second;
312  // }
313 
314 }; // end FEVInterface class
315 
316 template<class T>
317 T getFEMacroConstArgumentValue(FEVInterface::frontEndMacroConstArgs_t args,
318  const std::string& argName);
319 // specialized template version of getFEMacroConstArgumentValue for string
320 template<>
321 std::string getFEMacroConstArgumentValue<std::string>(
322  FEVInterface::frontEndMacroConstArgs_t args, const std::string& argName);
323 
324 template<class T>
325 T getFEMacroArgumentValue(FEVInterface::frontEndMacroArgs_t args,
326  const std::string& argName);
327 
328 // specialized template version of getFEMacroArgumentValue for string
329 template<>
330 std::string getFEMacroArgumentValue<std::string>(FEVInterface::frontEndMacroArgs_t argsIn,
331  const std::string& argName);
332 
333 // include template definitions required at include level for compiler
334 #include "otsdaq-core/FECore/FEVInterface.icc"
335 
336 } // namespace ots
337 
338 #endif