otsdaq_components  v2_02_00
FEOtsUDPProducerTemplateInterface_interface.cc
1 #include "otsdaq-components/FEInterfaces/FEOtsUDPProducerTemplateInterface.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutMacros.h"
4 #include "otsdaq-core/Macros/InterfacePluginMacros.h"
5 #include <iostream>
6 #include <set>
7 
8 using namespace ots;
9 
10 //========================================================================================================================
11 FEOtsUDPProducerTemplateInterface::FEOtsUDPProducerTemplateInterface(const std::string& interfaceUID,
12  const ConfigurationTree& theXDAQContextConfigTree, const std::string& interfaceConfigurationPath)
13 : Socket (
14  theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("HostIPAddress").getValue<std::string>()
15  , theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("HostPort").getValue<unsigned int>())
16 //, WorkLoop (interfaceUID + "-workloop")
17 , FEProducerVInterface (interfaceUID, theXDAQContextConfigTree, interfaceConfigurationPath)
18 //, DataProducer ("supervisorID","bufferID","processorID",100/*bufferSize*/)
19 , OtsUDPHardware (theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("InterfaceIPAddress").getValue<std::string>()
20  , theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("InterfacePort").getValue<unsigned int>())
21 , OtsUDPFirmwareDataGen(theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("FirmwareVersion").getValue<unsigned int>())
22 {
23  //registration of FEMacro 'varTest2' generated, Oct-11-2018 02:28:57, by 'admin' using MacroMaker.
24  FEVInterface::registerFEMacroFunction("varTest2",//feMacroName
25  static_cast<FEVInterface::frontEndMacroFunction_t>(&FEOtsUDPProducerTemplateInterface::varTest2), //feMacroFunction
26  std::vector<std::string>{"myOtherArg"}, //namesOfInputArgs
27  std::vector<std::string>{"myArg","outArg1"}, //namesOfOutputArgs
28  1); //requiredUserPermissions
29 
30 
31  //registration of FEMacro 'varTest' generated, Oct-11-2018 11:36:28, by 'admin' using MacroMaker.
32  FEVInterface::registerFEMacroFunction("varTest",//feMacroName
33  static_cast<FEVInterface::frontEndMacroFunction_t>(&FEOtsUDPProducerTemplateInterface::varTest), //feMacroFunction
34  std::vector<std::string>{"myOtherArg"}, //namesOfInputArgs
35  std::vector<std::string>{"myArg","outArg1"}, //namesOfOutputArgs
36  1); //requiredUserPermissions
37 
38  universalAddressSize_ = 8;
39  universalDataSize_ = 8;
40 }
41 
42 //========================================================================================================================
43 FEOtsUDPProducerTemplateInterface::~FEOtsUDPProducerTemplateInterface(void)
44 {}
45 
46 //========================================================================================================================
47 void FEOtsUDPProducerTemplateInterface::configure(void)
48 {
49 // unsigned int i = VStateMachine::getIterationIndex();
50 // unsigned int j = VStateMachine::getSubIterationIndex();
51 // if(i == 0 && j < 5)
52 // VStateMachine::indicateSubIterationWork();
53 // else if(i < 10)
54 // VStateMachine::indicateIterationWork();
55 //
56 // __FE_COUTV__(VStateMachine::getSubIterationIndex());
57 // __FE_COUTV__(VStateMachine::getSubIterationWork());
58 // __FE_COUTV__(VStateMachine::getIterationIndex());
59 // __FE_COUTV__(VStateMachine::getIterationWork());
60 //
61 // __FE_COUTV__(i);
62 // __FE_COUTV__(getInterfaceUID());
63 // switch(i)
64 // {
65 // case 1:
66 // if(getInterfaceUID() == "ExampleInterface0")
67 // {
68 // FEVInterface::sendToFrontEnd("ExampleInterface1","Hello1");
69 // FEVInterface::sendToFrontEnd("ExampleInterface1",4.3f);
70 // FEVInterface::sendToFrontEnd("ExampleInterface1",4);
71 // FEVInterface::sendToFrontEnd("ExampleInterface2","Hello2");
72 // FEVInterface::sendToFrontEnd("ExampleInterface2",4.6f);
73 // FEVInterface::sendToFrontEnd("ExampleInterface2",6);
74 // }
75 // break;
76 // case 2:
77 // if(getInterfaceUID() != "ExampleInterface0")
78 // {
79 // std::string a = FEVInterface::receiveFromFrontEnd("ExampleInterface0");
80 // double b = FEVInterface::receiveFromFrontEnd<double>("ExampleInterface0");
81 // unsigned short c =
82 // FEVInterface::receiveFromFrontEnd<unsigned short>("ExampleInterface0");
83 // __FE_COUTV__(a);
84 // __FE_COUTV__(b);
85 // __FE_COUTV__(c);
86 // }
87 // break;
88 // case 3:
89 // if(getInterfaceUID() == "ExampleInterface0")
90 // {
91 // std::vector<frontEndMacroArg_t> argsIn;
92 // __SET_ARG_IN__("myOtherArg",(unsigned int)5);
93 //
94 // std::vector<frontEndMacroArg_t> argsOut;
95 //
96 // __FE_COUTV__(StringMacros::vectorToString(argsIn));
97 //
98 // FEVInterface::runFrontEndMacro("ExampleInterface2","varTest2",
99 // argsIn,argsOut);
100 //
101 // __FE_COUTV__(StringMacros::vectorToString(argsOut));
102 // __FE_COUTV__(FEVInterface::getFEMacroArgument(
103 // argsOut,"outArg1"));
104 //
105 // {
106 // std::string a = FEVInterface::getFEMacroArgument(
107 // argsOut,"myArg");
108 // double b = getFEMacroArgumentValue<double>(
109 // argsOut,"outArg1");
110 // unsigned short c = getFEMacroArgumentValue<unsigned short>(
111 // argsOut,"outArg1");
112 // __FE_COUTV__(a);
113 // __FE_COUTV__(b);
114 // __FE_COUTV__(c);
115 // }
116 //
117 //
118 //
119 // FEVInterface::runFrontEndMacro("ExampleInterface1","varTest",
120 // argsIn,argsOut);
121 // __FE_COUTV__(StringMacros::vectorToString(argsOut));
122 //
123 // {
124 // std::string a = __GET_ARG_OUT__("myArg",std::string);
125 // double b = __GET_ARG_OUT__("outArg1",double);
126 // unsigned short c = __GET_ARG_OUT__("outArg1",unsigned short);
127 // __FE_COUTV__(a);
128 // __FE_COUTV__(b);
129 // __FE_COUTV__(c);
130 // }
131 // }
132 //
133 // break;
134 // default:;
135 // }
136 //
137 //
138 // return;
139 
140  __FE_COUT__ << "configure" << __E__;
141  __FE_COUT__ << "Clearing receive socket buffer: " << OtsUDPHardware::clearReadSocket() << " packets cleared." << __E__;
142 
143  std::string sendBuffer;
144  std::string recvBuffer;
145  uint64_t readQuadWord;
146 
147  __FE_COUT__ << "Configuration Path Table: " <<
148  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getConfigurationName() <<
149  "-v" <<
150  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getConfigurationVersion() <<
151  __E__;
152 
153  __FE_COUT__ << "Interface name: " <<
154  theXDAQContextConfigTree_.getNode(theConfigurationPath_) << __E__;
155 
156  __FE_COUT__ << "Configured Firmware Version: " <<
157  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("FirmwareVersion").getValue<unsigned int>()
158  << __E__;
159 
160  __FE_COUT__ << "Setting Destination IP: " <<
161  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToIPAddress").getValue<std::string>()
162  << __E__;
163  __FE_COUT__ << "And Destination Port: " <<
164  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToPort").getValue<unsigned int>()
165  << __E__;
166 
167  OtsUDPFirmwareCore::setDataDestination(sendBuffer,
168  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToIPAddress").getValue<std::string>(),
169  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToPort").getValue<uint64_t>()
170  );
171  OtsUDPHardware::write(sendBuffer);
172 
173  __FE_COUT__ << "Reading back burst dest MAC/IP/Port: " << __E__;
174 
175  OtsUDPFirmwareCore::readDataDestinationMAC(sendBuffer);
176  OtsUDPHardware::read(sendBuffer,readQuadWord);
177 
178  OtsUDPFirmwareCore::readDataDestinationIP(sendBuffer);
179  OtsUDPHardware::read(sendBuffer,readQuadWord);
180 
181  OtsUDPFirmwareCore::readDataDestinationPort(sendBuffer);
182  OtsUDPHardware::read(sendBuffer,readQuadWord);
183 
184 
185 
186  OtsUDPFirmwareCore::readControlDestinationPort(sendBuffer);
187  OtsUDPHardware::read(sendBuffer,readQuadWord);
188 
189  //Run Configure Sequence Commands
190  FEVInterface::runSequenceOfCommands("LinkToConfigureSequence");
191 
192  __FE_COUT__ << "Done with ots Template configuring." << __E__;
193 }
194 
195 //========================================================================================================================
196 //void FEOtsUDPProducerTemplateInterface::configureDetector(const DACStream& theDACStream)
197 //{
198 // __FE_COUT__ << "\tconfigureDetector" << __E__;
199 //}
200 
201 //========================================================================================================================
202 void FEOtsUDPProducerTemplateInterface::halt(void)
203 {
204  __FE_COUT__ << "\tHalt" << __E__;
205  stop();
206 }
207 
208 //========================================================================================================================
209 void FEOtsUDPProducerTemplateInterface::pause(void)
210 {
211  __FE_COUT__ << "\tPause" << __E__;
212  stop();
213 }
214 
215 //========================================================================================================================
216 void FEOtsUDPProducerTemplateInterface::resume(void)
217 {
218  __FE_COUT__ << "\tResume" << __E__;
219  start("");
220 }
221 
222 //========================================================================================================================
223 void FEOtsUDPProducerTemplateInterface::start(std::string )//runNumber)
224 {
225  __FE_COUT__ << "\tStart" << __E__;
226 
227 
228 // unsigned int i = VStateMachine::getIterationIndex();
229 // unsigned int j = VStateMachine::getSubIterationIndex();
230 // if(i == 0 && j < 5)
231 // VStateMachine::indicateSubIterationWork();
232 // else if(i < 10)
233 // VStateMachine::indicateIterationWork();
234 //
235 //
236 // __FE_COUTV__(VStateMachine::getSubIterationIndex());
237 // __FE_COUTV__(VStateMachine::getSubIterationWork());
238 // __FE_COUTV__(VStateMachine::getIterationIndex());
239 // __FE_COUTV__(VStateMachine::getIterationWork());
240 //
241 //
242 // return;
243 
244 
245 
246  //Run Start Sequence Commands
247  FEVInterface::runSequenceOfCommands("LinkToStartSequence");
248 
249  std::string sendBuffer;
250  OtsUDPFirmwareCore::startBurst(sendBuffer);
251  OtsUDPHardware::write(sendBuffer);
252 }
253 
254 //========================================================================================================================
255 void FEOtsUDPProducerTemplateInterface::stop(void)
256 {
257  __FE_COUT__ << "\tStop" << __E__;
258 
259  //Run Stop Sequence Commands
260 
261  FEVInterface::runSequenceOfCommands("LinkToStopSequence");
262 
263  std::string sendBuffer;
264  OtsUDPFirmwareCore::stopBurst(sendBuffer);
265  OtsUDPHardware::write(sendBuffer);
266 }
267 
268 //========================================================================================================================
269 bool FEOtsUDPProducerTemplateInterface::running(void)
270 {
271  __FE_COUT__ << "\tRunning" << __E__;
272 
273  //__SS__ << "?" << __E__; //test exceptions during running
274  //__SS_THROW__;
275 
276 
277  int state = -1;
278  while(WorkLoop::continueWorkLoop_)
279  {
280  //while running
281  //play with the LEDs at address 0x1003
282 
283  ++state;
284  if(state < 8)
285  sleep(1);
286  else
287  {
288  // if(1 || getInterfaceUID() == "ExampleInterface1")
289  // {
290  // throw __OTS_SOFT_EXCEPTION__("Soft error here");
291  // }
292  // else
293  break;
294  }
295 
296 
297 
298  {
299  if(DataProducerBase::attachToEmptySubBuffer(
300  dataP_, headerP_) < 0)
301  {
302  __CFG_COUT__ << "There are no available buffers! Retrying...after waiting 10 milliseconds!" << std::endl;
303  usleep(10000);
304  return true;
305  }
306 
307  if(1) // test data buffers
308  {
309  //sleep(1);
310  unsigned long long value = 0xB57321; //this is 8-bytes
311  std::string& buffer = *dataP_;
312  buffer.resize(8); //NOTE: this is inexpensive according to Lorenzo/documentation in C++11 (only increases size once and doesn't decrease size)
313  memcpy((void *)&buffer[0] /*dest*/,(void *)&value /*src*/, 8 /*numOfBytes*/);
314 
315  //size() and length() are equivalent
316  __CFG_COUT__ << "Writing to buffer " << buffer.size() << " bytes!" << __E__;
317  __CFG_COUT__ << "Writing to buffer length " << buffer.length() << " bytes!" << __E__;
318 
319  __CFG_COUT__ << "Buffer Data: " << BinaryStringMacros::binaryTo8ByteHexString(buffer) << __E__;
320 
321  __CFG_COUTV__(DataProcessor::theCircularBuffer_);
322 
323  __CFG_COUT__ << __E__;
324 
325 
326 
327 
328 
329  __CFG_COUT__ << __E__;
330 
331 
332  DataProducerBase::setWrittenSubBuffer<std::string,std::map<std::string,std::string> >();
333  __CFG_COUT__ << __E__;
334  __CFG_COUTV__(DataProcessor::theCircularBuffer_);
335 
336  }
337  }
338  if(0)
339  {
340 
341  unsigned long long value = 0xA54321; //this is 8-bytes
342  std::string buffer;
343  buffer.resize(8); //NOTE: this is inexpensive according to Lorenzo/documentation in C++11 (only increases size once and doesn't decrease size)
344  memcpy((void *)&buffer[0] /*dest*/,(void *)&value /*src*/, 8 /*numOfBytes*/);
345 
346  //size() and length() are equivalent
347  __FE_COUT__ << "Writing to buffer " << buffer.size() << " bytes!" << __E__;
348  __FE_COUT__ << "Writing to buffer length " << buffer.length() << " bytes!" << __E__;
349 
350  __FE_COUT__ << "Buffer Data: " << BinaryStringMacros::binaryTo8ByteHexString(buffer) << __E__;
351 
352 
353  FEProducerVInterface::copyToNextBuffer(buffer);
354  }
355 
356  }
357 
358  // //example!
359  // //play with array of 8 LEDs at address 0x1003
360 
361  //
362  // bool flashLEDsWhileRunning = false;
363  // if(flashLEDsWhileRunning)
364  // {
365  // std::string writeBuffer;
366  // int state = -1;
367  // while(WorkLoop::continueWorkLoop_)
368  // {
369  // //while running
370  // //play with the LEDs at address 0x1003
371  //
372  // ++state;
373  // if(state < 8)
374  // {
375  // writeBuffer.resize(0);
376  // OtsUDPFirmwareCore::write(writeBuffer, 0x1003,1<<state);
377  // OtsUDPHardware::write(writeBuffer);
378  // }
379  // else if(state%2 == 1 && state < 11)
380  // {
381  // writeBuffer.resize(0);
382  // OtsUDPFirmwareCore::write(writeBuffer, 0x1003, 0xFF);
383  // OtsUDPHardware::write(writeBuffer);
384  // }
385  // else if(state%2 == 0 && state < 11)
386  // {
387  // writeBuffer.resize(0);
388  // OtsUDPFirmwareCore::write(writeBuffer, 0x1003,0);
389  // OtsUDPHardware::write(writeBuffer);
390  // }
391  // else
392  // state = -1;
393  //
394  // sleep(1);
395  // }
396  // }
397 
398  return false;
399 }
400 
401 //========================================================================================================================
402 //NOTE: buffer for address must be at least size universalAddressSize_
403 //NOTE: buffer for returnValue must be max UDP size to handle return possibility
404 void ots::FEOtsUDPProducerTemplateInterface::universalRead(char *address, char *returnValue)
405 {
406  __FE_COUT__ << "address size " << universalAddressSize_ << __E__;
407 
408  __FE_COUT__ << "Request: ";
409  for(unsigned int i=0;i<universalAddressSize_;++i)
410  printf("%2.2X",(unsigned char)address[i]);
411  std::cout << __E__;
412 
413  std::string readBuffer, sendBuffer;
414  OtsUDPFirmwareCore::readAdvanced(sendBuffer,address,1 /*size*/);
415 
416  OtsUDPHardware::read(sendBuffer, readBuffer); // data reply
417 
418  __FE_COUT__ << "Result SIZE: " << readBuffer.size() << __E__;
419  std::memcpy(returnValue,readBuffer.substr(2).c_str(),universalDataSize_);
420 } //end universalRead()
421 
422 //========================================================================================================================
423 //NOTE: buffer for address must be at least size universalAddressSize_
424 //NOTE: buffer for writeValue must be at least size universalDataSize_
425 void ots::FEOtsUDPProducerTemplateInterface::universalWrite(char* address, char* writeValue)
426 {
427  __FE_COUT__ << "address size " << universalAddressSize_ << __E__;
428  __FE_COUT__ << "data size " << universalDataSize_ << __E__;
429  __FE_COUT__ << "Sending: ";
430  for(unsigned int i=0;i<universalAddressSize_;++i)
431  printf("%2.2X",(unsigned char)address[i]);
432  std::cout << __E__;
433 
434  std::string sendBuffer;
435  OtsUDPFirmwareCore::writeAdvanced(sendBuffer,address,writeValue,1 /*size*/);
436  OtsUDPHardware::write(sendBuffer); // data request
437 } //end universalWrite()
438 
439 
440 
441 
442 //========================================================================================================================
443 //varTest
444 // FEMacro 'varTest' generated, Oct-11-2018 11:36:28, by 'admin' using MacroMaker.
445 // Macro Notes: This is a great test!
446 void FEOtsUDPProducerTemplateInterface::varTest(__ARGS__)
447 {
448  __FE_COUT__ << "# of input args = " << argsIn.size() << __E__;
449  __FE_COUT__ << "# of output args = " << argsOut.size() << __E__;
450  for(auto &argIn:argsIn)
451  __FE_COUT__ << argIn.first << ": " << argIn.second << __E__;
452 
453  //macro commands section
454  {
455  char *address = new char[universalAddressSize_]{0}; //create address buffer of interface size and init to all 0
456  char *data = new char[universalDataSize_]{0}; //create data buffer of interface size and init to all 0
457  uint64_t macroAddress; //create macro address buffer (size 8 bytes)
458  uint64_t macroData; //create macro address buffer (size 8 bytes)
459  std::map<std::string /*arg name*/,uint64_t /*arg val*/> macroArgs; //create map from arg name to 64-bit number
460 
461  // command-#0: Read(0x1002 /*address*/,myArg /*data*/);
462  macroAddress = 0x1002; memcpy(address,&macroAddress,8); //copy macro address to buffer
463  universalRead(address,data); memcpy(&macroArgs["myArg"],data,8); //copy buffer to argument map
464  __SET_ARG_OUT__("myArg",macroArgs["myArg"]); //update output argument result
465 
466  // command-#1: Read(0x1001 /*address*/,data);
467  macroAddress = 0x1001; memcpy(address,&macroAddress,8); //copy macro address to buffer
468  universalRead(address,data); memcpy(&macroArgs["outArg1"],data,8); //copy buffer to argument map
469  __SET_ARG_OUT__("outArg1",macroArgs["outArg1"]); //update output argument result
470 
471  // command-#2: Write(0x1002 /*address*/,myOtherArg /*data*/);
472  macroAddress = 0x1002; memcpy(address,&macroAddress,8); //copy macro address to buffer
473  macroArgs["myOtherArg"] = __GET_ARG_IN__("myOtherArg", uint64_t); //initialize from input arguments //get macro data argument
474  memcpy(data,&macroArgs["myOtherArg"],8); //copy macro data argument to buffer
475  universalWrite(address,data);
476 
477  // command-#3: Write(0x1001 /*address*/,myArg /*data*/);
478  macroAddress = 0x1001; memcpy(address,&macroAddress,8); //copy macro address to buffer //get macro data argument
479  memcpy(data,&macroArgs["myArg"],8); //copy macro data argument to buffer
480  universalWrite(address,data);
481 
482  // command-#4: delay(4);
483  __FE_COUT__ << "Sleeping for... " << 4 << " milliseconds " << __E__;
484  usleep(4*1000 /* microseconds */);
485 
486 
487  delete[] address; //free the memory
488  delete[] data; //free the memory
489  }
490 
491  for(auto &argOut:argsOut)
492  __FE_COUT__ << argOut.first << ": " << argOut.second << __E__;
493 
494 } //end varTest()
495 
496 
497 //========================================================================================================================
498 //varTest2
499 // FEMacro 'varTest2' generated, Oct-11-2018 02:28:57, by 'admin' using MacroMaker.
500 // Macro Notes: [Modified 14:28 10/11/2018] This is a great test!
501 void FEOtsUDPProducerTemplateInterface::varTest2(__ARGS__)
502 {
503  __FE_COUT__ << "# of input args = " << argsIn.size() << __E__;
504  __FE_COUT__ << "# of output args = " << argsOut.size() << __E__;
505  for(auto &argIn:argsIn)
506  __FE_COUT__ << argIn.first << ": " << argIn.second << __E__;
507 
508  //macro commands section
509  {
510  char *address = new char[universalAddressSize_]{0}; //create address buffer of interface size and init to all 0
511  char *data = new char[universalDataSize_]{0}; //create data buffer of interface size and init to all 0
512  uint64_t macroAddress; //create macro address buffer (size 8 bytes)
513  uint64_t macroData; //create macro address buffer (size 8 bytes)
514  std::map<std::string /*arg name*/,uint64_t /*arg val*/> macroArgs; //create map from arg name to 64-bit number
515 
516  // command-#0: Read(0x1002 /*address*/,myArg /*data*/);
517  macroAddress = 0x1002; memcpy(address,&macroAddress,8); //copy macro address to buffer
518  universalRead(address,data); memcpy(&macroArgs["myArg"],data,8); //copy buffer to argument map
519  __SET_ARG_OUT__("myArg",macroArgs["myArg"]); //update output argument result
520 
521  // command-#1: Read(0x1001 /*address*/,data);
522  macroAddress = 0x1001; memcpy(address,&macroAddress,8); //copy macro address to buffer
523  universalRead(address,data); memcpy(&macroArgs["outArg1"],data,8); //copy buffer to argument map
524  __SET_ARG_OUT__("outArg1",macroArgs["outArg1"]); //update output argument result
525 
526  // command-#2: Write(0x1002 /*address*/,myOtherArg /*data*/);
527  macroAddress = 0x1002; memcpy(address,&macroAddress,8); //copy macro address to buffer
528  macroArgs["myOtherArg"] = __GET_ARG_IN__("myOtherArg", uint64_t); //initialize from input arguments //get macro data argument
529  memcpy(data,&macroArgs["myOtherArg"],8); //copy macro data argument to buffer
530  universalWrite(address,data);
531 
532  // command-#3: Write(0x1001 /*address*/,myArg /*data*/);
533  macroAddress = 0x1001; memcpy(address,&macroAddress,8); //copy macro address to buffer //get macro data argument
534  memcpy(data,&macroArgs["myArg"],8); //copy macro data argument to buffer
535  universalWrite(address,data);
536 
537  // command-#4: delay(4);
538  __FE_COUT__ << "Sleeping for... " << 4 << " milliseconds " << __E__;
539  usleep(4*1000 /* microseconds */);
540 
541 
542  delete[] address; //free the memory
543  delete[] data; //free the memory
544  }
545 
546  for(auto &argOut:argsOut)
547  __FE_COUT__ << argOut.first << ": " << argOut.second << __E__;
548 
549 } //end varTest2()
550 
551 DEFINE_OTS_INTERFACE(FEOtsUDPProducerTemplateInterface)