56#if __linux__ || __APPLE__
68UDP_Port::UDP_Port(
const char* target_ip_,
int udp_port_) : lastStatus(), lock(), buff(), target_ip(target_ip_), rx_port(udp_port_)
70 initialize_defaults();
75 initialize_defaults();
81 pthread_mutex_destroy(&lock);
84void UDP_Port::initialize_defaults()
87 int result = pthread_mutex_init(&lock,
nullptr);
90 LOG_DEBUG(
"Mavlink - udp_port.cpp: mutex init failed");
97int UDP_Port::read_message(mavlink_message_t& message)
100 mavlink_status_t status;
101 uint8_t msgReceived =
false;
108 int result = _read_port(cp);
116 msgReceived = mavlink_parse_char(MAVLINK_COMM_1, cp, &message, &status);
119 if ((lastStatus.packet_rx_drop_count != status.packet_rx_drop_count) && debug)
122 LOG_ERROR(
"Mavlink - udp_port.cpp: DROPPED {} PACKETS\n", status.packet_rx_drop_count);
133 LOG_ERROR(
"Mavlink - udp_port.cpp: Could not read, res = {}, errno = {} \n", result, errno);
139 if (msgReceived && debug)
145 LOG_INFO(
"Mavlink - udp_port.cpp: Received UDP data: ");
146 std::array<uint8_t, MAVLINK_MAX_PACKET_LEN> buffer{};
149 auto messageLength = mavlink_msg_to_send_buffer(buffer.data(), &message);
152 if (messageLength > MAVLINK_MAX_PACKET_LEN)
155 LOG_ERROR(
"Mavlink - udp_port.cpp: FATAL ERROR: MESSAGE LENGTH IS LARGER THAN BUFFER SIZE");
161 for (
size_t i = 0; i < static_cast<size_t>(messageLength); i++)
163 [[maybe_unused]]
unsigned char v = buffer.at(i);
165 LOG_INFO(
"Mavlink - udp_port.cpp: {}", v);
177int UDP_Port::write_message(
const mavlink_message_t& message)
179 std::array<char, 300> buf{};
182 unsigned len = mavlink_msg_to_send_buffer(
reinterpret_cast<uint8_t*
>(buf.data()), &message);
185 int bytesWritten = _write_port(buf.data(), len);
186 if (bytesWritten < 0)
189 LOG_ERROR(
"Mavlink - udp_port.cpp: Could not write, res = {}, errno = {}\n", bytesWritten, errno);
201void UDP_Port::start()
208 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
211 LOG_ERROR(
"Mavlink - udp_port.cpp: error socket failed");
215 struct sockaddr_in addr
217 memset(&addr, 0,
sizeof(addr));
218 addr.sin_family = AF_INET;
219 addr.sin_addr.s_addr = inet_addr(target_ip);
221 addr.sin_port = htons(
static_cast<uint16_t
>(rx_port));
223 if (bind(sock,
reinterpret_cast<struct sockaddr*
>(&addr),
sizeof(
struct sockaddr)))
225 LOG_ERROR(
"Mavlink - udp_port.cpp: error bind failed");
241 LOG_INFO(
"Mavlink - udp_port.cpp: Listening to {}:{}\n", target_ip, rx_port);
242 lastStatus.packet_rx_drop_count = 0;
253 LOG_INFO(
"Mavlink - udp_port.cpp: CLOSE PORT");
255 int result = close(sock);
261 LOG_WARN(
"Mavlink - udp_port.cpp: Error on port close ({})\n", result);
272int UDP_Port::_read_port(uint8_t& cp)
277 pthread_mutex_lock(&lock);
280 if (buff_ptr < buff_len)
282 cp = buff.at(
static_cast<uint8_t
>(buff_ptr));
288 struct sockaddr_in addr
290 len =
sizeof(
struct sockaddr_in);
291 result =
static_cast<int>(recvfrom(sock, &buff, BUFF_LEN, 0,
reinterpret_cast<struct sockaddr*
>(&addr), &len));
294 if (strcmp(inet_ntoa(addr.sin_addr), target_ip) == 0)
296 tx_port = ntohs(addr.sin_port);
298 LOG_INFO(
"Mavlink - udp_port.cpp: Got first packet, sending to {}:{}\n", target_ip, rx_port);
303 LOG_ERROR(
"Mavlink - udp_port.cpp: Got packet from {}:{} but listening on {}\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), target_ip);
310 cp = buff.at(
static_cast<uint8_t
>(buff_ptr));
317 pthread_mutex_unlock(&lock);
325int UDP_Port::_write_port(
char* buf,
unsigned len)
328 pthread_mutex_lock(&lock);
331 int bytesWritten = 0;
334 struct sockaddr_in addr
336 memset(&addr, 0,
sizeof(addr));
337 addr.sin_family = AF_INET;
338 addr.sin_addr.s_addr = inet_addr(target_ip);
339 addr.sin_port = htons(
static_cast<uint16_t
>(tx_port));
340 bytesWritten =
static_cast<unsigned char>(sendto(sock, buf, len, 0,
reinterpret_cast<struct sockaddr*
>(&addr),
sizeof(
struct sockaddr_in)));
345 LOG_ERROR(
"Mavlink - udp_port.cpp: Sending before first packet received!\n");
350 pthread_mutex_unlock(&lock);
Utility class for logging to console and file.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
#define LOG_INFO
Info to the user on the state of the program.
UDP interface definition.