artdaq  v3_09_00
transfer_plugin_receiver.cc
1 #include "artdaq/TransferPlugins/TransferInterface.hh"
2 
3 #include "artdaq-core/Data/Fragment.hh"
4 #include "artdaq-core/Utilities/ExceptionHandler.hh"
5 
6 #include "cetlib/BasicPluginFactory.h"
7 #include "cetlib/filepath_maker.h"
8 #include "cetlib_except/exception.h"
9 #include "fhiclcpp/ParameterSet.h"
10 #include "fhiclcpp/make_ParameterSet.h"
11 
12 #include <boost/asio.hpp>
13 #include <boost/bind.hpp>
14 
15 #include <iostream>
16 #include <limits>
17 #include <string>
18 
19 // DUPLICATED CODE: also found in transfer_plugin_sender.cpp. Not as egregious as
20 // normal in that this function is unlikely to be changed, and this is
21 // a standalone app (not part of artdaq)
22 
23 fhicl::ParameterSet ReadParameterSet(const std::string& fhicl_filename)
24 {
25  if (std::getenv("FHICL_FILE_PATH") == nullptr)
26  {
27  std::cerr
28  << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
29  setenv("FHICL_FILE_PATH", ".", 0);
30  }
31 
32  fhicl::ParameterSet pset;
33  cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
34  fhicl::make_ParameterSet(fhicl_filename, lookup_policy, pset);
35 
36  return pset;
37 }
38 
39 int do_check(const artdaq::Fragment& frag);
40 
41 int main(int argc, char* argv[])
42 try
43 {
44  if (argc != 2)
45  {
46  std::cerr << "Usage: transfer_plugin_receiver <fhicl document>" << std::endl;
47  return 1;
48  }
49 
50  auto fhicl_filename = boost::lexical_cast<std::string>(argv[1]); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
51 
52  std::unique_ptr<artdaq::TransferInterface> transfer;
53  auto pset = ReadParameterSet(fhicl_filename);
54 
55  try
56  {
57  static cet::BasicPluginFactory bpf("transfer", "make");
58 
59  transfer =
60  bpf.makePlugin<std::unique_ptr<artdaq::TransferInterface>,
61  const fhicl::ParameterSet&,
63  pset.get<std::string>("transfer_plugin_type"),
64  pset,
66  }
67  catch (...)
68  {
69  artdaq::ExceptionHandler(artdaq::ExceptionHandlerRethrow::no,
70  "Error creating transfer plugin");
71  return 1;
72  }
73 
74  while (true)
75  {
76  artdaq::Fragment myfrag;
77  size_t timeout = 10000000;
78 
79  auto retval = transfer->receiveFragment(myfrag, timeout);
80 
82  {
83  std::cout << "Returned from call to transfer_->receiveFragmentFrom; fragment with seqID == " << myfrag.sequenceID() << ", fragID == " << myfrag.fragmentID() << " has size " << myfrag.sizeBytes() << " bytes" << std::endl;
84  }
85  else
86  {
87  std::cerr << "RECV_TIMEOUT received from call to transfer->receiveFragmentFrom" << std::endl;
88  continue;
89  }
90 
91  if (do_check(myfrag) != 0)
92  {
93  std::cerr << "Error: do_check indicates fragment failed to transmit correctly" << std::endl;
94  }
95  else
96  {
97  std::cerr << "Success: do_check indicates fragment transmitted correctly" << std::endl;
98  }
99  }
100 
101  return 0;
102 }
103 catch (...)
104 {
105  return -1;
106 }
107 
108 // JCF, Jun-22-2016
109 
110 // do_check assumes std::iota was used to fill the sent fragment with
111 // monotonically incrementing 64-bit unsigned integers
112 
113 int do_check(const artdaq::Fragment& frag)
114 {
115  uint64_t variable_to_compare = 0;
116 
117  for (auto ptr_into_frag = reinterpret_cast<const uint64_t*>(frag.dataBeginBytes()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
118  ptr_into_frag != reinterpret_cast<const uint64_t*>(frag.dataEndBytes()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
119  ++ptr_into_frag, ++variable_to_compare)
120  {
121  if (variable_to_compare != *ptr_into_frag)
122  {
123  std::cerr << "ERROR for fragment with sequence ID " << frag.sequenceID() << ", fragment ID " << frag.fragmentID() << ": expected ADC value of " << variable_to_compare << ", got " << *ptr_into_frag << std::endl;
124  return 1;
125  }
126  }
127 
128  return 0;
129 }
This TransferInterface is a Receiver.
Role
Used to determine if a TransferInterface is a Sender or Receiver.
For code clarity, things checking for successful receive should check retval &gt;= NO_RANK_INFO.