Split beast output into two separate writers for verbatim vs. non-verbatim
in preparation for supporting both types of connection in parallel
This commit is contained in:
parent
dfc588335a
commit
54409b4836
|
|
@ -303,7 +303,8 @@ void showHelp(void) {
|
||||||
"--net-ro-interval <rate> TCP output memory flush rate in seconds (default: 0)\n"
|
"--net-ro-interval <rate> TCP output memory flush rate in seconds (default: 0)\n"
|
||||||
"--net-heartbeat <rate> TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n"
|
"--net-heartbeat <rate> TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n"
|
||||||
"--net-buffer <n> TCP buffer size 64Kb * (2^n) (default: n=0, 64Kb)\n"
|
"--net-buffer <n> 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"
|
"--forward-mlat Allow forwarding of received mlat results to output ports\n"
|
||||||
"--lat <latitude> Reference/receiver latitude for surface posn (opt)\n"
|
"--lat <latitude> Reference/receiver latitude for surface posn (opt)\n"
|
||||||
"--lon <longitude> Reference/receiver longitude for surface posn (opt)\n"
|
"--lon <longitude> Reference/receiver longitude for surface posn (opt)\n"
|
||||||
|
|
|
||||||
10
dump1090.h
10
dump1090.h
|
|
@ -324,8 +324,12 @@ struct { // Internal state
|
||||||
struct net_service *services; // Active services
|
struct net_service *services; // Active services
|
||||||
struct client *clients; // Our clients
|
struct client *clients; // Our clients
|
||||||
|
|
||||||
struct net_writer raw_out; // Raw output
|
struct net_service *beast_verbatim_service; // Beast-format output service, verbatim mode
|
||||||
struct net_writer beast_out; // Beast-format output
|
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 sbs_out; // SBS-format output
|
||||||
struct net_writer fatsv_out; // FATSV-format output
|
struct net_writer fatsv_out; // FATSV-format output
|
||||||
|
|
||||||
|
|
@ -353,7 +357,7 @@ struct { // Internal state
|
||||||
char *net_output_beast_ports; // List of Beast output TCP ports
|
char *net_output_beast_ports; // List of Beast output TCP ports
|
||||||
char *net_bind_address; // Bind address
|
char *net_bind_address; // Bind address
|
||||||
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
|
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 forward_mlat; // allow forwarding of mlat messages to output ports
|
||||||
int quiet; // Suppress stdout
|
int quiet; // Suppress stdout
|
||||||
uint32_t show_only; // Only show messages from this ICAO
|
uint32_t show_only; // Only show messages from this ICAO
|
||||||
|
|
|
||||||
6
mode_s.c
6
mode_s.c
|
|
@ -389,12 +389,10 @@ static void decodeExtendedSquitter(struct modesMessage *mm);
|
||||||
|
|
||||||
int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
|
int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
|
||||||
{
|
{
|
||||||
// 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
|
// Preserve the original uncorrected copy for later forwarding
|
||||||
memcpy(mm->verbatim, msg, MODES_LONG_MSG_BYTES);
|
memcpy(mm->verbatim, msg, MODES_LONG_MSG_BYTES);
|
||||||
}
|
// Work on our local copy.
|
||||||
|
memcpy(mm->msg, msg, MODES_LONG_MSG_BYTES);
|
||||||
msg = mm->msg;
|
msg = mm->msg;
|
||||||
|
|
||||||
// don't accept all-zeros messages
|
// don't accept all-zeros messages
|
||||||
|
|
|
||||||
56
net_io.c
56
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_beast_heartbeat(struct net_service *service);
|
||||||
static void send_sbs_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 writeFATSVEvent(struct modesMessage *mm, struct aircraft *a);
|
||||||
static void writeFATSVPositionUpdate(float lat, float lon, float alt);
|
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);
|
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);
|
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);
|
// we maintain two output services, one producing a stream of verbatim messages, one producing a stream of cooked messages
|
||||||
serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_ports);
|
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);
|
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);
|
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
|
// 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
|
// Don't forward mlat messages, unless --forward-mlat is set
|
||||||
if (mm->source == SOURCE_MLAT && !Modes.forward_mlat)
|
if (mm->source == SOURCE_MLAT && !Modes.forward_mlat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Filter some messages from cooked output
|
// Filter some messages from cooked output
|
||||||
// Don't forward 2-bit-corrected messages
|
// Don't forward 2-bit-corrected messages
|
||||||
if (!Modes.net_verbatim && mm->correctedbits >= 2)
|
if (mm->correctedbits >= 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't forward unreliable messages
|
// Don't forward unreliable messages
|
||||||
if (!Modes.net_verbatim && (a && !a->reliable) && !mm->reliable)
|
if ((a && !a->reliable) && !mm->reliable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int msgLen = mm->msgbits / 8;
|
writeBeastMessage(&Modes.beast_cooked_out, mm->timestampMsg, mm->signalLevel, mm->verbatim, mm->msgbits / 8);
|
||||||
char *p = prepareWrite(&Modes.beast_out, 2 + 2 * (7 + msgLen));
|
}
|
||||||
|
|
||||||
|
static void writeBeastMessage(struct net_writer *writer, uint64_t timestamp, double signalLevel, unsigned char *msg, int msgLen) {
|
||||||
char ch;
|
char ch;
|
||||||
int j;
|
int j;
|
||||||
int sig;
|
int sig;
|
||||||
unsigned char *msg = (Modes.net_verbatim ? mm->verbatim : mm->msg);
|
|
||||||
|
|
||||||
|
char *p = prepareWrite(writer, 2 + 2 * (7 + msgLen));
|
||||||
if (!p)
|
if (!p)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -411,21 +430,21 @@ static void modesSendBeastOutput(struct modesMessage *mm, struct aircraft *a) {
|
||||||
{return;}
|
{return;}
|
||||||
|
|
||||||
/* timestamp, big-endian */
|
/* timestamp, big-endian */
|
||||||
*p++ = (ch = (mm->timestampMsg >> 40));
|
*p++ = (ch = (timestamp >> 40));
|
||||||
if (0x1A == ch) {*p++ = ch; }
|
if (0x1A == ch) {*p++ = ch; }
|
||||||
*p++ = (ch = (mm->timestampMsg >> 32));
|
*p++ = (ch = (timestamp >> 32));
|
||||||
if (0x1A == ch) {*p++ = ch; }
|
if (0x1A == ch) {*p++ = ch; }
|
||||||
*p++ = (ch = (mm->timestampMsg >> 24));
|
*p++ = (ch = (timestamp >> 24));
|
||||||
if (0x1A == ch) {*p++ = ch; }
|
if (0x1A == ch) {*p++ = ch; }
|
||||||
*p++ = (ch = (mm->timestampMsg >> 16));
|
*p++ = (ch = (timestamp >> 16));
|
||||||
if (0x1A == ch) {*p++ = ch; }
|
if (0x1A == ch) {*p++ = ch; }
|
||||||
*p++ = (ch = (mm->timestampMsg >> 8));
|
*p++ = (ch = (timestamp >> 8));
|
||||||
if (0x1A == ch) {*p++ = ch; }
|
if (0x1A == ch) {*p++ = ch; }
|
||||||
*p++ = (ch = (mm->timestampMsg));
|
*p++ = (ch = (timestamp));
|
||||||
if (0x1A == ch) {*p++ = ch; }
|
if (0x1A == ch) {*p++ = ch; }
|
||||||
|
|
||||||
sig = round(sqrt(mm->signalLevel) * 255);
|
sig = round(sqrt(signalLevel) * 255);
|
||||||
if (mm->signalLevel > 0 && sig < 1)
|
if (signalLevel > 0 && sig < 1)
|
||||||
sig = 1;
|
sig = 1;
|
||||||
if (sig > 255)
|
if (sig > 255)
|
||||||
sig = 255;
|
sig = 255;
|
||||||
|
|
@ -437,7 +456,7 @@ static void modesSendBeastOutput(struct modesMessage *mm, struct aircraft *a) {
|
||||||
if (0x1A == ch) {*p++ = ch; }
|
if (0x1A == ch) {*p++ = ch; }
|
||||||
}
|
}
|
||||||
|
|
||||||
completeWrite(&Modes.beast_out, p);
|
completeWrite(writer, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_beast_heartbeat(struct net_service *service)
|
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
|
// Delegate to the format-specific outputs, each of which makes its own decision about filtering messages
|
||||||
modesSendSBSOutput(mm, a);
|
modesSendSBSOutput(mm, a);
|
||||||
modesSendRawOutput(mm, a);
|
modesSendRawOutput(mm, a);
|
||||||
modesSendBeastOutput(mm, a);
|
modesSendBeastVerbatimOutput(mm, a);
|
||||||
|
modesSendBeastCookedOutput(mm, a);
|
||||||
writeFATSVEvent(mm, a);
|
writeFATSVEvent(mm, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue