From 5c3692a5135e3b1f3edad3f0f7fe13d373f36a30 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 21 Jan 2016 17:45:27 +0000 Subject: [PATCH 1/6] Require an explicit #define at build time to enable --aggressive. --- dump1090.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dump1090.c b/dump1090.c index a8e74f6..7b7ba4b 100644 --- a/dump1090.c +++ b/dump1090.c @@ -2,7 +2,7 @@ // // dump1090.c: main program & miscellany // -// Copyright (c) 2014,2015 Oliver Jowett +// Copyright (c) 2014-2016 Oliver Jowett // // This file is free software: you may copy, redistribute and/or modify it // under the terms of the GNU General Public License as published by the @@ -702,7 +702,9 @@ void showHelp(void) { "--no-fix Disable single-bits error correction using CRC\n" "--no-crc-check Disable messages with broken CRC (discouraged)\n" "--phase-enhance Enable phase enhancement\n" +#ifdef ALLOW_AGGRESSIVE "--aggressive More CPU for more messages (two bits fixes, ...)\n" +#endif "--mlat display raw messages in Beast ascii mode\n" "--stats With --ifile print stats at exit. No other output\n" "--stats-range Collect/show range histogram\n" @@ -1010,7 +1012,11 @@ int main(int argc, char **argv) { } else if (!strcmp(argv[j],"--hae")) { Modes.use_hae = 1; } else if (!strcmp(argv[j],"--aggressive")) { +#ifdef ALLOW_AGGRESSIVE Modes.nfix_crc = MODES_MAX_BITERRORS; +#else + fprintf(stderr, "warning: --aggressive not supported in this build, option ignored.\n"); +#endif } else if (!strcmp(argv[j],"--interactive")) { Modes.interactive = Modes.throttle = 1; } else if (!strcmp(argv[j],"--throttle")) { From ecbdbf23d676d1eae1c0f518243d9790db65c74a Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 21 Jan 2016 17:48:06 +0000 Subject: [PATCH 2/6] Never forward mlat via SBS or raw output; it is no longer identifiable as mlat when forwarded on those paths. --- net_io.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/net_io.c b/net_io.c index 9a7eee9..361c668 100644 --- a/net_io.c +++ b/net_io.c @@ -643,12 +643,16 @@ static void send_sbs_heartbeat(struct net_service *service) //========================================================================= // void modesQueueOutput(struct modesMessage *mm, struct aircraft *a) { - if ((mm->bFlags & MODES_ACFLAGS_FROM_MLAT) && !Modes.forward_mlat) - return; + int is_mlat = ((mm->bFlags & MODES_ACFLAGS_FROM_MLAT) != 0); - modesSendSBSOutput(mm, a); - modesSendBeastOutput(mm); - modesSendRawOutput(mm); + if (!is_mlat) { + modesSendSBSOutput(mm, a); + modesSendRawOutput(mm); + } + + if (!is_mlat || Modes.forward_mlat) { + modesSendBeastOutput(mm); + } } // //========================================================================= From 5632a2ccdb429b2da0d99a2f06c357d5a1760542 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 21 Jan 2016 18:35:41 +0000 Subject: [PATCH 3/6] Try to get travis working again. --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e99fbe7..1b94ac7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,11 @@ os: - linux - osx +sudo: required +dist: trusty + before_install: - if [ `uname` = "Linux" ]; then - sudo add-apt-repository ppa:gqrx/releases -y; sudo apt-get update -qq; sudo apt-get install -y build-essential debhelper librtlsdr-dev libusb-1.0-0-dev pkg-config; elif [ `uname` = "Darwin" ]; then @@ -20,4 +22,4 @@ script: elif [ `uname` = "Darwin" ]; then make; make test; - fi \ No newline at end of file + fi From 1170ed9620b7ce4a4387dbacd19493a8eb5e6855 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 21 Jan 2016 19:01:11 +0000 Subject: [PATCH 4/6] Set faup1090 default max range to 360NM. This effectively disables receiver-relative CPR. --- faup1090.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faup1090.c b/faup1090.c index 43e2959..ae30e5e 100644 --- a/faup1090.c +++ b/faup1090.c @@ -63,7 +63,7 @@ static void faupInitConfig(void) { Modes.check_crc = 1; Modes.net = 1; Modes.net_heartbeat_interval = MODES_NET_HEARTBEAT_INTERVAL; - Modes.maxRange = 1852 * 300; // 300NM default max range + Modes.maxRange = 1852 * 360; // 360NM default max range; this also disables receiver-relative positions Modes.quiet = 1; Modes.net_output_flush_size = MODES_OUT_FLUSH_SIZE; Modes.net_output_flush_interval = 200; // milliseconds @@ -111,7 +111,7 @@ static void showHelp(void) { "--net-fatsv-port FlightAware TSV output port (default: 10001)\n" "--lat Reference/receiver latitude for surface posn (opt)\n" "--lon Reference/receiver longitude for surface posn (opt)\n" -"--max-range Absolute maximum range for position decoding (in nm, default: 300)\n" +"--max-range Absolute maximum range for position decoding (in nm, default: 360)\n" "--stdout REQUIRED. Write results to stdout.\n" "--help Show this help\n" "\n", From d9eec668cf912be4cb51ca8fea801cbb9c40bd37 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 21 Jan 2016 19:42:37 +0000 Subject: [PATCH 5/6] Track what data we got via TIS-B, report it as such. --- dump1090.h | 1 + mode_s.c | 5 +++++ net_io.c | 64 ++++++++++++++++++++++++++++++++++++------------------ track.c | 6 +++++ track.h | 1 + 5 files changed, 56 insertions(+), 21 deletions(-) diff --git a/dump1090.h b/dump1090.h index d3748b6..7ab45d1 100644 --- a/dump1090.h +++ b/dump1090.h @@ -165,6 +165,7 @@ typedef struct rtlsdr_dev rtlsdr_dev_t; #define MODES_ACFLAGS_FROM_MLAT (1<<18) // Data was derived from multilateration #define MODES_ACFLAGS_ALTITUDE_HAE_VALID (1<<19) // altitude_hae is valid #define MODES_ACFLAGS_HAE_DELTA_VALID (1<<20) // hae_delta is valid +#define MODES_ACFLAGS_FROM_TISB (1<<21) // Data was derived from TIS-B messages #define MODES_ACFLAGS_LLEITHER_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID) #define MODES_ACFLAGS_LLBOTH_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID) diff --git a/mode_s.c b/mode_s.c index b53bd4f..b487a01 100644 --- a/mode_s.c +++ b/mode_s.c @@ -714,6 +714,11 @@ static void decodeExtendedSquitter(struct modesMessage *mm) // Check CF on DF18 to work out the format of the ES and whether we need to look for an IMF bit if (mm->msgtype == 18) { + /* we just globally tag any DF18 as TIS-B, + * which is not strictly true but close enough + */ + mm->bFlags |= MODES_ACFLAGS_FROM_TISB; + switch (mm->cf) { case 0: // ADS-B ES/NT devices that report the ICAO 24-bit address in the AA field break; diff --git a/net_io.c b/net_io.c index 361c668..261cc88 100644 --- a/net_io.c +++ b/net_io.c @@ -879,6 +879,31 @@ static const char *jsonEscapeString(const char *str) { return buf; } +static char *append_flags(char *p, char *end, int flags) +{ + p += sprintf(p, end-p, "["); + if (flags & MODES_ACFLAGS_SQUAWK_VALID) + p += snprintf(p, end-p, "\"squawk\","); + if (flags & MODES_ACFLAGS_CALLSIGN_VALID) + p += snprintf(p, end-p, "\"callsign\","); + if (flags & MODES_ACFLAGS_LATLON_VALID) + p += snprintf(p, end-p, "\"lat\",\"lon\","); + if (flags & MODES_ACFLAGS_ALTITUDE_VALID) + p += snprintf(p, end-p, "\"altitude\","); + if (flags & MODES_ACFLAGS_HEADING_VALID) + p += snprintf(p, end-p, "\"track\","); + if (flags & MODES_ACFLAGS_SPEED_VALID) + p += snprintf(p, end-p, "\"speed\","); + if (flags & MODES_ACFLAGS_VERTRATE_VALID) + p += snprintf(p, end-p, "\"vert_rate\","); + if (flags & MODES_ACFLAGS_CATEGORY_VALID) + p += snprintf(p, end-p, "\"category\","); + if (p[-1] != '[') + --p; + p += snprintf(p, end-p, "]"); + return p; +} + char *generateAircraftJson(const char *url_path, int *len) { uint64_t now = mstime(); struct aircraft *a; @@ -929,26 +954,12 @@ char *generateAircraftJson(const char *url_path, int *len) { if (a->bFlags & MODES_ACFLAGS_CATEGORY_VALID) p += snprintf(p, end-p, ",\"category\":\"%02X\"", a->category); if (a->mlatFlags) { - p += snprintf(p, end-p, ",\"mlat\":["); - if (a->mlatFlags & MODES_ACFLAGS_SQUAWK_VALID) - p += snprintf(p, end-p, "\"squawk\","); - if (a->mlatFlags & MODES_ACFLAGS_CALLSIGN_VALID) - p += snprintf(p, end-p, "\"callsign\","); - if (a->mlatFlags & MODES_ACFLAGS_LATLON_VALID) - p += snprintf(p, end-p, "\"lat\",\"lon\","); - if (a->mlatFlags & MODES_ACFLAGS_ALTITUDE_VALID) - p += snprintf(p, end-p, "\"altitude\","); - if (a->mlatFlags & MODES_ACFLAGS_HEADING_VALID) - p += snprintf(p, end-p, "\"track\","); - if (a->mlatFlags & MODES_ACFLAGS_SPEED_VALID) - p += snprintf(p, end-p, "\"speed\","); - if (a->mlatFlags & MODES_ACFLAGS_VERTRATE_VALID) - p += snprintf(p, end-p, "\"vert_rate\","); - if (a->mlatFlags & MODES_ACFLAGS_CATEGORY_VALID) - p += snprintf(p, end-p, "\"category\","); - if (p[-1] != '[') - --p; - p += snprintf(p, end-p, "]"); + p += snprintf(p, end-p, ",\"mlat\":"); + p = append_flags(p, end, a->mlatFlags); + } + if (a->tisbFlags) { + p += snprintf(p, end-p, ",\"tisb\":"); + p = append_flags(p, end, a->tisbFlags); } p += snprintf(p, end-p, ",\"messages\":%ld,\"seen\":%.1f,\"rssi\":%.1f}", @@ -1554,7 +1565,7 @@ static void modesReadFromClient(struct client *c) { } } -#define TSV_MAX_PACKET_SIZE 160 +#define TSV_MAX_PACKET_SIZE 180 static void writeFATSV() { @@ -1599,6 +1610,7 @@ static void writeFATSV() char *p, *end; int flags; + int used_tisb = 0; // skip non-ICAO if (a->addr & MODES_NON_ICAO_ADDRESS) @@ -1621,6 +1633,7 @@ static void writeFATSV() alt = a->altitude; altAge = now - a->seenAltitude; altValid = (altAge <= 30000); + used_tisb |= (a->tisbFlags & MODES_ACFLAGS_ALTITUDE_VALID); } if (flags & MODES_ACFLAGS_AOG_VALID) { @@ -1633,21 +1646,26 @@ static void writeFATSV() altAge = 0; ground = 1; } + + used_tisb |= (a->tisbFlags & MODES_ACFLAGS_AOG_VALID); } if (flags & MODES_ACFLAGS_LATLON_VALID) { latlonAge = now - a->seenLatLon; latlonValid = (latlonAge <= 30000); + used_tisb |= (a->tisbFlags & MODES_ACFLAGS_LATLON_VALID); } if (flags & MODES_ACFLAGS_HEADING_VALID) { trackAge = now - a->seenTrack; trackValid = (trackAge <= 30000); + used_tisb |= (a->tisbFlags & MODES_ACFLAGS_HEADING_VALID); } if (flags & MODES_ACFLAGS_SPEED_VALID) { speedAge = now - a->seenSpeed; speedValid = (speedAge <= 30000); + used_tisb |= (a->tisbFlags & MODES_ACFLAGS_SPEED_VALID); } // don't send mode S very often @@ -1729,6 +1747,10 @@ static void writeFATSV() useful = 1; } + if (used_tisb) { + p += snprintf(p, bufsize(p,end), "\ttisb\t1"); + } + // if we didn't get at least an alt or a speed or a latlon or // a heading, bail out. We don't need to do anything special // to unwind prepareWrite(). diff --git a/track.c b/track.c index 744bf88..eb22eb3 100644 --- a/track.c +++ b/track.c @@ -597,6 +597,12 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm) else a->mlatFlags = (a->mlatFlags & a->bFlags) & ~mm->bFlags; + // Same for TIS-B + if (mm->bFlags & MODES_ACFLAGS_FROM_TISB) + a->tisbFlags = (a->tisbFlags & a->bFlags) | mm->bFlags; + else + a->tisbFlags = (a->tisbFlags & a->bFlags) & ~mm->bFlags; + if (mm->msgtype == 32) { int flags = a->modeACflags; if ((flags & (MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODEC_OLD)) == MODEAC_MSG_MODEC_OLD) { diff --git a/track.h b/track.h index 84ee85b..9153050 100644 --- a/track.h +++ b/track.h @@ -78,6 +78,7 @@ struct aircraft { uint64_t seenTrack; // Time (millis) at which track was measured int mlatFlags; // Data derived from mlat messages + int tisbFlags; // Data derived from TIS-B messages long messages; // Number of Mode S messages received int modeA; // Squawk From c4e162287dbd073f8b63d11d6220b69a5becfb5f Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 21 Jan 2016 20:22:18 +0000 Subject: [PATCH 6/6] Oops, sprintf -> snprintf --- net_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net_io.c b/net_io.c index 261cc88..3d12a6b 100644 --- a/net_io.c +++ b/net_io.c @@ -881,7 +881,7 @@ static const char *jsonEscapeString(const char *str) { static char *append_flags(char *p, char *end, int flags) { - p += sprintf(p, end-p, "["); + p += snprintf(p, end-p, "["); if (flags & MODES_ACFLAGS_SQUAWK_VALID) p += snprintf(p, end-p, "\"squawk\","); if (flags & MODES_ACFLAGS_CALLSIGN_VALID)