DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::tdemodules::AMCProtocolClient Class Reference

#include <AMCProtocolClient.hpp>

Classes

struct  TFTP_Ack_Header
 
struct  TFTP_Data_Header
 
struct  TFTP_Error_Header
 

Public Types

enum  TFTPOpCode : uint16_t {
  RRQ = 1 , WRQ = 2 , DAT = 3 , ACK = 4 ,
  ERR = 5
}
 

Public Member Functions

 AMCProtocolClient (const std::string &server_ip, uint16_t port)
 
std::vector< uint8_t > send_request (TFTPOpCode opcode, const std::vector< uint8_t > &payload)
 
std::vector< uint8_t > send_rrq (const std::vector< uint8_t > &payload)
 
std::vector< uint8_t > send_wrq (const std::vector< uint8_t > &payload)
 

Private Attributes

std::string m_host
 
uint16_t m_port
 
uint16_t m_timeout
 
const std::string m_log_prefix = "AMC with ip:" + m_host + " and port: " + std::to_string(m_port) + " | "
 
boost::asio::io_context m_io_context
 
boost::asio::ip::udp::socket m_socket
 
boost::asio::ip::udp::endpoint m_server_endpoint
 

Detailed Description

Definition at line 38 of file AMCProtocolClient.hpp.

Member Enumeration Documentation

◆ TFTPOpCode

Constructor & Destructor Documentation

◆ AMCProtocolClient()

dunedaq::tdemodules::AMCProtocolClient::AMCProtocolClient ( const std::string & server_ip,
uint16_t port )

Definition at line 13 of file AMCProtocolClient.cpp.

13 :
14 m_host(server_ip),
15 m_port(port),
16 m_timeout(50),
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}
boost::asio::ip::udp::endpoint m_server_endpoint
boost::asio::ip::udp::socket m_socket

Member Function Documentation

◆ send_request()

std::vector< uint8_t > dunedaq::tdemodules::AMCProtocolClient::send_request ( TFTPOpCode opcode,
const std::vector< uint8_t > & payload )

Definition at line 31 of file AMCProtocolClient.cpp.

31 {
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}
#define ERS_HERE
#define TLOG(...)
Definition macro.hpp:22
void append_big_uint16(std::vector< uint8_t > &buffer, uint16_t value)
Definition utilities.cpp:9
void error(const Issue &issue)
Definition ers.hpp:81

◆ send_rrq()

std::vector< uint8_t > dunedaq::tdemodules::AMCProtocolClient::send_rrq ( const std::vector< uint8_t > & payload)
inline

Definition at line 72 of file AMCProtocolClient.hpp.

72 {
73 return send_request(RRQ, payload);
74 }
std::vector< uint8_t > send_request(TFTPOpCode opcode, const std::vector< uint8_t > &payload)

◆ send_wrq()

std::vector< uint8_t > dunedaq::tdemodules::AMCProtocolClient::send_wrq ( const std::vector< uint8_t > & payload)
inline

Definition at line 76 of file AMCProtocolClient.hpp.

76 {
77 return send_request(WRQ, payload);
78 }

Member Data Documentation

◆ m_host

std::string dunedaq::tdemodules::AMCProtocolClient::m_host
private

Definition at line 82 of file AMCProtocolClient.hpp.

◆ m_io_context

boost::asio::io_context dunedaq::tdemodules::AMCProtocolClient::m_io_context
private

Definition at line 88 of file AMCProtocolClient.hpp.

◆ m_log_prefix

const std::string dunedaq::tdemodules::AMCProtocolClient::m_log_prefix = "AMC with ip:" + m_host + " and port: " + std::to_string(m_port) + " | "
private

Definition at line 86 of file AMCProtocolClient.hpp.

◆ m_port

uint16_t dunedaq::tdemodules::AMCProtocolClient::m_port
private

Definition at line 83 of file AMCProtocolClient.hpp.

◆ m_server_endpoint

boost::asio::ip::udp::endpoint dunedaq::tdemodules::AMCProtocolClient::m_server_endpoint
private

Definition at line 90 of file AMCProtocolClient.hpp.

◆ m_socket

boost::asio::ip::udp::socket dunedaq::tdemodules::AMCProtocolClient::m_socket
private

Definition at line 89 of file AMCProtocolClient.hpp.

◆ m_timeout

uint16_t dunedaq::tdemodules::AMCProtocolClient::m_timeout
private

Definition at line 84 of file AMCProtocolClient.hpp.


The documentation for this class was generated from the following files: