8 #include "art/Framework/Core/EDAnalyzer.h"
9 #include "art/Framework/Core/ModuleMacros.h"
10 #include "art/Framework/Principal/Run.h"
11 #include "art/Framework/Principal/Event.h"
12 #include "art/Framework/Principal/Handle.h"
13 #include "canvas/Utilities/Exception.h"
15 #include "artdaq-ots/Overlays/UDPFragment.hh"
16 #include "artdaq-core/Data/Fragment.hh"
17 #include "otsdaq-core/Macros/CoutMacros.h"
20 #include <boost/asio.hpp>
21 using boost::asio::ip::udp;
30 #include <arpa/inet.h>
40 virtual void analyze(art::Event
const & evt)
override;
41 virtual void beginRun(art::Run
const & run)
override;
45 std::string raw_data_label_;
46 std::string frag_type_;
47 boost::asio::io_service io_service_;
49 udp::endpoint remote_endpoint_;
54 ots::JSONDispatcher::JSONDispatcher(fhicl::ParameterSet
const & pset)
55 : art::EDAnalyzer(pset)
56 , prescale_(pset.get<int>(
"prescale",1))
57 , raw_data_label_(pset.get<std::string>(
"raw_data_label",
"daq"))
58 , frag_type_(pset.get<std::string>(
"frag_type",
"UDP"))
60 , socket_(io_service_, udp::v4())
62 std::cout << __COUT_HDR_FL__ <<
"JSONDispatcher Constructor Start" << std::endl;
63 int port = pset.get<
int>(
"port",35555);
66 boost::system::error_code ec;
67 socket_.set_option(boost::asio::socket_base::reuse_address(
true),ec);
69 mf::LogError(
"JSONDispatcher") <<
"An error occurred setting reuse_address: " << ec.message() << std::endl;
72 socket_.set_option(boost::asio::socket_base::broadcast(
true),ec);
74 mf::LogError(
"JSONDispatcher") <<
"An error occurred setting broadcast: " << ec.message() << std::endl;
78 remote_endpoint_ = udp::endpoint(boost::asio::ip::address_v4::broadcast(), port);
79 std::cout << __COUT_HDR_FL__ <<
"JSONDispatcher Constructor End" << std::endl;
82 ots::JSONDispatcher::~JSONDispatcher()
86 void ots::JSONDispatcher::beginRun(art::Run
const & run)
88 std::cout << __COUT_HDR_FL__ <<
"JSONDispatcher beginning run " << run.run() << std::endl;
92 void ots::JSONDispatcher::analyze(art::Event
const & evt)
95 art::EventNumber_t eventNumber = evt.event();
96 mf::LogInfo(
"JSONDispatcher") <<
"Received event with sequence ID " << eventNumber;
97 if((
int)eventNumber % prescale_ == 0) {
99 std::ostringstream outputJSON;
100 outputJSON <<
"{\"run\":" << std::to_string(evt.run()) <<
",\"subrun\":"<<std::to_string(evt.subRun()) <<
",\"event\":"<<std::to_string(eventNumber);
109 art::Handle<artdaq::Fragments> raw;
110 evt.getByLabel(raw_data_label_, frag_type_, raw);
111 outputJSON <<
",\"fragments\":[";
116 for (
size_t idx = 0; idx < raw->size(); ++idx)
118 if(idx > 0) { outputJSON <<
","; }
120 const auto& frag((*raw)[idx]);
125 if (frag.hasMetadata())
127 outputJSON <<
"\"metadata\":{";
130 outputJSON <<
"\"port\":"<<std::to_string(md->port)<<
",";
131 char buf[
sizeof(in_addr)];
132 struct sockaddr_in addr;
133 addr.sin_addr.s_addr = md->address;
134 inet_ntop(AF_INET, &(addr.sin_addr), buf, INET_ADDRSTRLEN);
135 outputJSON <<
"\"address\":\""<<std::string(buf) <<
"\"";
138 outputJSON <<
"\"header\":{";
139 outputJSON <<
"\"event_size\":"<<std::to_string(bb.hdr_event_size())<<
",";
140 outputJSON <<
"\"data_type\":"<<std::to_string(bb.hdr_data_type());
141 type = bb.hdr_data_type();
143 outputJSON <<
"\"data\":";
144 if(type == 0 || type > 2)
147 auto it = bb.dataBegin();
148 outputJSON << std::hex <<
"\"0x" << (int)*it <<
"\"" << std::dec;
151 for(; it !=bb.dataEnd(); ++it)
153 outputJSON <<
"," << std::hex <<
"\"0x" << (int)*it <<
"\"" << std::dec;
159 if(type == 2) { outputJSON <<
"\""; }
160 std::string output = std::string((
const char *)bb.dataBegin());
163 std::string find =
"\"";
164 std::string replace =
"\\\"";
165 for(std::string::size_type i = 0; (i = output.find(find, i)) != std::string::npos;)
167 output.replace(i, find.length(), replace);
168 i += replace.length();
171 outputJSON << output;
172 if(type == 2) { outputJSON <<
"\""; }
184 std::string s = outputJSON.str() +
"\0";
186 auto message = boost::asio::buffer(s);
188 socket_.send_to(message, remote_endpoint_);