From 51690ba0df060d97c623da6eadb2e088b0b5ecd7 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 14 Feb 2016 06:20:17 +0000 Subject: [PATCH] Get to where we're actually finding airspy packet boundaries. --- Makefile | 4 +-- adsbus.c | 74 ++++++++++++++++----------------------------------- airspy_adsb.c | 20 ++++++++++++++ airspy_adsb.h | 3 +++ common.c | 47 ++++++++++++++++++++++++++++++++ common.h | 32 ++++++++++++++++++++++ 6 files changed, 127 insertions(+), 53 deletions(-) create mode 100644 airspy_adsb.c create mode 100644 airspy_adsb.h create mode 100644 common.c create mode 100644 common.h diff --git a/Makefile b/Makefile index e3b6888..c89e29a 100644 --- a/Makefile +++ b/Makefile @@ -10,5 +10,5 @@ clean: %.o: %.c *.h $(CC) -c $(CFLAGS) $< -o $@ -adsbus: adsbus.o - $(CC) $(LDFLAGS) -o adsbus adsbus.o +adsbus: adsbus.o airspy_adsb.o common.o + $(CC) $(LDFLAGS) -o adsbus adsbus.o airspy_adsb.o common.o diff --git a/adsbus.c b/adsbus.c index cc6b155..288cde6 100644 --- a/adsbus.c +++ b/adsbus.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,6 +9,9 @@ #include #include +#include "common.h" +#include "airspy_adsb.h" + struct opts { char *backend_node; @@ -15,15 +19,7 @@ struct opts { }; -#define BUF_LEN 4096 -struct buf { - char buf[BUF_LEN]; - size_t start; - size_t length; -}; - - -int parseOpts(int argc, char *argv[], struct opts *opts) { +int parse_opts(int argc, char *argv[], struct opts *opts) { int opt; while ((opt = getopt(argc, argv, "h:p:")) != -1) { switch (opt) { @@ -43,7 +39,7 @@ int parseOpts(int argc, char *argv[], struct opts *opts) { } -int connectBackend(struct opts *opts) { +int connect_backend(struct opts *opts) { struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, @@ -90,32 +86,6 @@ int connectBackend(struct opts *opts) { } -int readToBuf(int fd, struct buf *buf) { - struct iovec iov[2]; - int iovcnt; - size_t space = BUF_LEN - buf->length; - size_t end = (buf->start + buf->length) % BUF_LEN; - if (end + space > BUF_LEN) { - // Wraps around - iovcnt = 2; - iov[0].iov_base = &buf->buf[end]; - iov[0].iov_len = BUF_LEN - end; - iov[1].iov_base = 0; - iov[1].iov_len = space - iov[0].iov_len; - } else { - iovcnt = 1; - iov[0].iov_base = &buf->buf[end]; - iov[0].iov_len = space; - } - ssize_t in = readv(fd, iov, iovcnt); - if (in < 0) { - return in; - } - buf->length += in; - return in; -} - - int loop(int bfd) { int efd = epoll_create(10); if (efd == -1) { @@ -136,10 +106,9 @@ int loop(int bfd) { } } - struct buf buf = { - .start = 0, - .length = 0, - }; + struct buf buf; + char buf_main[BUF_LEN], buf_temp[BUF_LEN]; + buf_init(&buf, buf_main, buf_temp); while (1) { #define MAX_EVENTS 10 @@ -152,19 +121,26 @@ int loop(int bfd) { for (int n = 0; n < nfds; n++) { if (events[n].data.fd == bfd) { - if (readToBuf(bfd, &buf) < 0) { + if (buf_fill(&buf, bfd) < 0) { fprintf(stderr, "Connection closed by backend\n"); return -1; } - fprintf(stderr, "buf len is now %d\n", buf.length); + + struct buf tmp; + struct packet packet; + buf_alias(&tmp, &buf); + while (airspy_adsb_parse(&tmp, &packet)) { + buf_alias(&buf, &tmp); + fprintf(stderr, "packet!\n"); + } + if (buf.length == BUF_LEN) { + fprintf(stderr, "Input buffer overrun\n"); return -1; } } } } - - return 0; } @@ -173,22 +149,18 @@ int main(int argc, char *argv[]) { .backend_node = "localhost", .backend_service = "30006", }; - if (parseOpts(argc, argv, &opts)) { + if (parse_opts(argc, argv, &opts)) { fprintf(stderr, "Usage: %s [-h backend_host] [-p backend_port]\n", argv[0]); return EXIT_FAILURE; } - int bfd = connectBackend(&opts); + int bfd = connect_backend(&opts); if (bfd < 0) { fprintf(stderr, "Unable to connect to %s/%s\n", opts.backend_node, opts.backend_service); return EXIT_FAILURE; } - if (loop(bfd)) { - fprintf(stderr, "Main loop exited with error\n"); - return EXIT_FAILURE; - } - + loop(bfd); close(bfd); return EXIT_SUCCESS; } diff --git a/airspy_adsb.c b/airspy_adsb.c new file mode 100644 index 0000000..20be191 --- /dev/null +++ b/airspy_adsb.c @@ -0,0 +1,20 @@ +#include + +#include "common.h" +#include "airspy_adsb.h" + +bool airspy_adsb_parse(struct buf *buf, struct packet *packet) { + if (buf->length < 35) { + // Minimum frame length + return false; + } + if (buf->buf[buf->start] != '*') { + return false; + } + char *last = memchr(&buf->buf[buf->start], '\n', buf->length); + if (!last) { + return false; + } + buf_consume(buf, last - &buf->buf[buf->start] + 1); + return true; +} diff --git a/airspy_adsb.h b/airspy_adsb.h new file mode 100644 index 0000000..3195572 --- /dev/null +++ b/airspy_adsb.h @@ -0,0 +1,3 @@ +#include + +bool airspy_adsb_parse(struct buf *, struct packet *); diff --git a/common.c b/common.c new file mode 100644 index 0000000..dd84a20 --- /dev/null +++ b/common.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +#include "common.h" + + +void buf_init(struct buf *buf, char *main, char *tmp) { + buf->buf = main; + buf->tmp = tmp; + buf->start = 0; + buf->length = 0; +} + +void buf_alias(struct buf *to, struct buf *from) { + memcpy(to, from, sizeof(*to)); +} + +ssize_t buf_fill(struct buf *buf, int fd) { + if (buf->start + buf->length == BUF_LEN) { + assert(buf->start > 0); + memmove(buf->buf, &buf->buf[buf->start], buf->length); + buf->start = 0; + } + + size_t space = BUF_LEN - buf->length - buf->start; + size_t end = buf->start + buf->length; + ssize_t in = read(fd, &buf->buf[end], space); + if (in < 0) { + return in; + } + buf->length += in; + return in; +} + +void buf_consume(struct buf *buf, size_t length) { + assert(buf->length >= length); + + buf->length -= length; + if (buf->length) { + buf->start += length; + } else { + buf->start = 0; + } +} diff --git a/common.h b/common.h new file mode 100644 index 0000000..d3d6dfb --- /dev/null +++ b/common.h @@ -0,0 +1,32 @@ +#include +#include + + +#define BUF_LEN 4096 +struct buf { + char *buf; + char *tmp; + size_t start; + size_t length; +}; + + +#define MLAT_HZ 60000000 +#define DATA_MAX 14 +struct packet { + enum { + MODE_AC, + MODE_S_SHORT, + MODE_S_LONG, + } type; + char data[DATA_MAX]; + uint64_t mlat_timestamp; + uint32_t rssi; +}; + + +void buf_init(struct buf *, char *, char *); +void buf_alias(struct buf *, struct buf *); + +ssize_t buf_fill(struct buf *, int); +void buf_consume(struct buf *, size_t);