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