Get to where we're actually finding airspy packet boundaries.
This commit is contained in:
4
Makefile
4
Makefile
@@ -10,5 +10,5 @@ clean:
|
|||||||
%.o: %.c *.h
|
%.o: %.c *.h
|
||||||
$(CC) -c $(CFLAGS) $< -o $@
|
$(CC) -c $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
adsbus: adsbus.o
|
adsbus: adsbus.o airspy_adsb.o common.o
|
||||||
$(CC) $(LDFLAGS) -o adsbus adsbus.o
|
$(CC) $(LDFLAGS) -o adsbus adsbus.o airspy_adsb.o common.o
|
||||||
|
|||||||
74
adsbus.c
74
adsbus.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@@ -8,6 +9,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "airspy_adsb.h"
|
||||||
|
|
||||||
|
|
||||||
struct opts {
|
struct opts {
|
||||||
char *backend_node;
|
char *backend_node;
|
||||||
@@ -15,15 +19,7 @@ struct opts {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define BUF_LEN 4096
|
int parse_opts(int argc, char *argv[], struct opts *opts) {
|
||||||
struct buf {
|
|
||||||
char buf[BUF_LEN];
|
|
||||||
size_t start;
|
|
||||||
size_t length;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int parseOpts(int argc, char *argv[], struct opts *opts) {
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "h:p:")) != -1) {
|
while ((opt = getopt(argc, argv, "h:p:")) != -1) {
|
||||||
switch (opt) {
|
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 = {
|
struct addrinfo hints = {
|
||||||
.ai_family = AF_UNSPEC,
|
.ai_family = AF_UNSPEC,
|
||||||
.ai_socktype = SOCK_STREAM,
|
.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 loop(int bfd) {
|
||||||
int efd = epoll_create(10);
|
int efd = epoll_create(10);
|
||||||
if (efd == -1) {
|
if (efd == -1) {
|
||||||
@@ -136,10 +106,9 @@ int loop(int bfd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct buf buf = {
|
struct buf buf;
|
||||||
.start = 0,
|
char buf_main[BUF_LEN], buf_temp[BUF_LEN];
|
||||||
.length = 0,
|
buf_init(&buf, buf_main, buf_temp);
|
||||||
};
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
#define MAX_EVENTS 10
|
#define MAX_EVENTS 10
|
||||||
@@ -152,19 +121,26 @@ int loop(int bfd) {
|
|||||||
|
|
||||||
for (int n = 0; n < nfds; n++) {
|
for (int n = 0; n < nfds; n++) {
|
||||||
if (events[n].data.fd == bfd) {
|
if (events[n].data.fd == bfd) {
|
||||||
if (readToBuf(bfd, &buf) < 0) {
|
if (buf_fill(&buf, bfd) < 0) {
|
||||||
fprintf(stderr, "Connection closed by backend\n");
|
fprintf(stderr, "Connection closed by backend\n");
|
||||||
return -1;
|
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) {
|
if (buf.length == BUF_LEN) {
|
||||||
|
fprintf(stderr, "Input buffer overrun\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -173,22 +149,18 @@ int main(int argc, char *argv[]) {
|
|||||||
.backend_node = "localhost",
|
.backend_node = "localhost",
|
||||||
.backend_service = "30006",
|
.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]);
|
fprintf(stderr, "Usage: %s [-h backend_host] [-p backend_port]\n", argv[0]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bfd = connectBackend(&opts);
|
int bfd = connect_backend(&opts);
|
||||||
if (bfd < 0) {
|
if (bfd < 0) {
|
||||||
fprintf(stderr, "Unable to connect to %s/%s\n", opts.backend_node, opts.backend_service);
|
fprintf(stderr, "Unable to connect to %s/%s\n", opts.backend_node, opts.backend_service);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loop(bfd)) {
|
loop(bfd);
|
||||||
fprintf(stderr, "Main loop exited with error\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(bfd);
|
close(bfd);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
20
airspy_adsb.c
Normal file
20
airspy_adsb.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
3
airspy_adsb.h
Normal file
3
airspy_adsb.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool airspy_adsb_parse(struct buf *, struct packet *);
|
||||||
47
common.c
Normal file
47
common.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
common.h
Normal file
32
common.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
#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);
|
||||||
Reference in New Issue
Block a user