otsdaq  v2_04_02
FESupervisor.cc
1 #include "otsdaq/CoreSupervisors/FESupervisor.h"
2 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
3 #include "otsdaq/FECore/FEVInterfacesManager.h"
4 
5 #include "artdaq/DAQdata/Globals.hh" // instantiates artdaq::Globals::metricMan_
6 
7 // https://cdcvs.fnal.gov/redmine/projects/artdaq/repository/revisions/develop/entry/artdaq/DAQdata/Globals.hh
8 // for metric manager include
9 // https://cdcvs.fnal.gov/redmine/projects/artdaq/repository/revisions/develop/entry/artdaq/Application/DataReceiverCore.cc
10 // for metric manager configuration example
11 
12 // get pset from Board Reader metric manager table
13 // try
14 // {
15 // metricMan->initialize(metric_pset, app_name);
16 // }
17 // catch (...)
18 // {
19 // ExceptionHandler(ExceptionHandlerRethrow::no,
20 // "Error loading metrics in
21 // DataReceiverCore::initialize()");
22 // }
23 //..
24 //
25 // metricMan->do_start();
26 // ..
27 // metricMan->shutdown();
28 
29 using namespace ots;
30 
31 XDAQ_INSTANTIATOR_IMPL(FESupervisor)
32 
33 //========================================================================================================================
34 FESupervisor::FESupervisor(xdaq::ApplicationStub* stub) : CoreSupervisorBase(stub)
35 {
36  __SUP_COUT__ << "Constructing..." << __E__;
37 
38  xoap::bind(this,
39  &FESupervisor::macroMakerSupervisorRequest,
40  "MacroMakerSupervisorRequest",
41  XDAQ_NS_URI);
42 
43  xoap::bind(
44  this, &FESupervisor::workLoopStatusRequest, "WorkLoopStatusRequest", XDAQ_NS_URI);
45 
46  xoap::bind(this,
47  &FESupervisor::frontEndCommunicationRequest,
48  "FECommunication",
49  XDAQ_NS_URI);
50 
51  try
52  {
53  CoreSupervisorBase::theStateMachineImplementation_.push_back(
55  CorePropertySupervisorBase::getContextTreeNode(),
56  CorePropertySupervisorBase::getSupervisorConfigurationPath()));
57  }
58  catch(...)
59  {
60  if(CorePropertySupervisorBase::allSupervisorInfo_.isMacroMakerMode())
61  {
62  __SUP_COUT_WARN__ << "Error caught constructing FE Interface Manager. In "
63  "Macro Maker mode, the input fhicl defines the "
64  "configuration tree, make sure you specified a valid "
65  "fcl file path."
66  << __E__;
67  }
68  throw;
69  }
70 
71  extractFEInterfacesManager();
72 
73  __SUP_COUT__ << "Constructed." << __E__;
74 
75  if(CorePropertySupervisorBase::allSupervisorInfo_.isMacroMakerMode())
76  {
77  __SUP_COUT_INFO__ << "Macro Maker mode, so configuring at startup!" << __E__;
78  if(!theFEInterfacesManager_)
79  {
80  __SUP_SS__ << "Missing FE Interface manager!" << __E__;
81  __SUP_SS_THROW__;
82  }
83 
84  // copied from CoreSupervisorBase::transitionConfiguring()
85 
86  // Now that the configuration manager has all the necessary configurations,
87  // create all objects that depend on the configuration (the first iteration)
88 
89  try
90  {
91  __SUP_COUT__ << "Configuring all state machine implementations..." << __E__;
92  preStateMachineExecutionLoop();
93  for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
94  {
95  // if one state machine is doing a sub-iteration, then target that one
96  if(subIterationWorkStateMachineIndex_ != (unsigned int)-1 &&
97  i != subIterationWorkStateMachineIndex_)
98  continue; // skip those not in the sub-iteration
99 
100  if(stateMachinesIterationDone_[i])
101  continue; // skip state machines already done
102 
103  preStateMachineExecution(i);
104  theStateMachineImplementation_[i]->parentSupervisor_ =
105  this; // for backwards compatibility, kept out of configure
106  // parameters
107  theStateMachineImplementation_[i]->configure(); // e.g. for FESupervisor,
108  // this is configure of
109  // FEVInterfacesManager
110  postStateMachineExecution(i);
111  }
112  postStateMachineExecutionLoop();
113  }
114  catch(const std::runtime_error& e)
115  {
116  __SUP_SS__ << "Error was caught while configuring: " << e.what() << __E__;
117  __SUP_COUT_ERR__ << "\n" << ss.str();
118  theStateMachine_.setErrorMessage(ss.str());
119  }
120  catch(...)
121  {
122  __SUP_SS__
123  << "Unknown error was caught while configuring. Please checked the logs."
124  << __E__;
125  __SUP_COUT_ERR__ << "\n" << ss.str();
126  theStateMachine_.setErrorMessage(ss.str());
127  }
128  } // end Macro Maker mode initial configure
129 } // end constructor
130 
131 //========================================================================================================================
132 FESupervisor::~FESupervisor(void)
133 {
134  __SUP_COUT__ << "Destroying..." << __E__;
135  // theStateMachineImplementation_ is reset and the object it points to deleted in
136  // ~CoreSupervisorBase()
137 
138  artdaq::Globals::CleanUpGlobals(); // destruct metricManager (among other things)
139 
140  __SUP_COUT__ << "Destructed." << __E__;
141 } // end destructor
142 
143 //========================================================================================================================
144 xoap::MessageReference FESupervisor::frontEndCommunicationRequest(
145  xoap::MessageReference message) try
146 {
147  __SUP_COUT__ << "FE Request received: " << SOAPUtilities::translate(message) << __E__;
148 
149  if(!theFEInterfacesManager_)
150  {
151  __SUP_SS__ << "No FE Interface Manager!" << __E__;
152  __SUP_SS_THROW__;
153  }
154  SOAPParameters typeParameter, rxParameters; // params for xoap to recv
155  typeParameter.addParameter("type");
156  SOAPUtilities::receive(message, typeParameter);
157 
158  std::string type = typeParameter.getValue("type");
159 
160  // types
161  // feSend
162  // feMacro
163  // feMacroMultiDimensionalStart
164  // macroMultiDimensionalStart
165  // feMacroMultiDimensionalCheck
166  // macroMultiDimensionalCheck
167 
168  rxParameters.addParameter("requester");
169  rxParameters.addParameter("targetInterfaceID");
170 
171  if(type == "feSend")
172  {
173  __SUP_COUTV__(type);
174 
175  rxParameters.addParameter("value");
176  SOAPUtilities::receive(message, rxParameters);
177 
178  std::string requester = rxParameters.getValue("requester");
179  std::string targetInterfaceID = rxParameters.getValue("targetInterfaceID");
180  std::string value = rxParameters.getValue("value");
181 
182  __SUP_COUTV__(requester);
183  __SUP_COUTV__(targetInterfaceID);
184  __SUP_COUTV__(value);
185 
186  // test that the interface exists
187  theFEInterfacesManager_->getFEInterface(targetInterfaceID);
188 
189  // mutex scope
190  {
191  std::lock_guard<std::mutex> lock(
192  theFEInterfacesManager_->frontEndCommunicationReceiveMutex_);
193 
194  theFEInterfacesManager_
195  ->frontEndCommunicationReceiveBuffer_[targetInterfaceID][requester]
196  .emplace(value);
197 
198  __SUP_COUT__ << "Number of target interface ID '" << targetInterfaceID
199  << "' buffers: "
200  << theFEInterfacesManager_
201  ->frontEndCommunicationReceiveBuffer_[targetInterfaceID]
202  .size()
203  << __E__;
204  __SUP_COUT__
205  << "Number of source interface ID '" << requester << "' values received: "
206  << theFEInterfacesManager_
207  ->frontEndCommunicationReceiveBuffer_[targetInterfaceID][requester]
208  .size()
209  << __E__;
210  }
211  return SOAPUtilities::makeSOAPMessageReference("Received");
212  } // end type feSend
213  else if(type == "feMacro")
214  {
215  __SUP_COUTV__(type);
216 
217  rxParameters.addParameter("feMacroName");
218  rxParameters.addParameter("inputArgs");
219 
220  SOAPUtilities::receive(message, rxParameters);
221 
222  std::string requester = rxParameters.getValue("requester");
223  std::string targetInterfaceID = rxParameters.getValue("targetInterfaceID");
224  std::string feMacroName = rxParameters.getValue("feMacroName");
225  std::string inputArgs = rxParameters.getValue("inputArgs");
226 
227  __SUP_COUTV__(requester);
228  __SUP_COUTV__(targetInterfaceID);
229  __SUP_COUTV__(feMacroName);
230  __SUP_COUTV__(inputArgs);
231 
232  std::string outputArgs;
233  try
234  {
235  theFEInterfacesManager_->runFEMacroByFE(
236  requester, targetInterfaceID, feMacroName, inputArgs, outputArgs);
237  }
238  catch(std::runtime_error& e)
239  {
240  __SUP_SS__ << "In Supervisor with LID="
241  << getApplicationDescriptor()->getLocalId()
242  << " the FE Macro named '" << feMacroName << "' with target FE '"
243  << targetInterfaceID << "' failed. Here is the error:\n\n"
244  << e.what() << __E__;
245  __SUP_SS_THROW__;
246  }
247  catch(...)
248  {
249  __SUP_SS__ << "In Supervisor with LID="
250  << getApplicationDescriptor()->getLocalId()
251  << " the FE Macro named '" << feMacroName << "' with target FE '"
252  << targetInterfaceID << "' failed due to an unknown error."
253  << __E__;
254  __SUP_SS_THROW__;
255  }
256 
257  __SUP_COUTV__(outputArgs);
258 
259  xoap::MessageReference replyMessage =
260  SOAPUtilities::makeSOAPMessageReference("feMacrosResponse");
261  SOAPParameters txParameters;
262  txParameters.addParameter("requester", requester);
263  txParameters.addParameter("targetInterfaceID", targetInterfaceID);
264  txParameters.addParameter("feMacroName", feMacroName);
265  txParameters.addParameter("outputArgs", outputArgs);
266  SOAPUtilities::addParameters(replyMessage, txParameters);
267 
268  __SUP_COUT__ << "Sending FE macro result: "
269  << SOAPUtilities::translate(replyMessage) << __E__;
270 
271  return replyMessage;
272  } // end type feMacro
273  else if(type == "feMacroMultiDimensionalStart" || // from iterator
274  type == "macroMultiDimensionalStart") // from iterator
275  {
276  __SUP_COUTV__(type);
277 
278  if(type[0] == 'm')
279  {
280  rxParameters.addParameter("macroString");
281  rxParameters.addParameter("macroName");
282  }
283  else
284  rxParameters.addParameter("feMacroName");
285 
286  rxParameters.addParameter("enableSavingOutput");
287  rxParameters.addParameter("outputFilePath");
288  rxParameters.addParameter("outputFileRadix");
289  rxParameters.addParameter("inputArgs");
290 
291  SOAPUtilities::receive(message, rxParameters);
292 
293  std::string requester = rxParameters.getValue("requester");
294  std::string targetInterfaceID = rxParameters.getValue("targetInterfaceID");
295  std::string macroName, macroString;
296  if(type[0] == 'm')
297  {
298  macroName = rxParameters.getValue("macroName");
299  macroString = rxParameters.getValue("macroString");
300  __SUP_COUTV__(macroString);
301  }
302  else
303  macroName = rxParameters.getValue("feMacroName");
304  bool enableSavingOutput = rxParameters.getValue("enableSavingOutput") == "1";
305  std::string outputFilePath = rxParameters.getValue("outputFilePath");
306  std::string outputFileRadix = rxParameters.getValue("outputFileRadix");
307  std::string inputArgs = rxParameters.getValue("inputArgs");
308 
309  __SUP_COUTV__(requester);
310  __SUP_COUTV__(targetInterfaceID);
311  __SUP_COUTV__(macroName);
312  __SUP_COUTV__(enableSavingOutput);
313  __SUP_COUTV__(outputFilePath);
314  __SUP_COUTV__(outputFileRadix);
315  __SUP_COUTV__(inputArgs);
316 
317  if(type[0] == 'm') // start Macro
318  {
319  try
320  {
321  theFEInterfacesManager_->startMacroMultiDimensional(requester,
322  targetInterfaceID,
323  macroName,
324  macroString,
325  enableSavingOutput,
326  outputFilePath,
327  outputFileRadix,
328  inputArgs);
329  }
330  catch(std::runtime_error& e)
331  {
332  __SUP_SS__ << "In Supervisor with LID="
333  << getApplicationDescriptor()->getLocalId()
334  << " the Macro named '" << macroName << "' with target FE '"
335  << targetInterfaceID
336  << "' failed to start multi-dimensional launch. "
337  << "Here is the error:\n\n"
338  << e.what() << __E__;
339  __SUP_SS_THROW__;
340  }
341  catch(...)
342  {
343  __SUP_SS__ << "In Supervisor with LID="
344  << getApplicationDescriptor()->getLocalId()
345  << " the Macro named '" << macroName << "' with target FE '"
346  << targetInterfaceID
347  << "' failed to start multi-dimensional launch "
348  << "due to an unknown error." << __E__;
349  __SUP_SS_THROW__;
350  }
351  }
352  else // start FE Macro
353  {
354  try
355  {
356  theFEInterfacesManager_->startFEMacroMultiDimensional(requester,
357  targetInterfaceID,
358  macroName,
359  enableSavingOutput,
360  outputFilePath,
361  outputFileRadix,
362  inputArgs);
363  }
364  catch(std::runtime_error& e)
365  {
366  __SUP_SS__ << "In Supervisor with LID="
367  << getApplicationDescriptor()->getLocalId()
368  << " the FE Macro named '" << macroName << "' with target FE '"
369  << targetInterfaceID
370  << "' failed to start multi-dimensional launch. "
371  << "Here is the error:\n\n"
372  << e.what() << __E__;
373  __SUP_SS_THROW__;
374  }
375  catch(...)
376  {
377  __SUP_SS__ << "In Supervisor with LID="
378  << getApplicationDescriptor()->getLocalId()
379  << " the FE Macro named '" << macroName << "' with target FE '"
380  << targetInterfaceID
381  << "' failed to start multi-dimensional launch "
382  << "due to an unknown error." << __E__;
383  __SUP_SS_THROW__;
384  }
385  }
386 
387  xoap::MessageReference replyMessage =
388  SOAPUtilities::makeSOAPMessageReference(type + "Done");
389  SOAPParameters txParameters;
390  // txParameters.addParameter("started", "1");
391  SOAPUtilities::addParameters(replyMessage, txParameters);
392 
393  __SUP_COUT__ << "Sending FE macro result: "
394  << SOAPUtilities::translate(replyMessage) << __E__;
395 
396  return replyMessage;
397  } // end type (fe)MacroMultiDimensionalStart
398  else if(type == "feMacroMultiDimensionalCheck" || // from iterator
399  type == "macroMultiDimensionalCheck")
400  {
401  __SUP_COUTV__(type);
402  if(type[0] == 'm')
403  rxParameters.addParameter("macroName");
404  else
405  rxParameters.addParameter("feMacroName");
406  rxParameters.addParameter("targetInterfaceID");
407 
408  SOAPUtilities::receive(message, rxParameters);
409 
410  std::string targetInterfaceID = rxParameters.getValue("targetInterfaceID");
411  std::string macroName;
412  if(type[0] == 'm')
413  macroName = rxParameters.getValue("macroName");
414  else
415  macroName = rxParameters.getValue("feMacroName");
416 
417  __SUP_COUTV__(targetInterfaceID);
418  __SUP_COUTV__(macroName);
419 
420  bool done = false;
421  try
422  {
423  done = theFEInterfacesManager_->checkMacroMultiDimensional(targetInterfaceID,
424  macroName);
425  }
426  catch(std::runtime_error& e)
427  {
428  __SUP_SS__ << "In Supervisor with LID="
429  << getApplicationDescriptor()->getLocalId()
430  << " the FE Macro named '" << macroName << "' with target FE '"
431  << targetInterfaceID
432  << "' failed to check multi-dimensional launch. "
433  << "Here is the error:\n\n"
434  << e.what() << __E__;
435  __SUP_SS_THROW__;
436  }
437  catch(...)
438  {
439  __SUP_SS__ << "In Supervisor with LID="
440  << getApplicationDescriptor()->getLocalId()
441  << " the FE Macro named '" << macroName << "' with target FE '"
442  << targetInterfaceID
443  << "' failed to check multi-dimensional launch "
444  << "due to an unknown error." << __E__;
445  __SUP_SS_THROW__;
446  }
447 
448  xoap::MessageReference replyMessage =
449  SOAPUtilities::makeSOAPMessageReference(type + "Done");
450  SOAPParameters txParameters;
451  txParameters.addParameter("Done", done ? "1" : "0");
452  SOAPUtilities::addParameters(replyMessage, txParameters);
453 
454  __SUP_COUT__ << "Sending FE macro result: "
455  << SOAPUtilities::translate(replyMessage) << __E__;
456 
457  return replyMessage;
458  } // end type (fe)MacroMultiDimensionalCheck
459  else
460  {
461  __SUP_SS__ << "Unrecognized FE Communication type: " << type << __E__;
462  __SUP_SS_THROW__;
463  }
464 }
465 catch(const std::runtime_error& e)
466 {
467  __SUP_SS__ << "Error encountered processing FE communication request: " << e.what()
468  << __E__;
469  __SUP_COUT_ERR__ << ss.str();
470 
471  SOAPParameters parameters;
472  parameters.addParameter("Error", ss.str());
473  return SOAPUtilities::makeSOAPMessageReference(
474  supervisorClassNoNamespace_ + "FailFECommunicationRequest", parameters);
475 }
476 catch(...)
477 {
478  __SUP_SS__ << "Unknown error encountered processing FE communication request."
479  << __E__;
480  __SUP_COUT_ERR__ << ss.str();
481 
482  SOAPParameters parameters;
483  parameters.addParameter("Error", ss.str());
484  return SOAPUtilities::makeSOAPMessageReference(
485  supervisorClassNoNamespace_ + "FailFECommunicationRequest", parameters);
486 } // end frontEndCommunicationRequest()
487 
488 //========================================================================================================================
489 // macroMakerSupervisorRequest
490 // Handles all MacroMaker Requests:
491 // - GetInterfaces (returns interface type and id)
492 //
493 // Note: this code assumes a CoreSupervisorBase has only one
494 // FEVInterfacesManager in its vector of state machines
495 xoap::MessageReference FESupervisor::macroMakerSupervisorRequest(
496  xoap::MessageReference message)
497 {
498  __SUP_COUT__ << "$$$$$$$$$$$$$$$$$" << __E__;
499 
500  // receive request parameters
501  SOAPParameters parameters;
502  parameters.addParameter("Request");
503 
504  __SUP_COUT__ << "Received Macro Maker message: " << SOAPUtilities::translate(message)
505  << __E__;
506 
507  SOAPUtilities::receive(message, parameters);
508  std::string request = parameters.getValue("Request");
509 
510  __SUP_COUT__ << "request: " << request << __E__;
511 
512  // request types:
513  // GetInterfaces
514  // UniversalWrite
515  // UniversalRead
516  // GetInterfaceMacros
517  // RunInterfaceMacro
518  // RunMacroMakerMacro
519 
520  SOAPParameters retParameters;
521 
522  try
523  {
524  if(request == "GetInterfaces")
525  {
526  if(theFEInterfacesManager_)
527  retParameters.addParameter(
528  "FEList",
529  theFEInterfacesManager_->getFEListString(
530  std::to_string(getApplicationDescriptor()->getLocalId())));
531  else // if no FE interfaces, return empty string
532  retParameters.addParameter("FEList", "");
533 
534  // if errors in state machine, send also
535  if(theStateMachine_.getErrorMessage() != "")
536  retParameters.addParameter("frontEndError",
537  theStateMachine_.getErrorMessage());
538 
539  return SOAPUtilities::makeSOAPMessageReference(
540  supervisorClassNoNamespace_ + "Response", retParameters);
541  }
542  else if(request == "UniversalWrite")
543  {
544  if(!theFEInterfacesManager_)
545  {
546  __SUP_SS__ << "No FE Interface Manager! Are you configured?" << __E__;
547  __SUP_SS_THROW__;
548  }
549  // params for running macros
550  SOAPParameters requestParameters;
551  requestParameters.addParameter("InterfaceID");
552  requestParameters.addParameter("Address");
553  requestParameters.addParameter("Data");
554  SOAPUtilities::receive(message, requestParameters);
555  std::string interfaceID = requestParameters.getValue("InterfaceID");
556  std::string addressStr = requestParameters.getValue("Address");
557  std::string dataStr = requestParameters.getValue("Data");
558 
559  __SUP_COUT__ << "Address: " << addressStr << " Data: " << dataStr
560  << " InterfaceID: " << interfaceID << __E__;
561 
562  // parameters interface index!
563  // unsigned int index = stoi(indexStr); // As long as the supervisor has only
564  // one interface, this index will remain 0?
565 
566  __SUP_COUT__
567  << "theFEInterfacesManager_->getInterfaceUniversalAddressSize(index) "
568  << theFEInterfacesManager_->getInterfaceUniversalAddressSize(interfaceID)
569  << __E__;
570  __SUP_COUT__
571  << "theFEInterfacesManager_->getInterfaceUniversalDataSize(index) "
572  << theFEInterfacesManager_->getInterfaceUniversalDataSize(interfaceID)
573  << __E__;
574 
575  // Converting std::string to char*
576  // char address
577 
578  char tmpHex[3]; // for use converting hex to binary
579  tmpHex[2] = '\0';
580 
581  __SUP_COUT__ << "Translating address: ";
582 
583  std::string addressTmp;
584  addressTmp.reserve(
585  theFEInterfacesManager_->getInterfaceUniversalAddressSize(interfaceID));
586  char* address = &addressTmp[0];
587 
588  if(addressStr.size() % 2) // if odd, make even
589  addressStr = "0" + addressStr;
590  unsigned int i = 0;
591  for(; i < addressStr.size() &&
592  i / 2 < theFEInterfacesManager_->getInterfaceUniversalAddressSize(
593  interfaceID);
594  i += 2)
595  {
596  tmpHex[0] = addressStr[addressStr.size() - 1 - i - 1];
597  tmpHex[1] = addressStr[addressStr.size() - 1 - i];
598  sscanf(tmpHex, "%hhX", (unsigned char*)&address[i / 2]);
599  printf("%2.2X", (unsigned char)address[i / 2]);
600  }
601  // finish and fill with 0s
602  for(; i / 2 <
603  theFEInterfacesManager_->getInterfaceUniversalAddressSize(interfaceID);
604  i += 2)
605  {
606  address[i / 2] = 0;
607  printf("%2.2X", (unsigned char)address[i / 2]);
608  }
609 
610  std::cout << __E__;
611 
612  __SUP_COUT__ << "Translating data: ";
613 
614  std::string dataTmp;
615  dataTmp.reserve(
616  theFEInterfacesManager_->getInterfaceUniversalDataSize(interfaceID));
617  char* data = &dataTmp[0];
618 
619  if(dataStr.size() % 2) // if odd, make even
620  dataStr = "0" + dataStr;
621 
622  i = 0;
623  for(; i < dataStr.size() &&
624  i / 2 <
625  theFEInterfacesManager_->getInterfaceUniversalDataSize(interfaceID);
626  i += 2)
627  {
628  tmpHex[0] = dataStr[dataStr.size() - 1 - i - 1];
629  tmpHex[1] = dataStr[dataStr.size() - 1 - i];
630  sscanf(tmpHex, "%hhX", (unsigned char*)&data[i / 2]);
631  printf("%2.2X", (unsigned char)data[i / 2]);
632  }
633  // finish and fill with 0s
634  for(; i / 2 <
635  theFEInterfacesManager_->getInterfaceUniversalDataSize(interfaceID);
636  i += 2)
637  {
638  data[i / 2] = 0;
639  printf("%2.2X", (unsigned char)data[i / 2]);
640  }
641 
642  std::cout << __E__;
643 
644  // char* address = new char[addressStr.size() + 1];
645  // std::copy(addressStr.begin(), addressStr.end(), address);
646  // address[addressStr.size()] = '\0';
647  // char* data = new char[dataStr.size() + 1];
648  // std::copy(dataStr.begin(), dataStr.end(), data);
649  // data[dataStr.size()] = '\0';
650 
651  theFEInterfacesManager_->universalWrite(interfaceID, address, data);
652 
653  // delete[] address;
654  // delete[] data;
655 
656  return SOAPUtilities::makeSOAPMessageReference(
657  supervisorClassNoNamespace_ + "DataWritten", retParameters);
658  }
659  else if(request == "UniversalRead")
660  {
661  if(!theFEInterfacesManager_)
662  {
663  __SUP_SS__ << "No FE Interface Manager! Are you configured?" << __E__;
664  __SUP_SS_THROW__;
665  }
666 
667  // params for running macros
668  SOAPParameters requestParameters;
669  requestParameters.addParameter("InterfaceID");
670  requestParameters.addParameter("Address");
671  SOAPUtilities::receive(message, requestParameters);
672  std::string interfaceID = requestParameters.getValue("InterfaceID");
673  std::string addressStr = requestParameters.getValue("Address");
674 
675  __SUP_COUT__ << "Address: " << addressStr << " InterfaceID: " << interfaceID
676  << __E__;
677 
678  // parameters interface index!
679  // parameter address and data
680  // unsigned int index = stoi(indexStr); // As long as the supervisor has only
681  // one interface, this index will remain 0?
682 
683  __SUP_COUT__
684  << "theFEInterfacesManager_->getInterfaceUniversalAddressSize(index) "
685  << theFEInterfacesManager_->getInterfaceUniversalAddressSize(interfaceID)
686  << __E__;
687  __SUP_COUT__
688  << "theFEInterfacesManager_->getInterfaceUniversalDataSize(index) "
689  << theFEInterfacesManager_->getInterfaceUniversalDataSize(interfaceID)
690  << __E__;
691 
692  char tmpHex[3]; // for use converting hex to binary
693  tmpHex[2] = '\0';
694 
695  __SUP_COUT__ << "Translating address: ";
696 
697  std::string addressTmp;
698  addressTmp.reserve(
699  theFEInterfacesManager_->getInterfaceUniversalAddressSize(interfaceID));
700  char* address = &addressTmp[0];
701 
702  if(addressStr.size() % 2) // if odd, make even
703  addressStr = "0" + addressStr;
704 
705  unsigned int i = 0;
706  for(; i < addressStr.size() &&
707  i / 2 < theFEInterfacesManager_->getInterfaceUniversalAddressSize(
708  interfaceID);
709  i += 2)
710  {
711  tmpHex[0] = addressStr[addressStr.size() - 1 - i - 1];
712  tmpHex[1] = addressStr[addressStr.size() - 1 - i];
713  sscanf(tmpHex, "%hhX", (unsigned char*)&address[i / 2]);
714  printf("%2.2X", (unsigned char)address[i / 2]);
715  }
716  // finish and fill with 0s
717  for(; i / 2 <
718  theFEInterfacesManager_->getInterfaceUniversalAddressSize(interfaceID);
719  i += 2)
720  {
721  address[i / 2] = 0;
722  printf("%2.2X", (unsigned char)address[i / 2]);
723  }
724 
725  std::cout << __E__;
726 
727  unsigned int dataSz =
728  theFEInterfacesManager_->getInterfaceUniversalDataSize(interfaceID);
729  std::string dataStr;
730  dataStr.resize(dataSz);
731  char* data = &dataStr[0];
732 
733  // std::string result =
734  // theFEInterfacesManager_->universalRead(index,address,data);
735  // __SUP_COUT__<< result << __E__ << __E__;
736 
737  try
738  {
739  theFEInterfacesManager_->universalRead(interfaceID, address, data);
740  }
741  catch(const std::runtime_error& e)
742  {
743  // do not allow read exception to crash everything when a macromaker
744  // command
745  __MOUT_ERR__ << "Exception caught during read: " << e.what() << __E__;
746  __SUP_COUT_ERR__ << "Exception caught during read: " << e.what() << __E__;
747  retParameters.addParameter("dataResult", "Time Out Error");
748  return SOAPUtilities::makeSOAPMessageReference(
749  supervisorClassNoNamespace_ + "aa", retParameters);
750  }
751  catch(...)
752  {
753  // do not allow read exception to crash everything when a macromaker
754  // command
755  __MOUT_ERR__ << "Exception caught during read." << __E__;
756  __SUP_COUT_ERR__ << "Exception caught during read." << __E__;
757  retParameters.addParameter("dataResult", "Time Out Error");
758  return SOAPUtilities::makeSOAPMessageReference(
759  supervisorClassNoNamespace_ + "aa", retParameters);
760  }
761 
762  // if dataSz is less than 8 show what the unsigned number would be
763  if(dataSz <= 8)
764  {
765  std::string str8(data);
766  str8.resize(8);
767  __SUP_COUT__ << "decResult[" << dataSz
768  << " bytes]: " << *((unsigned long long*)(&str8[0]))
769  << __E__;
770  }
771 
772  std::string hexResultStr;
773  hexResultStr.reserve(dataSz * 2 + 1);
774  char* hexResult = &hexResultStr[0];
775  // go through each byte and convert it to hex value (i.e. 2 0-F chars)
776  // go backwards through source data since should be provided in host order
777  // (i.e. a cast to unsigned long long should acquire expected value)
778  for(unsigned int i = 0; i < dataSz; ++i)
779  {
780  sprintf(&hexResult[i * 2], "%2.2X", (unsigned char)data[dataSz - 1 - i]);
781  }
782 
783  __SUP_COUT__ << "hexResult[" << strlen(hexResult)
784  << " nibbles]: " << std::string(hexResult) << __E__;
785 
786  retParameters.addParameter("dataResult", hexResult);
787  return SOAPUtilities::makeSOAPMessageReference(
788  supervisorClassNoNamespace_ + "aa", retParameters);
789  }
790  else if(request == "GetInterfaceMacros")
791  {
792  if(theFEInterfacesManager_)
793  retParameters.addParameter(
794  "FEMacros",
795  theFEInterfacesManager_->getFEMacrosString(
796  CorePropertySupervisorBase::getSupervisorUID(),
797  std::to_string(CoreSupervisorBase::getSupervisorLID())));
798  else
799  retParameters.addParameter("FEMacros", "");
800 
801  return SOAPUtilities::makeSOAPMessageReference(
802  supervisorClassNoNamespace_ + "Response", retParameters);
803  }
804  else if(request == "RunInterfaceMacro")
805  {
806  if(!theFEInterfacesManager_)
807  {
808  __SUP_SS__ << "Missing FE Interface Manager! Are you configured?"
809  << __E__;
810  __SUP_SS_THROW__;
811  }
812 
813  // params for running macros
814  SOAPParameters requestParameters;
815  requestParameters.addParameter("feMacroName");
816  requestParameters.addParameter("inputArgs");
817  requestParameters.addParameter("outputArgs");
818  requestParameters.addParameter("InterfaceID");
819  SOAPUtilities::receive(message, requestParameters);
820  std::string interfaceID = requestParameters.getValue("InterfaceID");
821  std::string feMacroName = requestParameters.getValue("feMacroName");
822  std::string inputArgs = requestParameters.getValue("inputArgs");
823  std::string outputArgs = requestParameters.getValue("outputArgs");
824 
825  // outputArgs must be filled with the proper argument names
826  // and then the response output values will be returned in the string.
827  try
828  {
829  theFEInterfacesManager_->runFEMacro(
830  interfaceID, feMacroName, inputArgs, outputArgs);
831  }
832  catch(std::runtime_error& e)
833  {
834  __SUP_SS__ << "In Supervisor with LID="
835  << getApplicationDescriptor()->getLocalId()
836  << " the FE Macro named '" << feMacroName
837  << "' with target FE '" << interfaceID
838  << "' failed. Here is the error:\n\n"
839  << e.what() << __E__;
840  __SUP_SS_THROW__;
841  }
842  catch(...)
843  {
844  __SUP_SS__ << "In Supervisor with LID="
845  << getApplicationDescriptor()->getLocalId()
846  << " the FE Macro named '" << feMacroName
847  << "' with target FE '" << interfaceID
848  << "' failed due to an unknown error." << __E__;
849  __SUP_SS_THROW__;
850  }
851 
852  // retParameters.addParameter("success", success ? "1" : "0");
853  retParameters.addParameter("outputArgs", outputArgs);
854 
855  return SOAPUtilities::makeSOAPMessageReference(
856  supervisorClassNoNamespace_ + "Response", retParameters);
857  }
858  else if(request == "RunMacroMakerMacro")
859  {
860  if(!theFEInterfacesManager_)
861  {
862  __SUP_SS__ << "Missing FE Interface Manager! Are you configured?"
863  << __E__;
864  __SUP_SS_THROW__;
865  }
866 
867  // params for running macros
868  SOAPParameters requestParameters;
869  requestParameters.addParameter("macroName");
870  requestParameters.addParameter("macroString");
871  requestParameters.addParameter("inputArgs");
872  requestParameters.addParameter("outputArgs");
873  requestParameters.addParameter("InterfaceID");
874  SOAPUtilities::receive(message, requestParameters);
875  std::string interfaceID = requestParameters.getValue("InterfaceID");
876  std::string macroName = requestParameters.getValue("macroName");
877  std::string macroString = requestParameters.getValue("macroString");
878  std::string inputArgs = requestParameters.getValue("inputArgs");
879  std::string outputArgs = requestParameters.getValue("outputArgs");
880 
881  // outputArgs must be filled with the proper argument names
882  // and then the response output values will be returned in the string.
883  try
884  {
885  theFEInterfacesManager_->runMacro(
886  interfaceID, macroString, inputArgs, outputArgs);
887  }
888  catch(std::runtime_error& e)
889  {
890  __SUP_SS__ << "In Supervisor with LID="
891  << getApplicationDescriptor()->getLocalId()
892  << " the MacroMaker Macro named '" << macroName
893  << "' with target FE '" << interfaceID
894  << "' failed. Here is the error:\n\n"
895  << e.what() << __E__;
896  __SUP_SS_THROW__;
897  }
898  catch(...)
899  {
900  __SUP_SS__ << "In Supervisor with LID="
901  << getApplicationDescriptor()->getLocalId()
902  << " the MacroMaker Macro named '" << macroName
903  << "' with target FE '" << interfaceID
904  << "' failed due to an unknown error." << __E__;
905  __SUP_SS_THROW__;
906  }
907 
908  retParameters.addParameter("outputArgs", outputArgs);
909 
910  return SOAPUtilities::makeSOAPMessageReference(
911  supervisorClassNoNamespace_ + "Response", retParameters);
912  }
913  else
914  {
915  __SUP_SS__ << "Unrecognized request received! '" << request << "'" << __E__;
916  __SUP_SS_THROW__;
917  }
918  }
919  catch(const std::runtime_error& e)
920  {
921  __SUP_SS__ << "Error occurred handling request: " << e.what() << __E__;
922  __SUP_COUT_ERR__ << ss.str();
923  retParameters.addParameter("Error", ss.str());
924  }
925  catch(...)
926  {
927  __SUP_SS__ << "Error occurred handling request." << __E__;
928  __SUP_COUT_ERR__ << ss.str();
929  retParameters.addParameter("Error", ss.str());
930  }
931 
932  return SOAPUtilities::makeSOAPMessageReference(
933  supervisorClassNoNamespace_ + "FailRequest", retParameters);
934 
935 } // end macroMakerSupervisorRequest()
936 
937 //========================================================================================================================
938 xoap::MessageReference FESupervisor::workLoopStatusRequest(xoap::MessageReference message)
939 {
940  if(!theFEInterfacesManager_)
941  {
942  __SUP_SS__ << "Invalid request for front-end workloop status from Supervisor "
943  "without a FEVInterfacesManager."
944  << __E__;
945  __SUP_SS_THROW__;
946  }
947 
948  return SOAPUtilities::makeSOAPMessageReference(
949  (theFEInterfacesManager_->allFEWorkloopsAreDone()
950  ? CoreSupervisorBase::WORK_LOOP_DONE
951  : CoreSupervisorBase::WORK_LOOP_WORKING));
952 } // end workLoopStatusRequest()
953 
954 //========================================================================================================================
955 // extractFEInterfaceManager
956 //
957 // locates theFEInterfacesManager in state machines vector and
958 // returns 0 if not found.
959 //
960 // Note: this code assumes a CoreSupervisorBase has only one
961 // FEVInterfacesManager in its vector of state machines
962 FEVInterfacesManager* FESupervisor::extractFEInterfacesManager()
963 {
964  theFEInterfacesManager_ = 0;
965 
966  for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
967  {
968  try
969  {
970  theFEInterfacesManager_ =
971  dynamic_cast<FEVInterfacesManager*>(theStateMachineImplementation_[i]);
972  if(!theFEInterfacesManager_)
973  {
974  // dynamic_cast returns null pointer on failure
975  __SUP_SS__ << "Dynamic cast failure!" << __E__;
976  __SUP_SS_THROW__;
977  }
978  __SUP_COUT__ << "State Machine " << i << " WAS of type FEVInterfacesManager"
979  << __E__;
980 
981  break;
982  }
983  catch(...)
984  {
985  __SUP_COUT__ << "State Machine " << i
986  << " was NOT of type FEVInterfacesManager" << __E__;
987  }
988  }
989 
990  __SUP_COUT__ << "theFEInterfacesManager pointer = " << theFEInterfacesManager_
991  << __E__;
992 
993  return theFEInterfacesManager_;
994 } // end extractFEInterfaceManager()
void startMacroMultiDimensional(const std::string &requester, const std::string &interfaceID, const std::string &macroName, const std::string &macroString, const bool enableSavingOutput, const std::string &outputFilePath, const std::string &outputFileRadix, const std::string &inputArgs)