otsdaq  v2_01_00
FESupervisor.cc
1 #include "otsdaq-core/CoreSupervisors/FESupervisor.h"
2 #include "otsdaq-core/FECore/FEVInterfacesManager.h"
3 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
4 #include "otsdaq-core/FECore/FEVInterfacesManager.h"
5 
6 using namespace ots;
7 
8 XDAQ_INSTANTIATOR_IMPL(FESupervisor)
9 
10 
11 
12 //========================================================================================================================
13 FESupervisor::FESupervisor(xdaq::ApplicationStub * s)
15 
16 {
17  xoap::bind(this, &FESupervisor::macroMakerSupervisorRequest, "MacroMakerSupervisorRequest", XDAQ_NS_URI);
18  xoap::bind(this, &FESupervisor::workLoopStatusRequest, "WorkLoopStatusRequest", XDAQ_NS_URI);
19 
20  CoreSupervisorBase::theStateMachineImplementation_.push_back(
22  CorePropertySupervisorBase::getContextTreeNode(),
23  CorePropertySupervisorBase::supervisorConfigurationPath_
24  )
25  );
26 
27 }
28 
29 //========================================================================================================================
30 FESupervisor::~FESupervisor(void)
31 {
32  //theStateMachineImplementation_ is reset and the object it points to deleted in ~CoreSupervisorBase()0
33 }
34 
35 
36 //========================================================================================================================
37 // macroMakerSupervisorRequest
38 // Handles all MacroMaker Requests:
39 // - GetInterfaces (returns interface type and id)
40 //
41 // Note: this code assumes a CoreSupervisorBase has only one
42 // FEVInterfacesManager in its vector of state machines
43 xoap::MessageReference FESupervisor::macroMakerSupervisorRequest(
44  xoap::MessageReference message)
45 
46 {
47  __COUT__ << "$$$$$$$$$$$$$$$$$" << std::endl;
48 
49  //locate theFEInterfacesManager in state machines vector
50  FEVInterfacesManager* theFEInterfacesManager = extractFEInterfaceManager();
51 
52  //receive request parameters
53  SOAPParameters parameters;
54  parameters.addParameter("Request");
55  parameters.addParameter("InterfaceID");
56 
57  //params for universal commands
58  parameters.addParameter("Address");
59  parameters.addParameter("Data");
60 
61  //params for running macros
62  parameters.addParameter("feMacroName");
63  parameters.addParameter("inputArgs");
64  parameters.addParameter("outputArgs");
65 
66  SOAPMessenger::receive(message, parameters);
67  std::string request = parameters.getValue("Request");
68  std::string addressStr = parameters.getValue("Address");
69  std::string dataStr = parameters.getValue("Data");
70  std::string InterfaceID = parameters.getValue("InterfaceID");
71 
72  __COUT__ << "request: " << request << std::endl;
73 
74  __COUT__ << "Address: " << addressStr << " Data: "
75  << dataStr << " InterfaceID: " << InterfaceID << std::endl;
76 
77  SOAPParameters retParameters;
78 
79  try
80  {
81  if (request == "GetInterfaces")
82  {
83  if (theFEInterfacesManager)
84  retParameters.addParameter("FEList",
85  theFEInterfacesManager->getFEListString(
86  std::to_string(getApplicationDescriptor()->getLocalId())));
87  else
88  retParameters.addParameter("FEList", "");
89 
90  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
91  retParameters);
92  }
93  else if (request == "UniversalWrite")
94  {
95  if (!theFEInterfacesManager)
96  {
97  __COUT_INFO__ << "No FE Interface Manager! (So no write occurred)" << std::endl;
98  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "DataWritten", retParameters);
99  }
100 
101  // parameters interface index!
102  //unsigned int index = stoi(indexStr); // As long as the supervisor has only one interface, this index will remain 0?
103 
104 
105 
106  __COUT__ << "theFEInterfacesManager->getInterfaceUniversalAddressSize(index) " <<
107  theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) << std::endl;
108  __COUT__ << "theFEInterfacesManager->getInterfaceUniversalDataSize(index) " <<
109  theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) << std::endl;
110 
111  //Converting std::string to char*
112  //char address
113 
114  char tmpHex[3]; //for use converting hex to binary
115  tmpHex[2] = '\0';
116 
117 
118  __COUT__ << "Translating address: ";
119 
120  std::string addressTmp; addressTmp.reserve(theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID));
121  char* address = &addressTmp[0];
122 
123  if (addressStr.size() % 2) //if odd, make even
124  addressStr = "0" + addressStr;
125  unsigned int i = 0;
126  for (; i < addressStr.size() &&
127  i / 2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID); i += 2)
128  {
129  tmpHex[0] = addressStr[addressStr.size() - 1 - i - 1];
130  tmpHex[1] = addressStr[addressStr.size() - 1 - i];
131  sscanf(tmpHex, "%hhX", (unsigned char*)&address[i / 2]);
132  printf("%2.2X", (unsigned char)address[i / 2]);
133  }
134  //finish and fill with 0s
135  for (; i / 2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID); i += 2)
136  {
137  address[i / 2] = 0;
138  printf("%2.2X", (unsigned char)address[i / 2]);
139  }
140 
141  std::cout << std::endl;
142 
143  __COUT__ << "Translating data: ";
144 
145  std::string dataTmp; dataTmp.reserve(theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID));
146  char* data = &dataTmp[0];
147 
148  if (dataStr.size() % 2) //if odd, make even
149  dataStr = "0" + dataStr;
150 
151  i = 0;
152  for (; i < dataStr.size() &&
153  i / 2 < theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID); i += 2)
154  {
155  tmpHex[0] = dataStr[dataStr.size() - 1 - i - 1];
156  tmpHex[1] = dataStr[dataStr.size() - 1 - i];
157  sscanf(tmpHex, "%hhX", (unsigned char*)&data[i / 2]);
158  printf("%2.2X", (unsigned char)data[i / 2]);
159  }
160  //finish and fill with 0s
161  for (; i / 2 < theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID); i += 2)
162  {
163  data[i / 2] = 0;
164  printf("%2.2X", (unsigned char)data[i / 2]);
165  }
166 
167  std::cout << std::endl;
168 
169  //char* address = new char[addressStr.size() + 1];
170  //std::copy(addressStr.begin(), addressStr.end(), address);
171  // address[addressStr.size()] = '\0';
172  // char* data = new char[dataStr.size() + 1];
173  // std::copy(dataStr.begin(), dataStr.end(), data);
174  // data[dataStr.size()] = '\0';
175 
176  theFEInterfacesManager->universalWrite(InterfaceID, address, data);
177 
178  //delete[] address;
179  //delete[] data;
180 
181  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "DataWritten", retParameters);
182  }
183  else if (request == "UniversalRead")
184  {
185  if (!theFEInterfacesManager)
186  {
187  __COUT_INFO__ << "No FE Interface Manager! (So no read occurred)" << std::endl;
188  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa", retParameters);
189  }
190 
191  // parameters interface index!
192  // parameter address and data
193  //unsigned int index = stoi(indexStr); // As long as the supervisor has only one interface, this index will remain 0?
194 
195  __COUT__ << "theFEInterfacesManager->getInterfaceUniversalAddressSize(index) "
196  << theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) << std::endl;
197  __COUT__ << "theFEInterfacesManager->getInterfaceUniversalDataSize(index) "
198  << theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) << std::endl;
199 
200  char tmpHex[3]; //for use converting hex to binary
201  tmpHex[2] = '\0';
202 
203 
204  __COUT__ << "Translating address: ";
205 
206  std::string addressTmp; addressTmp.reserve(theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID));
207  char* address = &addressTmp[0];
208 
209  if (addressStr.size() % 2) //if odd, make even
210  addressStr = "0" + addressStr;
211 
212  unsigned int i = 0;
213  for (; i < addressStr.size() &&
214  i / 2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID); i += 2)
215  {
216  tmpHex[0] = addressStr[addressStr.size() - 1 - i - 1];
217  tmpHex[1] = addressStr[addressStr.size() - 1 - i];
218  sscanf(tmpHex, "%hhX", (unsigned char*)&address[i / 2]);
219  printf("%2.2X", (unsigned char)address[i / 2]);
220  }
221  //finish and fill with 0s
222  for (; i / 2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID); i += 2)
223  {
224  address[i / 2] = 0;
225  printf("%2.2X", (unsigned char)address[i / 2]);
226  }
227 
228  std::cout << std::endl;
229 
230  unsigned int dataSz = theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID);
231  std::string dataStr; dataStr.resize(dataSz);
232  char* data = &dataStr[0];
233 
234 
235  // std::string result = theFEInterfacesManager->universalRead(index,address,data);
236  // __COUT__<< result << std::endl << std::endl;
237 
238  try
239  {
240  if (theFEInterfacesManager->universalRead(InterfaceID, address, data) < 0)
241  {
242  retParameters.addParameter("dataResult", "Time Out Error");
243  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa", retParameters);
244  }
245  }
246  catch (const std::runtime_error& e)
247  {
248  //do not allow read exception to crash everything when a macromaker command
249  __MOUT_ERR__ << "Exception caught during read: " << e.what() << std::endl;
250  __COUT_ERR__ << "Exception caught during read: " << e.what() << std::endl;
251  retParameters.addParameter("dataResult", "Time Out Error");
252  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa", retParameters);
253  }
254  catch (...)
255  {
256  //do not allow read exception to crash everything when a macromaker command
257  __MOUT_ERR__ << "Exception caught during read." << std::endl;
258  __COUT_ERR__ << "Exception caught during read." << std::endl;
259  retParameters.addParameter("dataResult", "Time Out Error");
260  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa", retParameters);
261  }
262 
263  //if dataSz is less than 8 show what the unsigned number would be
264  if (dataSz <= 8)
265  {
266  std::string str8(data);
267  str8.resize(8);
268  __COUT__ << "decResult[" << dataSz << " bytes]: " <<
269  *((unsigned long long *)(&str8[0])) << std::endl;
270 
271  }
272 
273  std::string hexResultStr;
274  hexResultStr.reserve(dataSz * 2 + 1);
275  char* hexResult = &hexResultStr[0];
276  //go through each byte and convert it to hex value (i.e. 2 0-F chars)
277  //go backwards through source data since should be provided in host order
278  // (i.e. a cast to unsigned long long should acquire expected value)
279  for (unsigned int i = 0; i < dataSz; ++i)
280  {
281  sprintf(&hexResult[i * 2], "%2.2X", (unsigned char)data[dataSz - 1 - i]);
282  }
283 
284  __COUT__ << "hexResult[" << strlen(hexResult) << " nibbles]: " << std::string(hexResult) << std::endl;
285 
286 
287 
288  retParameters.addParameter("dataResult", hexResult);
289  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa", retParameters);
290 
291  }
292  else if (request == "GetInterfaceMacros")
293  {
294  if (theFEInterfacesManager)
295  retParameters.addParameter("FEMacros", theFEInterfacesManager->getFEMacrosString(
296  std::to_string(getApplicationDescriptor()->getLocalId())));
297  else
298  retParameters.addParameter("FEMacros", "");
299 
300  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
301  retParameters);
302  }
303  else if (request == "RunInterfaceMacro")
304  {
305  if (!theFEInterfacesManager)
306  {
307  retParameters.addParameter("success", "0");
308  retParameters.addParameter("outputArgs", "");
309  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
310  retParameters);
311  }
312 
313  std::string feMacroName = parameters.getValue("feMacroName");
314  std::string inputArgs = parameters.getValue("inputArgs");
315  std::string outputArgs = parameters.getValue("outputArgs");
316 
317  //outputArgs must be filled with the proper argument names
318  // and then the response output values will be returned in the string.
319  bool success = true;
320  try
321  {
322  theFEInterfacesManager->runFEMacro(InterfaceID, feMacroName, inputArgs, outputArgs);
323  }
324  catch (std::runtime_error &e)
325  {
326  __SS__ << "In Supervisor with LID=" << getApplicationDescriptor()->getLocalId()
327  << " the FE Macro named '" << feMacroName << "' with tartget FE '"
328  << InterfaceID << "' failed. Here is the error:\n\n" << e.what() << std::endl;
329  __COUT_ERR__ << "\n" << ss.str();
330  success = false;
331  outputArgs = ss.str();
332  }
333 
334 
335  retParameters.addParameter("success", success ? "1" : "0");
336  retParameters.addParameter("outputArgs", outputArgs);
337 
338  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
339  retParameters);
340  }
341  else
342  {
343  __COUT_WARN__ << "Unrecognized request received! '" << request << "'" << std::endl;
344  }
345  }
346  catch (const std::runtime_error& e)
347  {
348  __SS__ << "Error occurred handling request: " << e.what() << __E__;
349  __COUT_ERR__ << ss.str();
350  }
351  catch (...)
352  {
353  __SS__ << "Error occurred handling request." << __E__;
354  __COUT_ERR__ << ss.str();
355  }
356 
357 
358 
359  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "FailRequest", retParameters);
360 
361 } //end macroMakerSupervisorRequest()
362 
363 
364 //========================================================================================================================
365 xoap::MessageReference FESupervisor::workLoopStatusRequest(xoap::MessageReference message)
366 
367 {
368  //locate theFEInterfacesManager in state machines vector
369  FEVInterfacesManager* theFEInterfacesManager = extractFEInterfaceManager();
370 
371  if (!theFEInterfacesManager)
372  {
373  __SS__ << "Invalid request for front-end workloop status from Supervisor without a FEVInterfacesManager."
374  << std::endl;
375  __COUT_ERR__ << ss.str();
376  throw std::runtime_error(ss.str());
377  }
378 
379  return SOAPUtilities::makeSOAPMessageReference(
380  (theFEInterfacesManager->allFEWorkloopsAreDone() ?
381  CoreSupervisorBase::WORK_LOOP_DONE :
382  CoreSupervisorBase::WORK_LOOP_WORKING));
383 } //end workLoopStatusRequest()
384 
385 //========================================================================================================================
386 //extractFEInterfaceManager
387 //
388 // locates theFEInterfacesManager in state machines vector and
389 // returns 0 if not found.
390 //
391 // Note: this code assumes a CoreSupervisorBase has only one
392 // FEVInterfacesManager in its vector of state machines
393 FEVInterfacesManager* FESupervisor::extractFEInterfaceManager()
394 {
395  FEVInterfacesManager* theFEInterfacesManager = 0;
396 
397  for (unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
398  {
399  try
400  {
401  theFEInterfacesManager =
402  dynamic_cast<FEVInterfacesManager*>(theStateMachineImplementation_[i]);
403  if (!theFEInterfacesManager)
404  {
405  //dynamic_cast returns null pointer on failure
406  __SS__ << "Dynamic cast failure!" << std::endl;
407  __COUT_ERR__ << ss.str();
408  throw std::runtime_error(ss.str());
409  }
410  __COUT__ << "State Machine " << i << " WAS of type FEVInterfacesManager" << std::endl;
411 
412  break;
413  }
414  catch (...)
415  {
416  __COUT__ << "State Machine " << i << " was NOT of type FEVInterfacesManager" << std::endl;
417  }
418  }
419 
420  __COUT__ << "theFEInterfacesManager pointer = " << theFEInterfacesManager << std::endl;
421 
422  return theFEInterfacesManager;
423 } // end extractFEInterfaceManager()
424 
425 
426 
427 
428 
429