Line data Source code
1 : /**
2 : * @file HSIEventSender.cpp HSIEventSender class
3 : * implementation
4 : *
5 : * This is part of the DUNE DAQ Software Suite, copyright 2020.
6 : * Licensing/copyright details are in the COPYING file that you should have
7 : * received with this code.
8 : */
9 :
10 : #include "hsilibs/HSIEventSender.hpp"
11 :
12 : #include "iomanager/IOManager.hpp"
13 : #include "logging/Logging.hpp"
14 : #include "confmodel/DaqModule.hpp"
15 : #include "confmodel/Connection.hpp"
16 :
17 : #include <chrono>
18 : #include <cstdlib>
19 : #include <string>
20 : #include <thread>
21 : #include <vector>
22 :
23 : namespace dunedaq {
24 : namespace hsilibs {
25 :
26 0 : HSIEventSender::HSIEventSender(const std::string& name)
27 : : dunedaq::appfwk::DAQModule(name)
28 0 : , m_hsievent_send_connection("")
29 0 : , m_queue_timeout(1)
30 0 : , m_hsievent_sender(nullptr)
31 0 : , m_sent_counter(0)
32 0 : , m_failed_to_send_counter(0)
33 0 : , m_last_sent_timestamp(0)
34 : {
35 0 : }
36 :
37 : void
38 0 : HSIEventSender::init(std::shared_ptr<appfwk::ConfigurationManager> mcfg)
39 : {
40 0 : auto mdal = mcfg->get_dal<confmodel::DaqModule>(get_name()); // Only need generic DaqModule for output
41 :
42 0 : if (!mdal) {
43 0 : throw appfwk::CommandFailed(ERS_HERE, "init", get_name(), "Unable to retrieve configuration object");
44 : }
45 :
46 0 : for (auto con : mdal->get_outputs()) {
47 0 : if (con->get_data_type() == datatype_to_string<dfmessages::HSIEvent>()) {
48 0 : m_hsievent_send_connection = con->UID();
49 : }
50 : }
51 :
52 0 : m_hsievent_sender = get_iom_sender<dfmessages::HSIEvent>(m_hsievent_send_connection);
53 0 : }
54 :
55 : bool
56 0 : HSIEventSender::ready_to_send(std::chrono::milliseconds timeout)
57 : {
58 0 : if (m_hsievent_sender == nullptr) {
59 : return false;
60 : }
61 0 : return m_hsievent_sender->is_ready_for_sending(timeout);
62 : }
63 :
64 : void
65 0 : HSIEventSender::send_hsi_event(dfmessages::HSIEvent& event)
66 : {
67 0 : TLOG_DEBUG(3) << get_name() << ": Sending HSIEvent to " << m_hsievent_send_connection << ". \n"
68 0 : << event.header << ", " << std::bitset<32>(event.signal_map) << ", " << event.timestamp << ", "
69 0 : << event.sequence_counter << "\n";
70 :
71 0 : bool was_successfully_sent = false;
72 0 : while (!was_successfully_sent) {
73 0 : try {
74 0 : dfmessages::HSIEvent event_copy(event);
75 0 : m_hsievent_sender->send(std::move(event_copy), m_queue_timeout);
76 0 : ++m_sent_counter;
77 0 : m_last_sent_timestamp.store(event.timestamp);
78 0 : was_successfully_sent = true;
79 0 : } catch (const dunedaq::iomanager::TimeoutExpired& excpt) {
80 0 : std::ostringstream oss_warn;
81 0 : oss_warn << "push to output connection \"" << m_hsievent_send_connection << "\"";
82 0 : ers::error(dunedaq::iomanager::TimeoutExpired(ERS_HERE, get_name(), oss_warn.str(), m_queue_timeout.count()));
83 0 : ++m_failed_to_send_counter;
84 0 : }
85 : }
86 0 : if (m_sent_counter > 0 && m_sent_counter % 200000 == 0)
87 0 : TLOG_DEBUG(3) << "Have sent out " << m_sent_counter << " HSI events";
88 0 : }
89 :
90 : void
91 0 : HSIEventSender::send_raw_hsi_data(const std::array<uint32_t, 7>& raw_data, raw_sender_ct* sender)
92 : {
93 0 : HSI_FRAME_STRUCT payload;
94 0 : ::memcpy(&payload, &raw_data[0], sizeof(HSI_FRAME_STRUCT));
95 :
96 0 : TLOG_DEBUG(3) << get_name() << ": Sending HSI_FRAME_STRUCT " << std::hex << "0x" << payload.frame.version << ", 0x"
97 0 : << payload.frame.detector_id
98 :
99 0 : << "; 0x" << payload.frame.timestamp_low << "; 0x" << payload.frame.timestamp_high << "; 0x"
100 0 : << payload.frame.input_low << "; 0x" << payload.frame.input_high << "; 0x" << payload.frame.trigger
101 0 : << "; 0x" << payload.frame.sequence << std::endl;
102 :
103 0 : try {
104 : // TODO deal with this
105 0 : if (!sender) {
106 0 : throw(QueueIsNullFatalError(ERS_HERE, get_name(), "HSIEventSender output"));
107 : }
108 0 : sender->send(std::move(payload), m_queue_timeout);
109 0 : } catch (const dunedaq::iomanager::TimeoutExpired& excpt) {
110 0 : std::ostringstream oss_warn;
111 0 : oss_warn << "push to output raw hsi data queue failed";
112 0 : ers::error(dunedaq::iomanager::TimeoutExpired(ERS_HERE, get_name(), oss_warn.str(), m_queue_timeout.count()));
113 0 : ++m_failed_to_send_counter;
114 0 : }
115 0 : }
116 :
117 : } // namespace hsilibs
118 : } // namespace dunedaq
119 :
120 : // Local Variables:
121 : // c-basic-offset: 2
122 : // End:
|