44 #include <px4_platform_common/sem.hpp> 45 #include <px4_platform_common/log.h> 47 #include <sys/ioctl.h> 76 void move(
void *dest,
size_t pos,
size_t n);
78 uint8_t buffer[512] = {};
81 static const size_t BUFFER_THRESHOLD =
sizeof(buffer) * 0.8;
94 if (buf_size > BUFFER_THRESHOLD) {
98 int r =
::read(fd, buffer + buf_size,
sizeof(buffer) - buf_size);
111 ASSERT(pos < buf_size);
112 ASSERT(pos + n <= buf_size);
114 memmove(dest, buffer + pos, n);
115 memmove(buffer + pos, buffer + (pos + n),
sizeof(buffer) - pos - n);
125 virtual int ioctl(
struct file *filp,
int cmd,
unsigned long arg);
127 virtual int open(
file *filp);
128 virtual int close(
file *filp);
134 virtual pollevent_t poll_state(
struct file *filp);
139 sem_t *this_lock = op == Read ? &objects->r_lock : &objects->w_lock;
141 while (sem_wait(this_lock) != 0) {
145 ASSERT(get_errno() == EINTR);
151 sem_t *this_lock = op == Read ? &objects->r_lock : &objects->w_lock;
164 bool _had_data =
false;
185 if (cmd == FIONSPACE) {
190 return ::ioctl(
_fd, cmd, arg);
195 _fd =
::open(objects->device_name, O_RDWR | O_NOCTTY);
197 return _fd >= 0 ? 0 : -1;
213 fds[0].events = POLLIN;
223 int ret =
::poll(fds,
sizeof(fds) /
sizeof(fds[0]), 100);
224 _had_data = ret > 0 && (fds[0].revents & POLLIN);
235 virtual ssize_t
read(
struct file *filp,
char *buffer,
size_t buflen);
236 virtual ssize_t
write(
struct file *filp,
const char *buffer,
size_t buflen);
240 size_t _remaining_partial = 0;
241 size_t _partial_start = 0;
242 uint8_t _partial_buffer[512] = {};
247 , _read_buffer{read_buffer}
254 uint16_t packet_len = 0;
310 packet_len = payload_len + 12;
312 if (incompat_flags & 0x1) {
327 if (packet_len > buflen) {
358 if ((
unsigned char)buffer[0] == 253) {
359 uint8_t payload_len = buffer[1];
360 uint8_t incompat_flags = buffer[2];
363 if (incompat_flags & 0x1) {
370 }
else if ((
unsigned char)buffer[0] == 254) {
371 uint8_t payload_len = buffer[1];
378 PX4_ERR(
"parser error");
387 ::ioctl(
_fd, FIONSPACE, (
unsigned long)&buf_free);
389 if (buf_free < (
int)buflen) {
416 virtual ssize_t
read(
struct file *filp,
char *buffer,
size_t buflen);
417 virtual ssize_t
write(
struct file *filp,
const char *buffer,
size_t buflen);
422 static const uint8_t HEADER_SIZE = 9;
434 uint16_t packet_len, payload_len;
474 if (packet_len > buflen) {
497 uint16_t payload_len;
503 if (memcmp(buffer,
">>>", 3) != 0) {
504 PX4_ERR(
"parser error");
508 payload_len = ((uint16_t)buffer[5] << 8) | buffer[6];
518 ::ioctl(
_fd, FIONSPACE, (
unsigned long)&buf_free);
521 if ((
unsigned)buf_free < buflen) {
551 if (!strcmp(argv[1],
"start")) {
553 PX4_ERR(
"already running");
564 PX4_ERR(
"alloc failed");
568 strncpy(objects->device_name, argv[2],
sizeof(objects->device_name));
569 sem_init(&objects->r_lock, 1, 1);
570 sem_init(&objects->w_lock, 1, 1);
572 objects->mavlink2 =
new Mavlink2Dev(objects->read_buffer);
573 objects->rtps =
new RtpsDev(objects->read_buffer);
575 if (!objects->mavlink2 || !objects->rtps) {
576 delete objects->mavlink2;
577 delete objects->rtps;
578 delete objects->read_buffer;
579 sem_destroy(&objects->r_lock);
580 sem_destroy(&objects->w_lock);
583 PX4_ERR(
"alloc failed");
587 objects->mavlink2->init();
588 objects->rtps->init();
592 if (!strcmp(argv[1],
"stop")) {
594 delete objects->mavlink2;
595 delete objects->rtps;
596 delete objects->read_buffer;
597 sem_destroy(&objects->r_lock);
598 sem_destroy(&objects->w_lock);
607 if (!strcmp(argv[1],
"status")) {
612 PX4_INFO(
"not running");
619 PX4_ERR(
"unrecognized command, try 'start <device>', 'stop', 'status'");
virtual int open(file *filp)
void unlock(enum Operation op)
size_t _remaining_partial
void lock()
Take the driver lock.
RtpsDev(ReadBuffer *_read_buffer)
Mavlink2Dev(ReadBuffer *_read_buffer)
virtual ssize_t read(struct file *filp, char *buffer, size_t buflen)
virtual ssize_t read(struct file *filp, char *buffer, size_t buflen)
ReadBuffer * _read_buffer
virtual ssize_t write(struct file *filp, const char *buffer, size_t buflen)
virtual int ioctl(struct file *filp, int cmd, unsigned long arg)
virtual ssize_t read(file_t *filep, char *buffer, size_t buflen)
Perform a read from the device.
static void read(bootloader_app_shared_t *pshared)
virtual int close(file *filp)
bool _had_data
whether poll() returned available data
Abstract class for any character device.
void lock(enum Operation op)
ReadBuffer * _read_buffer
static const uint8_t HEADER_SIZE
virtual pollevent_t poll_state(struct file *filp)
virtual ssize_t write(file_t *filep, const char *buffer, size_t buflen)
Perform a write to the device.
struct @83::@85::@87 file
virtual ssize_t write(struct file *filp, const char *buffer, size_t buflen)
uint8_t _partial_buffer[512]
DevCommon(const char *device_path)
__EXPORT int protocol_splitter_main(int argc, char *argv[])
void move(void *dest, size_t pos, size_t n)
void unlock()
Release the driver lock.
ParserState _parser_state
virtual int poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
Perform a poll setup/teardown operation.