Parse full airspy input.
This commit is contained in:
4
adsbus.c
4
adsbus.c
@@ -131,7 +131,7 @@ static int loop(int bfd) {
|
|||||||
while (airspy_adsb_parse(&buf, &packet)) {
|
while (airspy_adsb_parse(&buf, &packet)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf.length == BUF_LEN) {
|
if (buf.length == BUF_LEN_MAX) {
|
||||||
fprintf(stderr, "Input buffer overrun. This probably means that adsbus doesn't understand the protocol that this source is speaking.\n");
|
fprintf(stderr, "Input buffer overrun. This probably means that adsbus doesn't understand the protocol that this source is speaking.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -142,6 +142,8 @@ static int loop(int bfd) {
|
|||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
hex_init();
|
||||||
|
|
||||||
struct opts opts = {
|
struct opts opts = {
|
||||||
.backend_node = "localhost",
|
.backend_node = "localhost",
|
||||||
.backend_service = "30006",
|
.backend_service = "30006",
|
||||||
|
|||||||
@@ -1,27 +1,53 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "airspy_adsb.h"
|
#include "airspy_adsb.h"
|
||||||
|
|
||||||
|
static bool airspy_adsb_parse_common(char *, struct packet *);
|
||||||
|
|
||||||
|
|
||||||
bool airspy_adsb_parse(struct buf *buf, struct packet *packet) {
|
bool airspy_adsb_parse(struct buf *buf, struct packet *packet) {
|
||||||
if (buf->length < 35 ||
|
if (buf->length < 35 ||
|
||||||
buf_chr(buf, 0) != '*') {
|
buf_chr(buf, 0) != '*') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (buf->length >= 35 &&
|
if (buf->length >= 35 &&
|
||||||
|
buf_chr(buf, 33) == '\r' &&
|
||||||
buf_chr(buf, 34) == '\n' &&
|
buf_chr(buf, 34) == '\n' &&
|
||||||
buf_chr(buf, 15) == ';') {
|
buf_chr(buf, 15) == ';') {
|
||||||
|
if (!airspy_adsb_parse_common(buf_at(buf, 16), packet)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
packet->type = MODE_S_SHORT;
|
packet->type = MODE_S_SHORT;
|
||||||
|
hex_to_bin(packet->data, buf_at(buf, 1), 7);
|
||||||
buf_consume(buf, 35);
|
buf_consume(buf, 35);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (buf->length >= 49 &&
|
if (buf->length >= 49 &&
|
||||||
|
buf_chr(buf, 47) == '\r' &&
|
||||||
buf_chr(buf, 48) == '\n' &&
|
buf_chr(buf, 48) == '\n' &&
|
||||||
buf_chr(buf, 29) == ';') {
|
buf_chr(buf, 29) == ';') {
|
||||||
|
if (!airspy_adsb_parse_common(buf_at(buf, 30), packet)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
packet->type = MODE_S_LONG;
|
packet->type = MODE_S_LONG;
|
||||||
|
hex_to_bin(packet->data, buf_at(buf, 1), 14);
|
||||||
buf_consume(buf, 49);
|
buf_consume(buf, 49);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool airspy_adsb_parse_common(char *in, struct packet *packet) {
|
||||||
|
if (in[8] != ';' ||
|
||||||
|
in[11] != ';' ||
|
||||||
|
in[16] != ';') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint16_t mlat_mhz = 2 * hex_to_int(&in[9], 1);
|
||||||
|
packet->mlat_timestamp = hex_to_int(in, 4) * (MLAT_MHZ / mlat_mhz);
|
||||||
|
packet->rssi = hex_to_int(&in[12], 2) * (RSSI_MAX / (1 << 16));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
37
common.c
37
common.c
@@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
|
|
||||||
ssize_t buf_fill(struct buf *buf, int fd) {
|
ssize_t buf_fill(struct buf *buf, int fd) {
|
||||||
if (buf->start + buf->length == BUF_LEN) {
|
if (buf->start + buf->length == BUF_LEN_MAX) {
|
||||||
assert(buf->start > 0);
|
assert(buf->start > 0);
|
||||||
memmove(buf->buf, buf_at(buf, 0), buf->length);
|
memmove(buf->buf, buf_at(buf, 0), buf->length);
|
||||||
buf->start = 0;
|
buf->start = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t space = BUF_LEN - buf->length - buf->start;
|
size_t space = BUF_LEN_MAX - buf->length - buf->start;
|
||||||
ssize_t in = read(fd, buf_at(buf, buf->length), space);
|
ssize_t in = read(fd, buf_at(buf, buf->length), space);
|
||||||
if (in < 0) {
|
if (in < 0) {
|
||||||
return in;
|
return in;
|
||||||
@@ -33,3 +33,36 @@ void buf_consume(struct buf *buf, size_t length) {
|
|||||||
buf->start = 0;
|
buf->start = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t hex_table[256] = {0};
|
||||||
|
|
||||||
|
void hex_init() {
|
||||||
|
for (int i = '0'; i <= '9'; i++) {
|
||||||
|
hex_table[i] = i - '0';
|
||||||
|
}
|
||||||
|
for (int i = 'a'; i <= 'f'; i++) {
|
||||||
|
hex_table[i] = 10 + i - 'a';
|
||||||
|
}
|
||||||
|
for (int i = 'A'; i <= 'F'; i++) {
|
||||||
|
hex_table[i] = 10 + i - 'A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hex_to_bin(char *out, char *in, size_t bytes) {
|
||||||
|
uint8_t *in2 = (uint8_t *) in;
|
||||||
|
for (size_t i = 0, j = 0; i < bytes; i++, j += 2) {
|
||||||
|
out[i] = (hex_table[in2[j]] << 4) | hex_table[in2[j + 1]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t hex_to_int(char *in, size_t bytes) {
|
||||||
|
uint8_t *in2 = (uint8_t *) in;
|
||||||
|
uint64_t ret = 0;
|
||||||
|
bytes *= 2;
|
||||||
|
for (size_t i = 0; i < bytes; i++) {
|
||||||
|
ret <<= 4;
|
||||||
|
ret |= hex_table[in2[i]];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
14
common.h
14
common.h
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
//////// buf
|
//////// buf
|
||||||
|
|
||||||
#define BUF_LEN 4096
|
#define BUF_LEN_MAX 256
|
||||||
struct buf {
|
struct buf {
|
||||||
char buf[BUF_LEN];
|
char buf[BUF_LEN_MAX];
|
||||||
size_t start;
|
size_t start;
|
||||||
size_t length;
|
size_t length;
|
||||||
};
|
};
|
||||||
@@ -20,18 +20,22 @@ void buf_consume(struct buf *, size_t);
|
|||||||
|
|
||||||
//////// packet
|
//////// packet
|
||||||
|
|
||||||
#define MLAT_HZ 60000000
|
#define MLAT_MHZ 120
|
||||||
#define DATA_MAX 14
|
#define RSSI_MAX UINT32_MAX
|
||||||
|
#define DATA_LEN_MAX 14
|
||||||
struct packet {
|
struct packet {
|
||||||
enum {
|
enum {
|
||||||
MODE_AC,
|
MODE_AC,
|
||||||
MODE_S_SHORT,
|
MODE_S_SHORT,
|
||||||
MODE_S_LONG,
|
MODE_S_LONG,
|
||||||
} type;
|
} type;
|
||||||
char data[DATA_MAX];
|
char data[DATA_LEN_MAX];
|
||||||
uint64_t mlat_timestamp;
|
uint64_t mlat_timestamp;
|
||||||
uint32_t rssi;
|
uint32_t rssi;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//////// hex
|
//////// hex
|
||||||
|
void hex_init();
|
||||||
|
void hex_to_bin(char *, char *, size_t);
|
||||||
|
uint64_t hex_to_int(char *, size_t);
|
||||||
|
|||||||
Reference in New Issue
Block a user