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.
This commit is contained in:
Oliver Jowett 2019-11-27 21:04:27 +08:00
parent 54409b4836
commit 8ffa43b65c
3 changed files with 38 additions and 8 deletions

View File

@ -199,7 +199,7 @@ int main(int argc, char **argv) {
exit (1); 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 // Set up output connection on stdout
fatsv_output = makeFatsvOutputService(); fatsv_output = makeFatsvOutputService();

View File

@ -72,6 +72,8 @@ static int handleBeastCommand(struct client *c, char *p);
static int decodeBinMessage(struct client *c, char *p); static int decodeBinMessage(struct client *c, char *p);
static int decodeHexMessage(struct client *c, char *hex); 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_raw_heartbeat(struct net_service *service);
static void send_beast_heartbeat(struct net_service *service); static void send_beast_heartbeat(struct net_service *service);
static void send_sbs_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); exit(1);
} }
c->service = service; c->service = NULL;
c->next = Modes.clients; c->next = Modes.clients;
c->fd = fd; c->fd = fd;
c->buflen = 0; c->buflen = 0;
c->modeac_requested = 0; c->modeac_requested = 0;
Modes.clients = c; Modes.clients = c;
++service->connections; moveNetClient(c, service);
if (service->writer && service->connections == 1) {
service->writer->lastWrite = mstime(); // suppress heartbeat initially
}
return c; return c;
} }
@ -257,6 +256,7 @@ void modesInitNet(void) {
serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_ports); 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 // 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_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); 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); 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. // Handle a Beast command message.
// Currently, we just look for the Mode A/C 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]) { switch (p[1]) {
case 'j': case 'j':
c->modeac_requested = 0; c->modeac_requested = 0;
autoset_modeac();
break; break;
case 'J': case 'J':
c->modeac_requested = 1; 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; break;
} }
autoset_modeac();
return 0; return 0;
} }

View File

@ -206,7 +206,7 @@ int main(int argc, char **argv) {
exit(1); 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.mode_ac ? "J" : "j"); // Mode A/C on or off
sendBeastSettings(c, Modes.check_crc ? "f" : "F"); // CRC checks on or off sendBeastSettings(c, Modes.check_crc ? "f" : "F"); // CRC checks on or off