Style and include cleanups.

This commit is contained in:
Ian Gulliver
2016-02-17 16:40:09 -08:00
parent 8e2e7b2562
commit ae5b4c1ce4
19 changed files with 213 additions and 245 deletions

View File

@@ -13,8 +13,7 @@
#include "json.h"
#include "stats.h"
static void print_usage(char *argv[]) {
static void print_usage(const char *name) {
fprintf(stderr,
"\n"
"Usage: %s [OPTION]...\n"
@@ -25,7 +24,7 @@ static void print_usage(char *argv[]) {
"\t--dump=FORMAT\n"
"\t--incoming=[HOST/]PORT\n"
"\t--listen=FORMAT=[HOST/]PORT\n"
, argv[0]);
, name);
backend_print_usage();
client_print_usage();
}
@@ -56,9 +55,9 @@ static bool add_incoming(char *arg){
char *port = strrchr(arg, '/');
if (port) {
*(port++) = '\0';
incoming_new(arg, port, backend_new_fd, NULL);
incoming_new(arg, port, backend_new_fd_wrapper, NULL);
} else {
incoming_new(NULL, arg, backend_new_fd, NULL);
incoming_new(NULL, arg, backend_new_fd_wrapper, NULL);
}
return true;
}
@@ -94,6 +93,7 @@ static bool parse_opts(int argc, char *argv[]) {
{"incoming", required_argument, 0, 'i'},
{"listen", required_argument, 0, 'l'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0 },
};
int opt;
@@ -109,7 +109,7 @@ static bool parse_opts(int argc, char *argv[]) {
break;
case 'h':
print_usage(argv);
print_usage(argv[0]);
return false;
case 'i':
@@ -121,13 +121,13 @@ static bool parse_opts(int argc, char *argv[]) {
break;
default:
print_usage(argv);
print_usage(argv[0]);
return false;
}
if (handler) {
if (!handler(optarg)) {
print_usage(argv);
print_usage(argv[0]);
return false;
}
}
@@ -135,7 +135,7 @@ static bool parse_opts(int argc, char *argv[]) {
if (optind != argc) {
fprintf(stderr, "Not a flag: %s\n", argv[optind]);
print_usage(argv);
print_usage(argv[0]);
return false;
}
@@ -143,7 +143,6 @@ static bool parse_opts(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
server_init();
peer_init();
hex_init();
client_init();

View File

@@ -1,9 +1,9 @@
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "backend.h"
#include "airspy_adsb.h"
struct __attribute__((packed)) airspy_adsb_common_overlay {
@@ -37,13 +37,16 @@ struct airspy_adsb_parser_state {
struct mlat_state mlat_state;
};
static bool airspy_adsb_parse_common(struct airspy_adsb_common_overlay *, struct packet *, struct airspy_adsb_parser_state *);
void airspy_adsb_init() {
assert(sizeof(struct airspy_adsb_parser_state) <= PARSER_STATE_LEN);
assert(sizeof(struct airspy_adsb_mode_s_short_overlay) < BUF_LEN_MAX);
assert(sizeof(struct airspy_adsb_mode_s_long_overlay) < BUF_LEN_MAX);
static bool airspy_adsb_parse_common(const struct airspy_adsb_common_overlay *overlay, struct packet *packet, struct airspy_adsb_parser_state *state) {
if (overlay->semicolon1 != ';' ||
overlay->semicolon2 != ';' ||
overlay->semicolon3 != ';') {
return false;
}
uint16_t mlat_mhz = 2 * hex_to_int(overlay->mlat_precision, sizeof(overlay->mlat_precision) / 2);
packet->mlat_timestamp = mlat_timestamp_scale_in(hex_to_int(overlay->mlat_timestamp, sizeof(overlay->mlat_timestamp) / 2), UINT32_MAX, mlat_mhz, &state->mlat_state);
packet->rssi = rssi_scale_in(hex_to_int(overlay->rssi, sizeof(overlay->rssi) / 2), UINT16_MAX);
return true;
}
static bool airspy_adsb_parse_mode_s_short(struct buf *buf, struct packet *packet, struct airspy_adsb_parser_state *state) {
@@ -82,23 +85,16 @@ static bool airspy_adsb_parse_mode_s_long(struct buf *buf, struct packet *packet
return true;
}
bool airspy_adsb_parse(struct backend *backend, struct packet *packet) {
struct buf *buf = &backend->buf;
struct airspy_adsb_parser_state *state = (struct airspy_adsb_parser_state *) backend->parser_state;
void airspy_adsb_init() {
assert(sizeof(struct airspy_adsb_parser_state) <= PARSER_STATE_LEN);
assert(sizeof(struct airspy_adsb_mode_s_short_overlay) < BUF_LEN_MAX);
assert(sizeof(struct airspy_adsb_mode_s_long_overlay) < BUF_LEN_MAX);
}
bool airspy_adsb_parse(struct buf *buf, struct packet *packet, void *state_in) {
struct airspy_adsb_parser_state *state = (struct airspy_adsb_parser_state *) state_in;
return (
airspy_adsb_parse_mode_s_short(buf, packet, state) ||
airspy_adsb_parse_mode_s_long(buf, packet, state));
}
static bool airspy_adsb_parse_common(struct airspy_adsb_common_overlay *overlay, struct packet *packet, struct airspy_adsb_parser_state *state) {
if (overlay->semicolon1 != ';' ||
overlay->semicolon2 != ';' ||
overlay->semicolon3 != ';') {
return false;
}
uint16_t mlat_mhz = 2 * hex_to_int(overlay->mlat_precision, sizeof(overlay->mlat_precision) / 2);
packet->mlat_timestamp = mlat_timestamp_scale_in(hex_to_int(overlay->mlat_timestamp, sizeof(overlay->mlat_timestamp) / 2), UINT32_MAX, mlat_mhz, &state->mlat_state);
packet->rssi = rssi_scale_in(hex_to_int(overlay->rssi, sizeof(overlay->rssi) / 2), UINT16_MAX);
return true;
}

View File

@@ -1,8 +1,9 @@
#pragma once
#include <stdbool.h>
#include "backend.h"
#include "common.h"
struct buf;
struct packet;
void airspy_adsb_init();
bool airspy_adsb_parse(struct backend *, struct packet *);
bool airspy_adsb_parse(struct buf *, struct packet *, void *);

202
backend.c
View File

@@ -5,6 +5,7 @@
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "airspy_adsb.h"
#include "beast.h"
@@ -13,14 +14,22 @@
#include "client.h"
#include "backend.h"
typedef bool (*parser_wrapper)(struct backend *, struct packet *);
typedef bool (*parser)(struct buf *, struct packet *, void *state);
struct backend {
struct peer peer;
char id[UUID_LEN];
const char *node;
const char *service;
struct addrinfo *addrs;
struct addrinfo *addr;
struct buf buf;
char parser_state[PARSER_STATE_LEN];
parser_wrapper parser_wrapper;
parser parser;
};
static bool backend_autodetect_parse(struct backend *, struct packet *);
static void backend_connect(struct backend *);
static void backend_connect_next(struct backend *);
static void backend_connect_handler(struct peer *);
static void backend_read(struct peer *);
static void backend_connect_result(struct backend *, int);
struct parser {
char *name;
@@ -41,6 +50,24 @@ struct parser {
};
#define NUM_PARSERS (sizeof(parsers) / sizeof(*parsers))
static bool backend_parse_wrapper(struct backend *backend, struct packet *packet) {
return backend->parser(&backend->buf, packet, backend->parser_state);
}
static bool backend_autodetect_parse(struct backend *backend, struct packet *packet) {
struct buf *buf = &backend->buf;
void *state = backend->parser_state;
for (int i = 0; i < NUM_PARSERS; i++) {
if (parsers[i].parse(buf, packet, state)) {
fprintf(stderr, "B %s: Detected input format %s\n", backend->id, parsers[i].name);
backend->parser_wrapper = backend_parse_wrapper;
backend->parser = parsers[i].parse;
return true;
}
}
return false;
}
static struct backend *backend_create() {
struct backend *backend = malloc(sizeof(*backend));
@@ -51,41 +78,62 @@ static struct backend *backend_create() {
backend->service = NULL;
buf_init(&backend->buf);
memset(backend->parser_state, 0, PARSER_STATE_LEN);
backend->parser = backend_autodetect_parse;
backend->parser_wrapper = backend_autodetect_parse;
return backend;
}
void backend_new(char *node, char *service) {
struct backend *backend = backend_create();
backend->node = node;
backend->service = service;
backend_connect(backend);
static void backend_connect_handler(struct peer *peer) {
struct backend *backend = (struct backend *) peer;
peer_epoll_del(peer);
int error;
socklen_t len = sizeof(error);
assert(getsockopt(backend->peer.fd, SOL_SOCKET, SO_ERROR, &error, &len) == 0);
backend_connect_result(backend, error);
}
void backend_new_fd(int fd, void *unused) {
struct backend *backend = backend_create();
backend->peer.fd = fd;
backend->peer.event_handler = backend_read;
peer_epoll_add((struct peer *) backend, EPOLLIN);
fprintf(stderr, "B %s: New backend from incoming connection\n", backend->id);
}
static void backend_connect(struct backend *backend) {
fprintf(stderr, "B %s: Resolving %s/%s...\n", backend->id, backend->node, backend->service);
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
};
int gai_err = getaddrinfo(backend->node, backend->service, &hints, &backend->addrs);
if (gai_err) {
fprintf(stderr, "B %s: Failed to resolve %s/%s: %s\n", backend->id, backend->node, backend->service, gai_strerror(gai_err));
static void backend_connect_next(struct backend *backend) {
if (backend->addr == NULL) {
freeaddrinfo(backend->addrs);
fprintf(stderr, "B %s: Can't connect to any addresses of %s/%s\n", backend->id, backend->node, backend->service);
return;
}
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
assert(getnameinfo(backend->addr->ai_addr, backend->addr->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0);
fprintf(stderr, "B %s: Connecting to %s/%s...\n", backend->id, hbuf, sbuf);
backend->peer.fd = socket(backend->addr->ai_family, backend->addr->ai_socktype | SOCK_NONBLOCK, backend->addr->ai_protocol);
assert(backend->peer.fd >= 0);
int result = connect(backend->peer.fd, backend->addr->ai_addr, backend->addr->ai_addrlen);
backend_connect_result(backend, result == 0 ? result : errno);
}
static void backend_read(struct peer *peer) {
struct backend *backend = (struct backend *) peer;
if (buf_fill(&backend->buf, backend->peer.fd) <= 0) {
fprintf(stderr, "B %s: Connection closed by backend\n", backend->id);
close(backend->peer.fd);
// TODO: reconnect
return;
}
struct packet packet = {
.backend = backend,
};
while (backend->parser_wrapper(backend, &packet)) {
client_write(&packet);
}
if (backend->buf.length == BUF_LEN_MAX) {
fprintf(stderr, "B %s: Input buffer overrun. This probably means that adsbus doesn't understand the protocol that this source is speaking.\n", backend->id);
close(backend->peer.fd);
// TODO: reconnect
return;
}
backend->addr = backend->addrs;
backend_connect_next(backend);
}
static void backend_connect_result(struct backend *backend, int result) {
@@ -114,69 +162,41 @@ static void backend_connect_result(struct backend *backend, int result) {
}
}
static void backend_connect_next(struct backend *backend) {
if (backend->addr == NULL) {
freeaddrinfo(backend->addrs);
fprintf(stderr, "B %s: Can't connect to any addresses of %s/%s\n", backend->id, backend->node, backend->service);
return;
}
static void backend_connect(struct backend *backend) {
fprintf(stderr, "B %s: Resolving %s/%s...\n", backend->id, backend->node, backend->service);
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
assert(getnameinfo(backend->addr->ai_addr, backend->addr->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0);
fprintf(stderr, "B %s: Connecting to %s/%s...\n", backend->id, hbuf, sbuf);
backend->peer.fd = socket(backend->addr->ai_family, backend->addr->ai_socktype | SOCK_NONBLOCK, backend->addr->ai_protocol);
assert(backend->peer.fd >= 0);
int result = connect(backend->peer.fd, backend->addr->ai_addr, backend->addr->ai_addrlen);
backend_connect_result(backend, result == 0 ? result : errno);
}
static void backend_connect_handler(struct peer *peer) {
struct backend *backend = (struct backend *) peer;
peer_epoll_del(peer);
int error;
socklen_t len = sizeof(error);
assert(getsockopt(backend->peer.fd, SOL_SOCKET, SO_ERROR, &error, &len) == 0);
backend_connect_result(backend, error);
}
static void backend_read(struct peer *peer) {
struct backend *backend = (struct backend *) peer;
if (buf_fill(&backend->buf, backend->peer.fd) <= 0) {
fprintf(stderr, "B %s: Connection closed by backend\n", backend->id);
close(backend->peer.fd);
// TODO: reconnect
return;
}
struct packet packet = {
.backend = backend,
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
};
while (backend->parser(backend, &packet)) {
client_write(&packet);
}
if (backend->buf.length == BUF_LEN_MAX) {
fprintf(stderr, "B %s: Input buffer overrun. This probably means that adsbus doesn't understand the protocol that this source is speaking.\n", backend->id);
close(backend->peer.fd);
// TODO: reconnect
int gai_err = getaddrinfo(backend->node, backend->service, &hints, &backend->addrs);
if (gai_err) {
fprintf(stderr, "B %s: Failed to resolve %s/%s: %s\n", backend->id, backend->node, backend->service, gai_strerror(gai_err));
return;
}
backend->addr = backend->addrs;
backend_connect_next(backend);
}
static bool backend_autodetect_parse(struct backend *backend, struct packet *packet) {
for (int i = 0; i < NUM_PARSERS; i++) {
if (parsers[i].parse(backend, packet)) {
fprintf(stderr, "B %s: Detected input format %s\n", backend->id, parsers[i].name);
backend->parser = parsers[i].parse;
return true;
}
}
return false;
void backend_new(const char *node, const char *service) {
struct backend *backend = backend_create();
backend->node = node;
backend->service = service;
backend_connect(backend);
}
void backend_new_fd(int fd) {
struct backend *backend = backend_create();
backend->peer.fd = fd;
backend->peer.event_handler = backend_read;
peer_epoll_add((struct peer *) backend, EPOLLIN);
fprintf(stderr, "B %s: New backend from incoming connection\n", backend->id);
}
void backend_new_fd_wrapper(int fd, void *unused) {
backend_new_fd(fd);
}
void backend_print_usage() {

View File

@@ -4,23 +4,9 @@
#include "common.h"
#define PARSER_STATE_LEN 256
struct backend;
struct addrinfo;
typedef bool (*parser)(struct backend *, struct packet *);
struct backend {
struct peer peer;
char id[UUID_LEN];
char *node;
char *service;
struct addrinfo *addrs;
struct addrinfo *addr;
struct buf buf;
char parser_state[PARSER_STATE_LEN];
parser parser;
};
void backend_new(char *, char *);
void backend_new_fd(int, void *);
void backend_new(const char *, const char *);
void backend_new_fd(int);
void backend_new_fd_wrapper(int, void *);
void backend_print_usage();

23
beast.c
View File

@@ -1,10 +1,12 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "common.h"
#include "backend.h"
#include "beast.h"
struct __attribute__((packed)) beast_common_overlay {
uint8_t one_a;
uint8_t type;
@@ -28,12 +30,6 @@ struct beast_parser_state {
struct mlat_state mlat_state;
};
void beast_init() {
assert(sizeof(struct beast_parser_state) <= PARSER_STATE_LEN);
assert(sizeof(struct beast_mode_s_short_overlay) * 2 <= BUF_LEN_MAX);
assert(sizeof(struct beast_mode_s_long_overlay) * 2 <= BUF_LEN_MAX);
}
static uint64_t beast_parse_mlat(uint8_t *mlat_timestamp) {
return (
((uint64_t) mlat_timestamp[0]) << 40 |
@@ -44,7 +40,7 @@ static uint64_t beast_parse_mlat(uint8_t *mlat_timestamp) {
((uint64_t) mlat_timestamp[5]));
}
ssize_t beast_unescape(struct buf *out, struct buf *in, size_t out_bytes) {
static ssize_t beast_unescape(struct buf *out, const struct buf *in, size_t out_bytes) {
int o = 0, i = 0;
for (; i < in->length && o < out_bytes; i++, o++) {
if (i > 0 && buf_chr(in, i) == 0x1a) {
@@ -98,9 +94,14 @@ static bool beast_parse_mode_s_long(struct buf *buf, struct packet *packet, stru
return true;
}
bool beast_parse(struct backend *backend, struct packet *packet) {
struct buf *buf = &backend->buf;
struct beast_parser_state *state = (struct beast_parser_state *) backend->parser_state;
void beast_init() {
assert(sizeof(struct beast_parser_state) <= PARSER_STATE_LEN);
assert(sizeof(struct beast_mode_s_short_overlay) * 2 <= BUF_LEN_MAX);
assert(sizeof(struct beast_mode_s_long_overlay) * 2 <= BUF_LEN_MAX);
}
bool beast_parse(struct buf *buf, struct packet *packet, void *state_in) {
struct beast_parser_state *state = (struct beast_parser_state *) state_in;
if (buf->length < sizeof(struct beast_common_overlay) ||
buf_chr(buf, 0) != 0x1a) {

View File

@@ -1,8 +1,9 @@
#pragma once
#include <stdbool.h>
#include "backend.h"
#include "common.h"
struct buf;
struct packet;
void beast_init();
bool beast_parse(struct backend *, struct packet *);
bool beast_parse(struct buf *, struct packet *, void *);

View File

@@ -12,7 +12,6 @@
#include "stats.h"
#include "client.h"
struct client {
struct peer peer;
char id[UUID_LEN];
@@ -38,11 +37,6 @@ struct serializer {
};
#define NUM_SERIALIZERS (sizeof(serializers) / sizeof(*serializers))
void client_init() {
signal(SIGPIPE, SIG_IGN);
}
static void client_hangup(struct client *client) {
fprintf(stderr, "C %s (%s): Client disconnected\n", client->id, client->serializer->name);
if (client->prev) {
@@ -61,15 +55,6 @@ static void client_hangup_wrapper(struct peer *peer) {
client_hangup((struct client *) peer);
}
struct serializer *client_get_serializer(char *name) {
for (int i = 0; i < NUM_SERIALIZERS; i++) {
if (strcasecmp(serializers[i].name, name) == 0) {
return &serializers[i];
}
}
return NULL;
}
static bool client_hello(int fd, struct serializer *serializer) {
struct buf buf = BUF_INIT;
serializer->serialize(NULL, &buf);
@@ -82,6 +67,19 @@ static bool client_hello(int fd, struct serializer *serializer) {
return true;
}
void client_init() {
signal(SIGPIPE, SIG_IGN);
}
struct serializer *client_get_serializer(char *name) {
for (int i = 0; i < NUM_SERIALIZERS; i++) {
if (strcasecmp(serializers[i].name, name) == 0) {
return &serializers[i];
}
}
return NULL;
}
void client_add(int fd, struct serializer *serializer) {
int flags = fcntl(fd, F_GETFL, 0);
assert(flags >= 0);

View File

@@ -2,7 +2,6 @@
#include "common.h"
void client_init();
struct serializer *client_get_serializer(char *);
void client_add(int, struct serializer *);

View File

@@ -10,7 +10,6 @@
int epoll_fd;
void peer_init() {
epoll_fd = epoll_create1(0);
assert(epoll_fd >= 0);
@@ -123,15 +122,15 @@ void hex_init() {
}
}
void hex_to_bin(uint8_t *out, char *in, size_t bytes) {
uint8_t *in2 = (uint8_t *) in;
void hex_to_bin(uint8_t *out, const char *in, size_t bytes) {
const 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 hex_to_int(const char *in, size_t bytes) {
const uint8_t *in2 = (uint8_t *) in;
uint64_t ret = 0;
bytes *= 2;
for (size_t i = 0; i < bytes; i++) {
@@ -141,7 +140,7 @@ uint64_t hex_to_int(char *in, size_t bytes) {
return ret;
}
void hex_from_bin(char *out, uint8_t *in, size_t bytes) {
void hex_from_bin(char *out, const uint8_t *in, size_t bytes) {
for (size_t i = 0, j = 0; i < bytes; i++, j += 2) {
out[j] = hex_char_table[in[i] >> 4];
out[j + 1] = hex_char_table[in[i] & 0xf];
@@ -154,11 +153,3 @@ void uuid_gen(char *out) {
uuid_generate(uuid);
uuid_unparse(uuid, out);
}
char server_id[UUID_LEN];
void server_init() {
uuid_gen(server_id);
fprintf(stderr, "S %s: Server start\n", server_id);
}

View File

@@ -1,7 +1,6 @@
#pragma once
#include <stdint.h>
#include <unistd.h>
#include <sys/epoll.h>
@@ -83,18 +82,12 @@ uint32_t rssi_scale_in(uint32_t, uint32_t);
//////// hex
void hex_init();
void hex_to_bin(uint8_t *, char *, size_t);
uint64_t hex_to_int(char *, size_t);
void hex_from_bin(char *, uint8_t *, size_t);
void hex_to_bin(uint8_t *, const char *, size_t);
uint64_t hex_to_int(const char *, size_t);
void hex_from_bin(char *, const uint8_t *, size_t);
///////// uuid
#define UUID_LEN 37
void uuid_gen(char *);
///////// server
extern char server_id[];
void server_init();

View File

@@ -6,21 +6,20 @@
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "common.h"
#include "incoming.h"
struct incoming {
struct peer peer;
char id[UUID_LEN];
char *node;
char *service;
const char *node;
const char *service;
incoming_connection_handler handler;
void *passthrough;
};
static void incoming_handler(struct peer *peer) {
struct incoming *incoming = (struct incoming *) peer;
@@ -47,7 +46,7 @@ static void incoming_handler(struct peer *peer) {
incoming->handler(fd, incoming->passthrough);
}
void incoming_new(char *node, char *service, incoming_connection_handler handler, void *passthrough) {
void incoming_new(const char *node, const char *service, incoming_connection_handler handler, void *passthrough) {
struct incoming *incoming = malloc(sizeof(*incoming));
incoming->peer.event_handler = incoming_handler;
uuid_gen(incoming->id);

View File

@@ -1,4 +1,4 @@
#pragma once
typedef void (*incoming_connection_handler)(int fd, void *);
void incoming_new(char *, char *, incoming_connection_handler, void *);
void incoming_new(const char *, const char *, incoming_connection_handler, void *);

33
json.c
View File

@@ -7,23 +7,6 @@
#include "client.h"
#include "json.h"
// Hobo JSON to avoid overhead. Assumes that we can't get quotes in the data.
void json_init() {
assert(JSON_INTEGER_IS_LONG_LONG);
}
int json_buf_append_callback(const char *buffer, size_t size, void *data) {
struct buf *buf = data;
if (buf->length + size + 1 > BUF_LEN_MAX) {
return -1;
}
memcpy(buf_at(buf, buf->length), buffer, size);
buf->length += size;
return 0;
}
static void json_serialize_to_buf(json_t *obj, struct buf *buf) {
assert(json_dump_callback(obj, json_buf_append_callback, buf, 0) == 0);
json_decref(obj);
@@ -32,7 +15,6 @@ static void json_serialize_to_buf(json_t *obj, struct buf *buf) {
static void json_hello(struct buf *buf) {
json_t *hello = json_pack("{sssIsIsI}",
"server_id", server_id,
"mlat_timestamp_mhz", (json_int_t) MLAT_MHZ,
"mlat_timestamp_max", (json_int_t) MLAT_MAX,
"rssi_max", (json_int_t) RSSI_MAX);
@@ -40,7 +22,6 @@ static void json_hello(struct buf *buf) {
}
static void json_add_common(struct packet *packet, json_t *obj) {
json_object_set_new(obj, "backend_id", json_string(packet->backend->id));
json_object_set_new(obj, "type", json_string(packet_type_names[packet->type]));
if (packet->mlat_timestamp) {
json_object_set_new(obj, "mlat_timestamp", json_integer(packet->mlat_timestamp));
@@ -68,6 +49,10 @@ static void json_serialize_mode_s_long(struct packet *packet, struct buf *buf) {
json_serialize_to_buf(out, buf);
}
void json_init() {
assert(JSON_INTEGER_IS_LONG_LONG);
}
void json_serialize(struct packet *packet, struct buf *buf) {
if (!packet) {
json_hello(buf);
@@ -87,3 +72,13 @@ void json_serialize(struct packet *packet, struct buf *buf) {
break;
}
}
int json_buf_append_callback(const char *buffer, size_t size, void *data) {
struct buf *buf = data;
if (buf->length + size + 1 > BUF_LEN_MAX) {
return -1;
}
memcpy(buf_at(buf, buf->length), buffer, size);
buf->length += size;
return 0;
}

3
json.h
View File

@@ -1,8 +1,5 @@
#pragma once
#include "common.h"
void json_init();
void json_serialize(struct packet *, struct buf *);

15
raw.c
View File

@@ -1,12 +1,10 @@
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "raw.h"
struct __attribute__((packed)) raw_mode_s_short_overlay {
char asterisk;
char payload[14];
@@ -21,12 +19,6 @@ struct __attribute__((packed)) raw_mode_s_long_overlay {
char lf;
};
void raw_init() {
assert(sizeof(struct raw_mode_s_short_overlay) < BUF_LEN_MAX);
assert(sizeof(struct raw_mode_s_long_overlay) < BUF_LEN_MAX);
}
static bool raw_parse_mode_s_short(struct buf *buf, struct packet *packet) {
struct raw_mode_s_short_overlay *short_overlay = (struct raw_mode_s_short_overlay *) buf_at(buf, 0);
if (buf->length < sizeof(*short_overlay) ||
@@ -55,9 +47,12 @@ static bool raw_parse_mode_s_long(struct buf *buf, struct packet *packet) {
return true;
}
bool raw_parse(struct backend *backend, struct packet *packet) {
struct buf *buf = &backend->buf;
void raw_init() {
assert(sizeof(struct raw_mode_s_short_overlay) < BUF_LEN_MAX);
assert(sizeof(struct raw_mode_s_long_overlay) < BUF_LEN_MAX);
}
bool raw_parse(struct buf *buf, struct packet *packet, void *state_in) {
return (
raw_parse_mode_s_short(buf, packet) ||
raw_parse_mode_s_long(buf, packet));

7
raw.h
View File

@@ -1,8 +1,9 @@
#pragma once
#include <stdbool.h>
#include "backend.h"
#include "common.h"
struct buf;
struct packet;
void raw_init();
bool raw_parse(struct backend *, struct packet *);
bool raw_parse(struct buf *, struct packet *, void *);

View File

@@ -3,23 +3,19 @@
#include <jansson.h>
#include "common.h"
#include "backend.h"
#include "json.h"
#include "stats.h"
static struct stats_state {
uint64_t total_count;
uint64_t type_count[NUM_TYPES];
struct timespec start;
} stats_state = { 0 };
void stats_init() {
assert(clock_gettime(CLOCK_MONOTONIC, &stats_state.start) == 0);
}
void stats_serialize(struct packet *packet, struct buf *buf) {
if (packet) {
stats_state.total_count++;

View File

@@ -1,7 +1,7 @@
#pragma once
#include "common.h"
struct packet;
struct buf;
void stats_init();
void stats_serialize(struct packet *, struct buf *);