Style and include cleanups.
This commit is contained in:
19
adsbus.c
19
adsbus.c
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
202
backend.c
@@ -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() {
|
||||
|
||||
20
backend.h
20
backend.h
@@ -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
23
beast.c
@@ -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) {
|
||||
|
||||
7
beast.h
7
beast.h
@@ -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 *);
|
||||
|
||||
28
client.c
28
client.c
@@ -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);
|
||||
|
||||
1
client.h
1
client.h
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
void client_init();
|
||||
struct serializer *client_get_serializer(char *);
|
||||
void client_add(int, struct serializer *);
|
||||
|
||||
19
common.c
19
common.c
@@ -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);
|
||||
}
|
||||
|
||||
13
common.h
13
common.h
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
33
json.c
@@ -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
3
json.h
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
void json_init();
|
||||
void json_serialize(struct packet *, struct buf *);
|
||||
|
||||
|
||||
15
raw.c
15
raw.c
@@ -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
7
raw.h
@@ -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 *);
|
||||
|
||||
4
stats.c
4
stats.c
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user