31 {
32
33
34
35 std::vector<uint8_t> request;
36
37
38
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
49
50 std::vector<uint8_t> reply(516);
51
52 boost::asio::ip::udp::endpoint sender_endpoint;
53 boost::system::error_code ec;
54
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) {
64 }
65
66 if (len < 4) {
68 }
69 if (reply.size() < 4)
70 throw std::runtime_error("Packet too short to be valid");
71
72
73 boost::endian::big_uint16_t rpl_opcode_be;
74 std::memcpy(&rpl_opcode_be, reply.data(), sizeof(rpl_opcode_be));
75
76
78
79 switch (rpl_opcode) {
81 if (reply.size() < sizeof(TFTP_Data_Header))
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
92 reply.resize(len);
93
94 reply.erase(reply.begin(), reply.begin() + 2);
95
96 return reply;
97 }
98
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
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
115 return {};
116 }
117
118 default:
120
121 return {};
122 }
123}
const std::string m_log_prefix
void append_big_uint16(std::vector< uint8_t > &buffer, uint16_t value)
void error(const Issue &issue)