Mlat synthetic message detection.
Notice synthetic mlat messages by looking for messages with a magic timestamp value. If they arrive, tag the derived data as mlat-derived. Don't include mlat-derived output in FATSV output to avoid loops.
This commit is contained in:
parent
8f08c1b87f
commit
12a7d45e75
3
debian/changelog
vendored
3
debian/changelog
vendored
|
@ -18,6 +18,9 @@ dump1090-mutability (1.15~dev) UNRELEASED; urgency=medium
|
||||||
* Support DC filtering (quite expensive) via --dcfilter
|
* Support DC filtering (quite expensive) via --dcfilter
|
||||||
* Track age of heading/speed/altitude; use this when deciding what to emit
|
* Track age of heading/speed/altitude; use this when deciding what to emit
|
||||||
in FATSV format
|
in FATSV format
|
||||||
|
* Notice synthetic mlat messages by looking for messages with a magic
|
||||||
|
timestamp value. If they arrive, tag the derived data as mlat-derived.
|
||||||
|
Don't include mlat-derived output in FATSV output to avoid loops.
|
||||||
|
|
||||||
-- Oliver Jowett <oliver@mutability.co.uk> Thu, 19 Feb 2015 22:39:19 +0000
|
-- Oliver Jowett <oliver@mutability.co.uk> Thu, 19 Feb 2015 22:39:19 +0000
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,7 @@ typedef struct rtlsdr_dev rtlsdr_dev_t;
|
||||||
#define MODES_ACFLAGS_LATLON_REL_OK (1<<15) // Indicates it's OK to do a relative CPR
|
#define MODES_ACFLAGS_LATLON_REL_OK (1<<15) // Indicates it's OK to do a relative CPR
|
||||||
#define MODES_ACFLAGS_REL_CPR_USED (1<<16) // Lat/lon derived from relative CPR
|
#define MODES_ACFLAGS_REL_CPR_USED (1<<16) // Lat/lon derived from relative CPR
|
||||||
#define MODES_ACFLAGS_CATEGORY_VALID (1<<17) // Aircraft category is known
|
#define MODES_ACFLAGS_CATEGORY_VALID (1<<17) // Aircraft category is known
|
||||||
|
#define MODES_ACFLAGS_FROM_MLAT (1<<18) // Data was derived from multilateration
|
||||||
|
|
||||||
#define MODES_ACFLAGS_LLEITHER_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID)
|
#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)
|
#define MODES_ACFLAGS_LLBOTH_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID)
|
||||||
|
|
8
mode_s.c
8
mode_s.c
|
@ -59,6 +59,11 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/* A timestamp that indicates the data is synthetic, created from a
|
||||||
|
* multilateration result
|
||||||
|
*/
|
||||||
|
#define MAGIC_MLAT_TIMESTAMP 0xFF01A71A71A7ULL
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
// Given the Downlink Format (DF) of the message, return the message length in bits.
|
// Given the Downlink Format (DF) of the message, return the message length in bits.
|
||||||
|
@ -563,6 +568,9 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
|
||||||
|
|
||||||
mm->bFlags = 0;
|
mm->bFlags = 0;
|
||||||
|
|
||||||
|
if (mm->remote && mm->timestampMsg == MAGIC_MLAT_TIMESTAMP)
|
||||||
|
mm->bFlags |= MODES_ACFLAGS_FROM_MLAT;
|
||||||
|
|
||||||
// AA (Address announced)
|
// AA (Address announced)
|
||||||
if (mm->msgtype == 11 || mm->msgtype == 17 || mm->msgtype == 18) {
|
if (mm->msgtype == 11 || mm->msgtype == 17 || mm->msgtype == 18) {
|
||||||
mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
|
mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
|
||||||
|
|
19
net_io.c
19
net_io.c
|
@ -1513,6 +1513,8 @@ static void writeFATSV()
|
||||||
|
|
||||||
char *p, *end;
|
char *p, *end;
|
||||||
|
|
||||||
|
int flags;
|
||||||
|
|
||||||
// skip non-ICAO
|
// skip non-ICAO
|
||||||
if (a->addr & MODES_NON_ICAO_ADDRESS)
|
if (a->addr & MODES_NON_ICAO_ADDRESS)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1527,16 +1529,19 @@ static void writeFATSV()
|
||||||
|
|
||||||
emittedAge = (now - a->fatsv_last_emitted);
|
emittedAge = (now - a->fatsv_last_emitted);
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
|
// ignore all mlat-derived data
|
||||||
|
flags = a->bFlags & ~a->mlatFlags;
|
||||||
|
|
||||||
|
if (flags & MODES_ACFLAGS_ALTITUDE_VALID) {
|
||||||
alt = a->altitude;
|
alt = a->altitude;
|
||||||
altAge = now - a->seenAltitude;
|
altAge = now - a->seenAltitude;
|
||||||
altValid = (altAge <= 30000);
|
altValid = (altAge <= 30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_AOG_VALID) {
|
if (flags & MODES_ACFLAGS_AOG_VALID) {
|
||||||
groundValid = 1;
|
groundValid = 1;
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_AOG) {
|
if (flags & MODES_ACFLAGS_AOG) {
|
||||||
// force zero altitude on ground
|
// force zero altitude on ground
|
||||||
alt = 0;
|
alt = 0;
|
||||||
altValid = 1;
|
altValid = 1;
|
||||||
|
@ -1545,17 +1550,17 @@ static void writeFATSV()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) {
|
if (flags & MODES_ACFLAGS_LATLON_VALID) {
|
||||||
latlonAge = now - a->seenLatLon;
|
latlonAge = now - a->seenLatLon;
|
||||||
latlonValid = (latlonAge <= 30000);
|
latlonValid = (latlonAge <= 30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) {
|
if (flags & MODES_ACFLAGS_HEADING_VALID) {
|
||||||
trackAge = now - a->seenTrack;
|
trackAge = now - a->seenTrack;
|
||||||
trackValid = (trackAge <= 30000);
|
trackValid = (trackAge <= 30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_SPEED_VALID) {
|
if (flags & MODES_ACFLAGS_SPEED_VALID) {
|
||||||
speedAge = now - a->seenSpeed;
|
speedAge = now - a->seenSpeed;
|
||||||
speedValid = (speedAge <= 30000);
|
speedValid = (speedAge <= 30000);
|
||||||
}
|
}
|
||||||
|
@ -1604,7 +1609,7 @@ static void writeFATSV()
|
||||||
p += snprintf(p, bufsize(p,end), "\tident\t%s", a->flight);
|
p += snprintf(p, bufsize(p,end), "\tident\t%s", a->flight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->bFlags & MODES_ACFLAGS_SQUAWK_VALID) {
|
if (flags & MODES_ACFLAGS_SQUAWK_VALID) {
|
||||||
p += snprintf(p, bufsize(p,end), "\tsquawk\t%04x", a->modeA);
|
p += snprintf(p, bufsize(p,end), "\tsquawk\t%04x", a->modeA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
track.c
7
track.c
|
@ -535,6 +535,13 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
|
||||||
// Update the aircrafts a->bFlags to reflect the newly received mm->bFlags;
|
// Update the aircrafts a->bFlags to reflect the newly received mm->bFlags;
|
||||||
a->bFlags |= mm->bFlags;
|
a->bFlags |= mm->bFlags;
|
||||||
|
|
||||||
|
// Update mlat flags. The mlat flags indicate which bits in bFlags
|
||||||
|
// were last set based on a mlat-derived message.
|
||||||
|
if (mm->bFlags & MODES_ACFLAGS_FROM_MLAT)
|
||||||
|
a->mlatFlags = (a->mlatFlags & a->bFlags) | mm->bFlags;
|
||||||
|
else
|
||||||
|
a->mlatFlags = (a->mlatFlags & a->bFlags) & ~mm->bFlags;
|
||||||
|
|
||||||
if (mm->msgtype == 32) {
|
if (mm->msgtype == 32) {
|
||||||
int flags = a->modeACflags;
|
int flags = a->modeACflags;
|
||||||
if ((flags & (MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODEC_OLD)) == MODEAC_MSG_MODEC_OLD) {
|
if ((flags & (MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODEC_OLD)) == MODEAC_MSG_MODEC_OLD) {
|
||||||
|
|
2
track.h
2
track.h
|
@ -75,6 +75,8 @@ struct aircraft {
|
||||||
uint64_t seenSpeed; // Time (millis) at which speed was measured
|
uint64_t seenSpeed; // Time (millis) at which speed was measured
|
||||||
uint64_t seenTrack; // Time (millis) at which track was measured
|
uint64_t seenTrack; // Time (millis) at which track was measured
|
||||||
|
|
||||||
|
int mlatFlags; // Data derived from mlat messages
|
||||||
|
|
||||||
long messages; // Number of Mode S messages received
|
long messages; // Number of Mode S messages received
|
||||||
int modeA; // Squawk
|
int modeA; // Squawk
|
||||||
int modeC; // Altitude
|
int modeC; // Altitude
|
||||||
|
|
Loading…
Reference in a new issue