DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
tdemodules
src
AMCProtocolClient.cpp
Go to the documentation of this file.
1
#include "
tdemodules/AMCProtocolClient.hpp
"
2
3
#include <boost/lexical_cast.hpp>
4
#include <fmt/ranges.h>
5
#include "
utilities.hpp
"
6
7
#include "
logging/Logging.hpp
"
8
9
namespace
dunedaq
{
10
namespace
tdemodules
{
11
12
13
AMCProtocolClient::AMCProtocolClient
(
const
std::string& server_ip, uint16_t port) :
14
m_host
(server_ip),
15
m_port
(port),
16
m_timeout
(50),
17
m_io_context
(),
18
m_socket
(
m_io_context
)
19
{
20
21
using
boost::asio::ip::udp;
22
udp::resolver resolver(
m_io_context
);
23
m_server_endpoint
= *resolver.resolve(udp::v4(),
m_host
, std::to_string(
m_port
)).begin();
24
25
m_socket
.open(udp::v4());
26
m_socket
.non_blocking(
true
);
27
28
}
29
30
std::vector<uint8_t>
31
AMCProtocolClient::send_request
(
TFTPOpCode
opcode,
const
std::vector<uint8_t>& payload) {
32
33
// Build TFTP RRQ or WRQ packet
34
// Switch to uin8_t
35
std::vector<uint8_t> request;
36
// request.push_back(static_cast<char>(opcode >> 8));
37
// request.push_back(static_cast<char>(opcode & 0xFF));
38
// append_bigendian(request, opcode);
39
append_big_uint16
(request, opcode);
40
request.insert( request.end(), payload.begin(), payload.end());
41
42
std::stringstream request_str;
43
for
(
size_t
i = 0; i < request.size(); ++i) {
44
request_str << std::setfill(
'0'
) << std::setw(2) << std::hex << +request[i] <<
" "
;
45
}
46
TLOG
() <<
"sending request to AMC: "
<< request_str.str();
47
48
m_socket
.send_to(boost::asio::buffer(request),
m_server_endpoint
);
49
50
std::vector<uint8_t> reply(516);
// TFTP packets max ~516 bytes
51
52
boost::asio::ip::udp::endpoint sender_endpoint;
53
boost::system::error_code ec;
54
55
size_t
len = 0;
56
for
(
int
i = 0; i <
m_timeout
; ++i) {
// wait up to ~5 seconds total
57
std::this_thread::sleep_for(std::chrono::milliseconds(100));
58
len =
m_socket
.receive_from(boost::asio::buffer(reply), sender_endpoint, 0, ec);
59
if
(!ec)
break
;
60
}
61
62
if
(ec) {
63
throw
AMCProtocolIssue(
ERS_HERE
,
m_log_prefix
,
"TFTP receive error: "
+ ec.message());
64
}
65
66
if
(len < 4) {
67
throw
AMCProtocolIssue(
ERS_HERE
,
m_log_prefix
,
"Invalid TFTP reply: too short"
);
68
}
69
if
(reply.size() < 4)
70
throw
std::runtime_error(
"Packet too short to be valid"
);
71
72
// Parse returin code
73
boost::endian::big_uint16_t rpl_opcode_be;
74
std::memcpy(&rpl_opcode_be, reply.data(),
sizeof
(rpl_opcode_be));
75
76
// A bit of overcasting here?
77
TFTPOpCode
rpl_opcode =
static_cast<
TFTPOpCode
>
(
static_cast<
uint16_t
>
(rpl_opcode_be));
78
79
switch
(rpl_opcode) {
80
case
TFTPOpCode::DAT
: {
81
if
(reply.size() <
sizeof
(
TFTP_Data_Header
))
82
throw
AMCProtocolIssue(
ERS_HERE
,
m_log_prefix
,
"Incomplete DATA packet"
);
83
84
TFTP_Data_Header
header;
85
std::memcpy(&header, reply.data(),
sizeof
(header));
86
87
TLOG
() <<
"Received DATA packet:\n"
<<
88
" Block #: "
<<
static_cast<
uint16_t
>
(header.
block
) <<
"\n"
<<
89
" Payload size: "
<< reply.size() -
sizeof
(header) <<
" bytes\n"
;
90
91
// Data starts at byte 3
92
reply.resize(len);
93
// Remove opcode
94
reply.erase(reply.begin(), reply.begin() + 2);
95
96
return
reply;
97
}
98
99
case
TFTPOpCode::ACK
: {
100
TFTP_Ack_Header
header;
101
std::memcpy(&header, reply.data(),
sizeof
(header));
102
103
TLOG
() <<
m_log_prefix
<<
"Recieved Ack packet:\n"
<<
static_cast<
uint16_t
>
(header.
block
);
104
return
{};
105
}
106
107
case
TFTPOpCode::ERR
: {
108
TFTP_Error_Header
header;
109
std::memcpy(&header, reply.data(),
sizeof
(header));
110
111
std::string error_msg(
reinterpret_cast<
const
char
*
>
(reply.data() +
sizeof
(header)),
112
reply.size() -
sizeof
(header));
113
114
ers::error
(AMCResponseErr(
ERS_HERE
,
m_log_prefix
,
static_cast<
uint16_t
>
(header.
error_code
), error_msg));
115
return
{};
116
}
117
118
default
:
119
ers::error
(AMCUnknownOpCode(
ERS_HERE
,
m_log_prefix
,
static_cast<
uint16_t
>
(opcode)));
120
121
return
{};
122
}
123
}
124
125
126
127
128
}
// namespace tdemodules
129
}
// namespace dunedaq
130
AMCProtocolClient.hpp
ERS_HERE
#define ERS_HERE
Definition
LocalContext.hpp:141
dunedaq::tdemodules::AMCProtocolClient::AMCProtocolClient
AMCProtocolClient(const std::string &server_ip, uint16_t port)
Definition
AMCProtocolClient.cpp:13
dunedaq::tdemodules::AMCProtocolClient::m_log_prefix
const std::string m_log_prefix
Definition
AMCProtocolClient.hpp:86
dunedaq::tdemodules::AMCProtocolClient::m_port
uint16_t m_port
Definition
AMCProtocolClient.hpp:83
dunedaq::tdemodules::AMCProtocolClient::m_timeout
uint16_t m_timeout
Definition
AMCProtocolClient.hpp:84
dunedaq::tdemodules::AMCProtocolClient::m_host
std::string m_host
Definition
AMCProtocolClient.hpp:82
dunedaq::tdemodules::AMCProtocolClient::send_request
std::vector< uint8_t > send_request(TFTPOpCode opcode, const std::vector< uint8_t > &payload)
Definition
AMCProtocolClient.cpp:31
dunedaq::tdemodules::AMCProtocolClient::m_server_endpoint
boost::asio::ip::udp::endpoint m_server_endpoint
Definition
AMCProtocolClient.hpp:90
dunedaq::tdemodules::AMCProtocolClient::m_io_context
boost::asio::io_context m_io_context
Definition
AMCProtocolClient.hpp:88
dunedaq::tdemodules::AMCProtocolClient::m_socket
boost::asio::ip::udp::socket m_socket
Definition
AMCProtocolClient.hpp:89
dunedaq::tdemodules::AMCProtocolClient::TFTPOpCode
TFTPOpCode
Definition
AMCProtocolClient.hpp:40
dunedaq::tdemodules::AMCProtocolClient::ERR
@ ERR
Definition
AMCProtocolClient.hpp:45
dunedaq::tdemodules::AMCProtocolClient::DAT
@ DAT
Definition
AMCProtocolClient.hpp:43
dunedaq::tdemodules::AMCProtocolClient::ACK
@ ACK
Definition
AMCProtocolClient.hpp:44
Logging.hpp
TLOG
#define TLOG(...)
Definition
macro.hpp:22
dunedaq::tdemodules
Definition
AMCController.hpp:19
dunedaq::tdemodules::append_big_uint16
void append_big_uint16(std::vector< uint8_t > &buffer, uint16_t value)
Definition
utilities.cpp:9
dunedaq
Including Qt Headers.
Definition
module.cpp:16
ers::error
void error(const Issue &issue)
Definition
ers.hpp:92
dunedaq::tdemodules::AMCProtocolClient::TFTP_Ack_Header
Definition
AMCProtocolClient.hpp:60
dunedaq::tdemodules::AMCProtocolClient::TFTP_Ack_Header::block
boost::endian::big_uint16_t block
Definition
AMCProtocolClient.hpp:62
dunedaq::tdemodules::AMCProtocolClient::TFTP_Data_Header
Definition
AMCProtocolClient.hpp:50
dunedaq::tdemodules::AMCProtocolClient::TFTP_Data_Header::block
boost::endian::big_uint16_t block
Definition
AMCProtocolClient.hpp:52
dunedaq::tdemodules::AMCProtocolClient::TFTP_Error_Header
Definition
AMCProtocolClient.hpp:55
dunedaq::tdemodules::AMCProtocolClient::TFTP_Error_Header::error_code
boost::endian::big_uint16_t error_code
Definition
AMCProtocolClient.hpp:57
utilities.hpp
Generated on
for DUNE-DAQ by
1.17.0