Skip to content

Commit f96a9fb

Browse files
committed
Telem_UDP: create a basic UDP client
1 parent 3cee03b commit f96a9fb

5 files changed

+249
-1
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ SRCS_CPP += common_tool.cpp
8181
SRCS_CPP += telem_client.cpp
8282
SRCS_CPP += telem_forwarder_client.cpp
8383
SRCS_CPP += telem_serial.cpp
84+
SRCS_CPP += telem_udp.cpp
8485
SRCS_CPP += dataflash_logger.cpp
8586
SRCS_CPP += analyzing_dataflash_message_handler.cpp
8687
SRCS_CPP += LA_MsgHandler.cpp

dataflash_logger_program.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "mavlink_reader.h"
66
#include "telem_forwarder_client.h"
77
#include "telem_serial.h"
8+
#include "telem_udp.h"
89

910
#include "la-log.h"
1011

@@ -27,6 +28,7 @@ void DataFlash_Logger_Program::usage()
2728
::printf(" -h display usage information\n");
2829
::printf(" -d debug mode\n");
2930
::printf(" -s use serial port\n");
31+
::printf(" -u use UDP port\n");
3032
::printf("\n");
3133
::printf("Example: %s\n", program_name());
3234
exit(0);
@@ -127,6 +129,21 @@ void DataFlash_Logger_Program::create_telem_forwarder_client()
127129
client->telem_client->init();
128130
}
129131

132+
void DataFlash_Logger_Program::create_udp_client()
133+
{
134+
client = new DLP_Client();
135+
client->reader = new MAVLink_Reader(config());
136+
if (client->reader == NULL) {
137+
la_log(LOG_ERR, "Failed to create reader from (%s)\n", config_filename);
138+
exit(1);
139+
}
140+
141+
client->telem_client = new Telem_UDP();
142+
143+
client->telem_client->configure(config());
144+
client->telem_client->init();
145+
}
146+
130147
void DataFlash_Logger_Program::run()
131148
{
132149
init_config();
@@ -140,6 +157,8 @@ void DataFlash_Logger_Program::run()
140157

141158
if (serial_port) {
142159
create_serial_client();
160+
} else if (udp_port) {
161+
create_udp_client();
143162
} else {
144163
create_telem_forwarder_client();
145164
}
@@ -176,7 +195,7 @@ void DataFlash_Logger_Program::parse_arguments(int argc, char *argv[])
176195
_argc = argc;
177196
_argv = argv;
178197

179-
while ((opt = getopt(argc, argv, "hc:ds")) != -1) {
198+
while ((opt = getopt(argc, argv, "hc:dsu")) != -1) {
180199
switch(opt) {
181200
case 'h':
182201
usage();
@@ -190,6 +209,9 @@ void DataFlash_Logger_Program::parse_arguments(int argc, char *argv[])
190209
case 's':
191210
serial_port = true;
192211
break;
212+
case 'u':
213+
udp_port = true;
214+
break;
193215
}
194216
}
195217
}

dataflash_logger_program.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,9 @@ class DataFlash_Logger_Program : public Common_Tool {
5050

5151
void create_telem_forwarder_client();
5252
void create_serial_client();
53+
void create_udp_client();
5354

55+
bool udp_port = false;
56+
// uint8_t _writer_buf[_writer_buflen] = { };
57+
uint32_t canary = 9876543;
5458
};

telem_udp.cpp

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#include "telem_udp.h"
2+
3+
#include <errno.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
7+
#include "la-log.h"
8+
9+
#ifdef _WIN32
10+
#include <ws2tcpip.h>
11+
#endif
12+
13+
#define UNUSED __attribute__ ((unused))
14+
15+
void Telem_UDP::pack_select_fds(fd_set &fds_read,
16+
fd_set &fds_write UNUSED,
17+
fd_set &fds_err,
18+
uint8_t &nfds)
19+
{
20+
FD_SET(fd, &fds_read);
21+
FD_SET(fd, &fds_err);
22+
23+
if (fd >= nfds) {
24+
nfds = fd + 1;
25+
}
26+
}
27+
28+
29+
void Telem_UDP::handle_select_fds(fd_set &fds_read,
30+
fd_set &fds_write UNUSED,
31+
fd_set &fds_err,
32+
uint8_t &nfds UNUSED)
33+
{
34+
/* check for packets from source */
35+
if (FD_ISSET(fd, &fds_err)) {
36+
FD_CLR(fd, &fds_err);
37+
la_log(LOG_ERR, "select(fd): %s", strerror(errno));
38+
}
39+
40+
if (FD_ISSET(fd, &fds_read)) {
41+
FD_CLR(fd, &fds_read);
42+
_recv_buflen_content = handle_recv();
43+
// ::fprintf(stderr, "received %u bytes\n", _recv_buflen_content);
44+
}
45+
}
46+
47+
48+
void Telem_UDP::create_and_bind()
49+
{
50+
int _fd;
51+
struct sockaddr_in sa;
52+
53+
_fd = socket(AF_INET, SOCK_DGRAM, 0);
54+
if (_fd < 0) {
55+
perror("socket");
56+
abort();
57+
}
58+
59+
memset(&sa, 0, sizeof(sa));
60+
sa.sin_family = AF_INET;
61+
sa.sin_addr.s_addr = htonl(INADDR_ANY);
62+
sa.sin_port = 0; // we don't care what our port is
63+
64+
if (bind(_fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
65+
perror("bind");
66+
abort();
67+
}
68+
69+
fd = _fd;
70+
}
71+
72+
73+
std::string Telem_UDP::udp_ip(INIReader *config) const
74+
{
75+
return config->Get("dflogger", "udp_ip", "127.0.0.1");
76+
}
77+
78+
uint16_t Telem_UDP::udp_port(INIReader *config) const
79+
{
80+
return config->GetInteger("dflogger", "udp_port", 14550);
81+
}
82+
83+
void Telem_UDP::pack_sockaddr(INIReader *config)
84+
{
85+
// uint16_t tf_port = config->GetInteger("solo", "telem_forward_port", 14560);
86+
const uint16_t tf_port = udp_port(config);
87+
const std::string ip = udp_ip(config);
88+
89+
la_log(LOG_INFO, "df-udp: connecting to %s:%u", ip.c_str(), tf_port);
90+
memset(&sa_tf, 0, sizeof(sa_tf));
91+
sa_tf.sin_family = AF_INET;
92+
#ifdef _WIN32
93+
sa_tf.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
94+
#else
95+
inet_aton(ip.c_str(), &sa_tf.sin_addr); // useful for debugging
96+
#endif
97+
sa_tf.sin_port = htons(tf_port);
98+
}
99+
100+
bool Telem_UDP::sane_recv_buf(uint8_t *pkt UNUSED, uint16_t pktlen UNUSED) const
101+
{
102+
return true;
103+
}
104+
105+
uint32_t Telem_UDP::handle_recv()
106+
{
107+
// ::printf("Receiving packet into position %u\n", _buflen_content);
108+
socklen_t sa_len = sizeof(sa);
109+
uint16_t res = recvfrom(fd,
110+
(char*)&_recv_buf[_recv_buflen_content],
111+
_recv_buflen-_recv_buflen_content,
112+
0,
113+
(struct sockaddr*)&sa,
114+
&sa_len);
115+
116+
if (!sane_recv_buf(_recv_buf, res)) {
117+
return 0;
118+
}
119+
120+
return res;
121+
}
122+
123+
bool Telem_UDP::send_message(const mavlink_message_t &msg)
124+
{
125+
if (send_buffer_space_free() < 1) {
126+
// dropped_packets++;
127+
return false;
128+
}
129+
memcpy(&_send_buf[_send_buf_stop++], (char*)&msg, sizeof(msg));
130+
if (_send_buf_stop >= send_buf_size()) {
131+
_send_buf_stop = 0;
132+
}
133+
return true;
134+
}
135+
136+
137+
void Telem_UDP::do_writer_sends()
138+
{
139+
char buf[1024]; // large enough...
140+
141+
while (_send_buf_start != _send_buf_stop) {
142+
mavlink_message_t &msg = _send_buf[_send_buf_start];
143+
uint16_t messageLen = mavlink_msg_to_send_buffer((uint8_t*)buf,&msg);
144+
145+
int32_t bytes_sent =
146+
sendto(fd, buf, messageLen, 0,
147+
(struct sockaddr *)&sa_tf, sizeof(struct sockaddr));
148+
if (bytes_sent == -1) {
149+
la_log(LOG_INFO, "Failed sendto: %s", strerror(errno));
150+
// we drop the message anyway!
151+
}
152+
_send_buf_start++;
153+
if (_send_buf_start >= send_buf_size()) {
154+
_send_buf_start = 0;
155+
}
156+
}
157+
158+
return;
159+
}
160+
161+
void Telem_UDP::configure(INIReader *config)
162+
{
163+
pack_sockaddr(config);
164+
165+
}
166+
167+
void Telem_UDP::init() {
168+
create_and_bind();
169+
}

telem_udp.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "INIReader.h"
2+
3+
#ifdef _WIN32
4+
#include <Winsock2.h>
5+
#else
6+
#include <sys/socket.h>
7+
#include <netinet/in.h>
8+
#include <arpa/inet.h>
9+
#endif
10+
11+
#include "telem_client.h"
12+
13+
class Telem_UDP : public Telem_Client {
14+
public:
15+
16+
Telem_UDP() :
17+
Telem_Client()
18+
{ }
19+
20+
uint32_t handle_recv();
21+
void init() override;
22+
23+
void configure(INIReader *config) override;
24+
void pack_select_fds(fd_set &fds_read, fd_set &fds_write, fd_set &fds_err, uint8_t &nfds) override;
25+
void handle_select_fds(fd_set &fds_read, fd_set &fds_write, fd_set &fds_err, uint8_t &nfds) override;
26+
27+
void do_writer_sends() override;
28+
bool send_message(const mavlink_message_t &msg) override;
29+
bool any_data_to_send() override {
30+
return _send_buf_start != _send_buf_stop;
31+
}
32+
33+
private:
34+
int fd = -1;
35+
36+
struct sockaddr_in sa; // our send-from address
37+
struct sockaddr_in sa_tf; /* udp address to connect to */
38+
39+
void create_and_bind();
40+
void pack_sockaddr(INIReader *config);
41+
bool sane_packet(uint8_t *pkt, uint16_t bpktlen);
42+
virtual bool sane_recv_buf(uint8_t *pkt, uint16_t pktlen) const;
43+
44+
/* send buffer stuff: */
45+
mavlink_message_t _send_buf[256]; // way too big?
46+
uint32_t send_buf_size() const override {
47+
return 256;
48+
}
49+
50+
std::string udp_ip(INIReader *config) const;
51+
uint16_t udp_port(INIReader *config) const;
52+
};

0 commit comments

Comments
 (0)