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 "
utilities.hpp
"
4
#include <boost/lexical_cast.hpp>
5
#include <fmt/ranges.h>
6
7
#include "
logging/Logging.hpp
"
8
9
namespace
dunedaq
{
10
namespace
tdemodules
{
11
12
AMCProtocolClient::AMCProtocolClient
(
const
std::string& server_ip, uint16_t port)
13
:
m_host
(server_ip)
14
,
m_port
(port)
15
,
m_timeout
(50)
16
,
m_io_context
()
17
,
m_socket
(
m_io_context
)
18
{
19
20
using
boost::asio::ip::udp;
21
udp::resolver resolver(
m_io_context
);
22
m_server_endpoint
= *resolver.resolve(udp::v4(),
m_host
, std::to_string(
m_port
)).begin();
23
24
m_socket
.open(udp::v4());
25
m_socket
.non_blocking(
true
);
26
}
27
28
std::vector<uint8_t>
29
AMCProtocolClient::send_request
(
TFTPOpCode
opcode,
const
std::vector<uint8_t>& payload)
30
{
31
32
// Build TFTP RRQ or WRQ packet
33
// Switch to uin8_t
34
std::vector<uint8_t> request;
35
// request.push_back(static_cast<char>(opcode >> 8));
36
// request.push_back(static_cast<char>(opcode & 0xFF));
37
// append_bigendian(request, opcode);
38
append_big_uint16
(request, opcode);
39
request.insert(request.end(), payload.begin(), payload.end());
40
41
std::stringstream request_str;
42
for
(
size_t
i = 0; i < request.size(); ++i) {
43
request_str << std::setfill(
'0'
) << std::setw(2) << std::hex << +request[i] <<
" "
;
44
}
45
TLOG
() <<
"sending request to AMC: "
<< request_str.str();
46
47
m_socket
.send_to(boost::asio::buffer(request),
m_server_endpoint
);
48
49
std::vector<uint8_t> reply(516);
// TFTP packets max ~516 bytes
50
51
boost::asio::ip::udp::endpoint sender_endpoint;
52
boost::system::error_code ec;
53
54
size_t
len = 0;
55
for
(
int
i = 0; i <
m_timeout
; ++i) {
// wait up to ~5 seconds total
56
std::this_thread::sleep_for(std::chrono::milliseconds(100));
57
len =
m_socket
.receive_from(boost::asio::buffer(reply), sender_endpoint, 0, ec);
58
if
(!ec)
59
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
}
// namespace tdemodules
126
}
// namespace dunedaq
AMCProtocolClient.hpp
ERS_HERE
#define ERS_HERE
Definition
LocalContext.hpp:127
dunedaq::tdemodules::AMCProtocolClient::AMCProtocolClient
AMCProtocolClient(const std::string &server_ip, uint16_t port)
Definition
AMCProtocolClient.cpp:12
dunedaq::tdemodules::AMCProtocolClient::m_log_prefix
const std::string m_log_prefix
Definition
AMCProtocolClient.hpp:77
dunedaq::tdemodules::AMCProtocolClient::m_port
uint16_t m_port
Definition
AMCProtocolClient.hpp:74
dunedaq::tdemodules::AMCProtocolClient::m_timeout
uint16_t m_timeout
Definition
AMCProtocolClient.hpp:75
dunedaq::tdemodules::AMCProtocolClient::m_host
std::string m_host
Definition
AMCProtocolClient.hpp:73
dunedaq::tdemodules::AMCProtocolClient::send_request
std::vector< uint8_t > send_request(TFTPOpCode opcode, const std::vector< uint8_t > &payload)
Definition
AMCProtocolClient.cpp:29
dunedaq::tdemodules::AMCProtocolClient::m_server_endpoint
boost::asio::ip::udp::endpoint m_server_endpoint
Definition
AMCProtocolClient.hpp:81
dunedaq::tdemodules::AMCProtocolClient::m_io_context
boost::asio::io_context m_io_context
Definition
AMCProtocolClient.hpp:79
dunedaq::tdemodules::AMCProtocolClient::m_socket
boost::asio::ip::udp::socket m_socket
Definition
AMCProtocolClient.hpp:80
dunedaq::tdemodules::AMCProtocolClient::TFTPOpCode
TFTPOpCode
Definition
AMCProtocolClient.hpp:36
dunedaq::tdemodules::AMCProtocolClient::ERR
@ ERR
Definition
AMCProtocolClient.hpp:41
dunedaq::tdemodules::AMCProtocolClient::DAT
@ DAT
Definition
AMCProtocolClient.hpp:39
dunedaq::tdemodules::AMCProtocolClient::ACK
@ ACK
Definition
AMCProtocolClient.hpp:40
Logging.hpp
TLOG
#define TLOG(...)
Definition
macro.hpp:21
dunedaq::tdemodules
Definition
AMCController.hpp:17
dunedaq::tdemodules::append_big_uint16
void append_big_uint16(std::vector< uint8_t > &buffer, uint16_t value)
Definition
utilities.cpp:9
dunedaq
The DUNE-DAQ namespace.
Definition
cib_utilities.cpp:5
ers::error
void error(const Issue &issue)
Definition
ers.hpp:101
dunedaq::tdemodules::AMCProtocolClient::TFTP_Ack_Header
Definition
AMCProtocolClient.hpp:58
dunedaq::tdemodules::AMCProtocolClient::TFTP_Ack_Header::block
boost::endian::big_uint16_t block
Definition
AMCProtocolClient.hpp:60
dunedaq::tdemodules::AMCProtocolClient::TFTP_Data_Header
Definition
AMCProtocolClient.hpp:46
dunedaq::tdemodules::AMCProtocolClient::TFTP_Data_Header::block
boost::endian::big_uint16_t block
Definition
AMCProtocolClient.hpp:48
dunedaq::tdemodules::AMCProtocolClient::TFTP_Error_Header
Definition
AMCProtocolClient.hpp:52
dunedaq::tdemodules::AMCProtocolClient::TFTP_Error_Header::error_code
boost::endian::big_uint16_t error_code
Definition
AMCProtocolClient.hpp:54
utilities.hpp
Generated on
for DUNE-DAQ by
1.18.0