Get to where we're actually finding airspy packet boundaries.

This commit is contained in:
Ian Gulliver
2016-02-14 06:20:17 +00:00
parent 34fec2dee8
commit 51690ba0df
6 changed files with 127 additions and 53 deletions

View File

@@ -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

View File

@@ -1,3 +1,4 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
@@ -8,6 +9,9 @@
#include <unistd.h>
#include <sys/epoll.h>
#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;
}

20
airspy_adsb.c Normal file
View 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
View File

@@ -0,0 +1,3 @@
#include <stdbool.h>
bool airspy_adsb_parse(struct buf *, struct packet *);

47
common.c Normal file
View 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
View 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);