From 54409b483660f8028ec9a61042a852322cf65ad8 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Wed, 27 Nov 2019 21:01:46 +0800 Subject: [PATCH] Split beast output into two separate writers for verbatim vs. non-verbatim in preparation for supporting both types of connection in parallel --- dump1090.c | 3 ++- dump1090.h | 14 +++++++++----- mode_s.c | 6 ++---- net_io.c | 56 ++++++++++++++++++++++++++++++++++++------------------ 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/dump1090.c b/dump1090.c index 3b205aa..9334581 100644 --- a/dump1090.c +++ b/dump1090.c @@ -303,7 +303,8 @@ void showHelp(void) { "--net-ro-interval TCP output memory flush rate in seconds (default: 0)\n" "--net-heartbeat TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n" "--net-buffer TCP buffer size 64Kb * (2^n) (default: n=0, 64Kb)\n" -"--net-verbatim Do not apply CRC corrections to messages we forward; send unchanged\n" +"--net-verbatim Make Beast-format output connections default to verbatim mode\n" +" (forward all messages, without applying CRC corrections)\n" "--forward-mlat Allow forwarding of received mlat results to output ports\n" "--lat Reference/receiver latitude for surface posn (opt)\n" "--lon Reference/receiver longitude for surface posn (opt)\n" diff --git a/dump1090.h b/dump1090.h index 8e3e893..baca8d1 100644 --- a/dump1090.h +++ b/dump1090.h @@ -324,10 +324,14 @@ struct { // Internal state struct net_service *services; // Active services struct client *clients; // Our clients - struct net_writer raw_out; // Raw output - struct net_writer beast_out; // Beast-format output - struct net_writer sbs_out; // SBS-format output - struct net_writer fatsv_out; // FATSV-format output + struct net_service *beast_verbatim_service; // Beast-format output service, verbatim mode + struct net_service *beast_cooked_service; // Beast-format output service, "cooked" mode + + struct net_writer raw_out; // AVR-format output + struct net_writer beast_verbatim_out; // Beast-format output, verbatim mode + struct net_writer beast_cooked_out; // Beast-format output, "cooked" mode + struct net_writer sbs_out; // SBS-format output + struct net_writer fatsv_out; // FATSV-format output #ifdef _WIN32 WSADATA wsaData; // Windows socket initialisation @@ -353,7 +357,7 @@ struct { // Internal state char *net_output_beast_ports; // List of Beast output TCP ports char *net_bind_address; // Bind address int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n) - int net_verbatim; // if true, send the original message, not the CRC-corrected one + int net_verbatim; // if true, Beast output connections default to verbatim mode int forward_mlat; // allow forwarding of mlat messages to output ports int quiet; // Suppress stdout uint32_t show_only; // Only show messages from this ICAO diff --git a/mode_s.c b/mode_s.c index d548353..3e7d058 100644 --- a/mode_s.c +++ b/mode_s.c @@ -389,12 +389,10 @@ static void decodeExtendedSquitter(struct modesMessage *mm); int decodeModesMessage(struct modesMessage *mm, unsigned char *msg) { + // Preserve the original uncorrected copy for later forwarding + memcpy(mm->verbatim, msg, MODES_LONG_MSG_BYTES); // Work on our local copy. memcpy(mm->msg, msg, MODES_LONG_MSG_BYTES); - if (Modes.net_verbatim) { - // Preserve the original uncorrected copy for later forwarding - memcpy(mm->verbatim, msg, MODES_LONG_MSG_BYTES); - } msg = mm->msg; // don't accept all-zeros messages diff --git a/net_io.c b/net_io.c index 3542963..2bd099a 100644 --- a/net_io.c +++ b/net_io.c @@ -76,6 +76,8 @@ 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); +static void writeBeastMessage(struct net_writer *writer, uint64_t timestamp, double signalLevel, unsigned char *msg, int msgLen); + static void writeFATSVEvent(struct modesMessage *mm, struct aircraft *a); static void writeFATSVPositionUpdate(float lat, float lon, float alt); @@ -254,8 +256,14 @@ void modesInitNet(void) { s = serviceInit("Raw TCP output", &Modes.raw_out, send_raw_heartbeat, READ_MODE_IGNORE, NULL, NULL); serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_ports); - s = serviceInit("Beast TCP output", &Modes.beast_out, send_beast_heartbeat, READ_MODE_BEAST_COMMAND, NULL, handleBeastCommand); - serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_ports); + // we maintain two output services, one producing a stream of verbatim messages, one producing a stream of cooked messages + 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); + + if (Modes.net_verbatim) + serviceListen(Modes.beast_verbatim_service, Modes.net_bind_address, Modes.net_output_beast_ports); + else + serviceListen(Modes.beast_cooked_service, Modes.net_bind_address, Modes.net_output_beast_ports); s = serviceInit("Basestation TCP output", &Modes.sbs_out, send_sbs_heartbeat, READ_MODE_IGNORE, NULL, NULL); serviceListen(s, Modes.net_bind_address, Modes.net_output_sbs_ports); @@ -376,27 +384,38 @@ static void completeWrite(struct net_writer *writer, void *endptr) { // // Write raw output in Beast Binary format with Timestamp to TCP clients // -static void modesSendBeastOutput(struct modesMessage *mm, struct aircraft *a) { +static void modesSendBeastVerbatimOutput(struct modesMessage *mm, struct aircraft __attribute__((unused)) *a) { + // Don't forward mlat messages, unless --forward-mlat is set + if (mm->source == SOURCE_MLAT && !Modes.forward_mlat) + return; + + // Do verbatim output for all messages + writeBeastMessage(&Modes.beast_verbatim_out, mm->timestampMsg, mm->signalLevel, mm->msg, mm->msgbits / 8); +} + +static void modesSendBeastCookedOutput(struct modesMessage *mm, struct aircraft *a) { // Don't forward mlat messages, unless --forward-mlat is set if (mm->source == SOURCE_MLAT && !Modes.forward_mlat) return; // Filter some messages from cooked output // Don't forward 2-bit-corrected messages - if (!Modes.net_verbatim && mm->correctedbits >= 2) + if (mm->correctedbits >= 2) return; // Don't forward unreliable messages - if (!Modes.net_verbatim && (a && !a->reliable) && !mm->reliable) + if ((a && !a->reliable) && !mm->reliable) return; - int msgLen = mm->msgbits / 8; - char *p = prepareWrite(&Modes.beast_out, 2 + 2 * (7 + msgLen)); + writeBeastMessage(&Modes.beast_cooked_out, mm->timestampMsg, mm->signalLevel, mm->verbatim, mm->msgbits / 8); +} + +static void writeBeastMessage(struct net_writer *writer, uint64_t timestamp, double signalLevel, unsigned char *msg, int msgLen) { char ch; int j; int sig; - unsigned char *msg = (Modes.net_verbatim ? mm->verbatim : mm->msg); + char *p = prepareWrite(writer, 2 + 2 * (7 + msgLen)); if (!p) return; @@ -411,21 +430,21 @@ static void modesSendBeastOutput(struct modesMessage *mm, struct aircraft *a) { {return;} /* timestamp, big-endian */ - *p++ = (ch = (mm->timestampMsg >> 40)); + *p++ = (ch = (timestamp >> 40)); if (0x1A == ch) {*p++ = ch; } - *p++ = (ch = (mm->timestampMsg >> 32)); + *p++ = (ch = (timestamp >> 32)); if (0x1A == ch) {*p++ = ch; } - *p++ = (ch = (mm->timestampMsg >> 24)); + *p++ = (ch = (timestamp >> 24)); if (0x1A == ch) {*p++ = ch; } - *p++ = (ch = (mm->timestampMsg >> 16)); + *p++ = (ch = (timestamp >> 16)); if (0x1A == ch) {*p++ = ch; } - *p++ = (ch = (mm->timestampMsg >> 8)); + *p++ = (ch = (timestamp >> 8)); if (0x1A == ch) {*p++ = ch; } - *p++ = (ch = (mm->timestampMsg)); + *p++ = (ch = (timestamp)); if (0x1A == ch) {*p++ = ch; } - sig = round(sqrt(mm->signalLevel) * 255); - if (mm->signalLevel > 0 && sig < 1) + sig = round(sqrt(signalLevel) * 255); + if (signalLevel > 0 && sig < 1) sig = 1; if (sig > 255) sig = 255; @@ -437,7 +456,7 @@ static void modesSendBeastOutput(struct modesMessage *mm, struct aircraft *a) { if (0x1A == ch) {*p++ = ch; } } - completeWrite(&Modes.beast_out, p); + completeWrite(writer, p); } static void send_beast_heartbeat(struct net_service *service) @@ -765,7 +784,8 @@ void modesQueueOutput(struct modesMessage *mm, struct aircraft *a) { // Delegate to the format-specific outputs, each of which makes its own decision about filtering messages modesSendSBSOutput(mm, a); modesSendRawOutput(mm, a); - modesSendBeastOutput(mm, a); + modesSendBeastVerbatimOutput(mm, a); + modesSendBeastCookedOutput(mm, a); writeFATSVEvent(mm, a); }