From 8ffa43b65c1ff8ea69d68bbb832039d085b86722 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Wed, 27 Nov 2019 21:04:27 +0800 Subject: [PATCH] Add a v/V Beast-format setting to control verbatim mode. Make --net-verbatim just control the default setting. 0x1A '1' 'v' disables verbatim mode (send "cooked" output); 0x1A '1' 'V' enables verbatim mode Support clients with different settings by switching them between output writers depending on what setting they want, so clients with different settings can co-exist (unlike the Mode A/C setting) In cooked mode, FEC corrections are applied to messages before they are send and only trustworthy messages are forwarded; this is the default case for downstream clients that don't want to apply their own rules and are happy with the decisions that dump1090 makes. In verbatim mode, all messages are forwarded, but no FEC corrections are applied; the downstream client needs to make its own FEC / noise filtering decisions. Usually the default for new connections is cooked mode. --net-verbatim changes the default to be verbatim mode. --- faup1090.c | 2 +- net_io.c | 42 ++++++++++++++++++++++++++++++++++++------ view1090.c | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/faup1090.c b/faup1090.c index 1232c6a..cd2be92 100644 --- a/faup1090.c +++ b/faup1090.c @@ -199,7 +199,7 @@ int main(int argc, char **argv) { exit (1); } - sendBeastSettings(c, "Cdfj"); // Beast binary, no filters, CRC checks on, no mode A/C + sendBeastSettings(c, "CdfjV"); // Beast binary, no filters, CRC checks on, no mode A/C, verbatim mode on // Set up output connection on stdout fatsv_output = makeFatsvOutputService(); diff --git a/net_io.c b/net_io.c index 2bd099a..a55f0cf 100644 --- a/net_io.c +++ b/net_io.c @@ -72,6 +72,8 @@ static int handleBeastCommand(struct client *c, char *p); static int decodeBinMessage(struct client *c, char *p); static int decodeHexMessage(struct client *c, char *hex); +static void moveNetClient(struct client *c, struct net_service *new_service); + static void send_raw_heartbeat(struct net_service *service); static void send_beast_heartbeat(struct net_service *service); static void send_sbs_heartbeat(struct net_service *service); @@ -145,17 +147,14 @@ struct client *createGenericClient(struct net_service *service, int fd) exit(1); } - c->service = service; + c->service = NULL; c->next = Modes.clients; c->fd = fd; c->buflen = 0; c->modeac_requested = 0; Modes.clients = c; - ++service->connections; - if (service->writer && service->connections == 1) { - service->writer->lastWrite = mstime(); // suppress heartbeat initially - } + moveNetClient(c, service); return c; } @@ -257,6 +256,7 @@ void modesInitNet(void) { serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_ports); // we maintain two output services, one producing a stream of verbatim messages, one producing a stream of cooked messages + // and switch clients between them if they request a change in mode Modes.beast_cooked_service = serviceInit("Beast TCP output (cooked mode)", &Modes.beast_cooked_out, send_beast_heartbeat, READ_MODE_BEAST_COMMAND, NULL, handleBeastCommand); Modes.beast_verbatim_service = serviceInit("Beast TCP output (verbatim mode)", &Modes.beast_verbatim_out, send_beast_heartbeat, READ_MODE_BEAST_COMMAND, NULL, handleBeastCommand); @@ -873,6 +873,29 @@ void sendBeastSettings(struct client *c, const char *settings) anetWrite(c->fd, buf, len); } +// Move a network client to a new service +static void moveNetClient(struct client *c, struct net_service *new_service) +{ + if (c->service == new_service) + return; + + if (c->service) { + // Flush to ensure correct message framing + if (c->service->writer) + flushWrites(c->service->writer); + --c->service->connections; + } + + if (new_service) { + // Flush to ensure correct message framing + if (new_service->writer) + flushWrites(new_service->writer); + ++new_service->connections; + } + + c->service = new_service; +} + // // Handle a Beast command message. // Currently, we just look for the Mode A/C command message @@ -887,13 +910,20 @@ static int handleBeastCommand(struct client *c, char *p) { switch (p[1]) { case 'j': c->modeac_requested = 0; + autoset_modeac(); break; case 'J': c->modeac_requested = 1; + autoset_modeac(); + break; + case 'v': + moveNetClient(c, Modes.beast_cooked_service); + break; + case 'V': + moveNetClient(c, Modes.beast_verbatim_service); break; } - autoset_modeac(); return 0; } diff --git a/view1090.c b/view1090.c index b4b8f1b..590d904 100644 --- a/view1090.c +++ b/view1090.c @@ -206,7 +206,7 @@ int main(int argc, char **argv) { exit(1); } - sendBeastSettings(c, "Cd"); // Beast binary format, no filters + sendBeastSettings(c, "CdV"); // Beast binary format, no filters, verbatim mode on sendBeastSettings(c, Modes.mode_ac ? "J" : "j"); // Mode A/C on or off sendBeastSettings(c, Modes.check_crc ? "f" : "F"); // CRC checks on or off