Changes to Mode A/C/S matchup code

Try to improve the matching of ModeA/C codes to Known Mode-S
This commit is contained in:
Malcolm Robb 2013-04-26 01:40:52 +01:00
parent 25f92e54ba
commit 2acb0947f0

View file

@ -75,6 +75,10 @@
#define MODEAC_MSG_SQUELCH_LEVEL 0x07FF /* Average signal strength limit */ #define MODEAC_MSG_SQUELCH_LEVEL 0x07FF /* Average signal strength limit */
#define MODEAC_MSG_FLAG (1<<0) #define MODEAC_MSG_FLAG (1<<0)
#define MODEAC_MSG_MODES_HIT (1<<1) #define MODEAC_MSG_MODES_HIT (1<<1)
#define MODEAC_MSG_MODEA_HIT (1<<2)
#define MODEAC_MSG_MODEC_HIT (1<<3)
#define MODEAC_MSG_MODEA_ONLY (1<<4)
#define MODEAC_MSG_MODEC_OLD (1<<5)
#define MODES_PREAMBLE_US 8 /* microseconds = bits */ #define MODES_PREAMBLE_US 8 /* microseconds = bits */
#define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2) #define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2)
@ -286,9 +290,6 @@ struct modesMessage {
int um; /* Request extraction of downlink request. */ int um; /* Request extraction of downlink request. */
int modeA; /* 13 bits identity (Squawk). */ int modeA; /* 13 bits identity (Squawk). */
// DF32 ModeA & Mode C
int modeC; /* Decoded Mode C */
/* Fields used by multiple message types. */ /* Fields used by multiple message types. */
int altitude, unit; int altitude, unit;
}; };
@ -1005,7 +1006,7 @@ int detectModeA(uint16_t *m, struct modesMessage *mm)
} }
// Input format is : 00:A4:A2:A1:00:B4:B2:B1:00:C4:C2:C1:00:D4:D2:D1 // Input format is : 00:A4:A2:A1:00:B4:B2:B1:00:C4:C2:C1:00:D4:D2:D1
int ModeAToModeC(unsigned int ModeA ) int ModeAToModeC(unsigned int ModeA)
{ {
unsigned int FiveHundreds = 0; unsigned int FiveHundreds = 0;
unsigned int OneHundreds = 0; unsigned int OneHundreds = 0;
@ -1062,10 +1063,6 @@ void decodeModeAMessage(struct modesMessage *mm, int ModeA)
// Flag ident in flight status // Flag ident in flight status
mm->fs = ModeA & 0x0080; mm->fs = ModeA & 0x0080;
// Convert ModeA to ModeC and use as an altitude
mm->modeC = ModeAToModeC(ModeA);
mm->altitude = mm->modeC * 100;
// Not much else we can tell from a Mode A/C reply. // Not much else we can tell from a Mode A/C reply.
// Just fudge up a few bits to keep other code happy // Just fudge up a few bits to keep other code happy
mm->crcok = 1; mm->crcok = 1;
@ -1543,7 +1540,6 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
if (mm->msgtype == 0 || mm->msgtype == 4 || if (mm->msgtype == 0 || mm->msgtype == 4 ||
mm->msgtype == 16 || mm->msgtype == 20) { mm->msgtype == 16 || mm->msgtype == 20) {
mm->altitude = decodeAC13Field(msg, &mm->unit); mm->altitude = decodeAC13Field(msg, &mm->unit);
mm->modeC = (mm->altitude + 49) / 100;
} }
/* Decode extended squitter specific stuff. */ /* Decode extended squitter specific stuff. */
@ -1567,7 +1563,6 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
mm->fflag = msg[6] & (1<<2); mm->fflag = msg[6] & (1<<2);
mm->tflag = msg[6] & (1<<3); mm->tflag = msg[6] & (1<<3);
mm->altitude = decodeAC12Field(msg,&mm->unit); mm->altitude = decodeAC12Field(msg,&mm->unit);
mm->modeC = (mm->altitude + 49) / 100;
mm->raw_latitude = ((msg[6] & 3) << 15) | mm->raw_latitude = ((msg[6] & 3) << 15) |
(msg[7] << 7) | (msg[7] << 7) |
(msg[8] >> 1); (msg[8] >> 1);
@ -1742,9 +1737,10 @@ void displayModesMessage(struct modesMessage *mm) {
if (mm->fs & 0x0080) { if (mm->fs & 0x0080) {
printf(" Mode A : %04x IDENT\n", mm->modeA); printf(" Mode A : %04x IDENT\n", mm->modeA);
} else { } else {
int modeC = ModeAToModeC(mm->modeA);
printf(" Mode A : %04x\n", mm->modeA); printf(" Mode A : %04x\n", mm->modeA);
if (mm->altitude >= -1300) if (modeC >= -13)
{printf(" Mode C : %d feet\n", mm->altitude);} {printf(" Mode C : %d feet\n", (modeC * 100));}
} }
} else { } else {
@ -2170,10 +2166,19 @@ struct aircraft *interactiveCreateAircraft(struct modesMessage *mm) {
a->sbsflags = 0; a->sbsflags = 0;
a->seen = time(NULL); a->seen = time(NULL);
a->messages = 0; a->messages = 0;
a->modeACflags = 0; if (mm->msgtype == 32) {
a->modeA = 0; a->modeACflags = MODEAC_MSG_FLAG;
a->modeC = 0; a->modeA = mm->modeA;
a->altitude = 0; a->modeC = ModeAToModeC(mm->modeA | mm->fs);
a->altitude = a->modeC * 100;
if (a->modeC < -12)
{a->modeACflags |= MODEAC_MSG_MODEA_ONLY;}
} else {
a->modeACflags = 0;
a->modeA = 0;
a->modeC = 0;
a->altitude = 0;
}
a->modeAcount = 0; a->modeAcount = 0;
a->modeCcount = 0; a->modeCcount = 0;
a->next = NULL; a->next = NULL;
@ -2223,17 +2228,23 @@ void interactiveUpdateAircraftModeA(struct aircraft *a) {
// First check for Mode-A <=> Mode-S Squawk matches // First check for Mode-A <=> Mode-S Squawk matches
if (a->modeA == b->modeA) { // If a 'real' Mode-S ICAO exists using this Mode-A Squawk if (a->modeA == b->modeA) { // If a 'real' Mode-S ICAO exists using this Mode-A Squawk
b->modeAcount++; b->modeAcount = a->messages;
a->modeACflags |= MODEAC_MSG_MODEA_HIT;
if ( (b->modeAcount > 0) && if ( (b->modeAcount > 0) &&
((b->modeCcount > 1) || (a->modeC < -12)) ) ( (b->modeCcount > 1)
{a->modeACflags |= MODEAC_MSG_MODES_HIT;} // flag this ModeA/C probably belongs to a known Mode S || (a->modeACflags & MODEAC_MSG_MODEA_ONLY)) ) // Allow Mode-A only matches if this Mode-A is invalid Mode-C
{a->modeACflags |= MODEAC_MSG_MODES_HIT;} // flag this ModeA/C probably belongs to a known Mode S
} }
// Next check for Mode-C <=> Mode-S Altitude matches // Next check for Mode-C <=> Mode-S Altitude matches
if (a->modeC == b->modeC) { // If a 'real' Mode S ICAO exists at this Mode-C Altitude if ( (a->modeC == b->modeC ) // If a 'real' Mode-S ICAO exists at this Mode-C Altitude
b->modeCcount++; || (a->modeC == b->modeC + 1) // or this Mode-C - 100 ft
if ((b->modeAcount > 0) && (b->modeCcount > 1)) || (a->modeC + 1 == b->modeC ) ) { // or this Mode-C + 100 ft
{a->modeACflags |= MODEAC_MSG_MODES_HIT;} // flag this ModeA/C probably belongs to a known Mode S b->modeCcount = a->messages;
a->modeACflags |= MODEAC_MSG_MODEC_HIT;
if ( (b->modeAcount > 0) &&
(b->modeCcount > 1) )
{a->modeACflags |= (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEC_OLD);} // flag this ModeA/C probably belongs to a known Mode S
} }
} }
b = b->next; b = b->next;
@ -2247,8 +2258,8 @@ void interactiveUpdateAircraftModeS() {
int flags = a->modeACflags; int flags = a->modeACflags;
if (flags & MODEAC_MSG_FLAG) { // find any fudged ICAO records if (flags & MODEAC_MSG_FLAG) { // find any fudged ICAO records
// clear the hit bit // clear the current A,C and S hit bits ready for this attempt
a->modeACflags = flags & ~MODEAC_MSG_MODES_HIT; a->modeACflags = flags & ~(MODEAC_MSG_MODEA_HIT | MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODES_HIT);
interactiveUpdateAircraftModeA(a); // and attempt to match them with Mode-S interactiveUpdateAircraftModeA(a); // and attempt to match them with Mode-S
} }
@ -2488,28 +2499,29 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
if (mm->msgtype == 0 || mm->msgtype == 4 || mm->msgtype == 20) { if (mm->msgtype == 0 || mm->msgtype == 4 || mm->msgtype == 20) {
if ( (a->modeCcount) // if we've a modeCcount already if ( (a->modeCcount) // if we've a modeCcount already
&& (a->modeC != mm->modeC ) // and Altitude has changed && (a->altitude != mm->altitude ) ) // and Altitude has changed
&& (a->modeC != mm->modeC + 1) // and Altitude not changed by +100 feet // && (a->modeC != mm->modeC + 1) // and Altitude not changed by +100 feet
&& (a->modeC + 1 != mm->modeC ) ) // and Altitude not changes by -100 feet // && (a->modeC + 1 != mm->modeC ) ) // and Altitude not changes by -100 feet
{a->modeCcount = 0;} //....zero the hit count {a->modeCcount = 0;} //....zero the hit count
a->altitude = mm->altitude; a->altitude = mm->altitude;
a->modeC = mm->modeC; a->modeC = (mm->altitude + 49) / 100;
} else if(mm->msgtype == 5 || mm->msgtype == 21) { } else if(mm->msgtype == 5 || mm->msgtype == 21) {
if (a->modeA != mm->modeA) { if (a->modeA != mm->modeA) {
a->modeAcount = 0; // Squawk has changed, so zero the hit count a->modeAcount = 0; // Squawk has changed, so zero the hit count
} }
a->modeA = mm->modeA; a->modeA = mm->modeA;
} else if (mm->msgtype == 17) { } else if (mm->msgtype == 17) {
if (mm->metype >= 1 && mm->metype <= 4) { if (mm->metype >= 1 && mm->metype <= 4) {
memcpy(a->flight, mm->flight, sizeof(a->flight)); memcpy(a->flight, mm->flight, sizeof(a->flight));
} else if (mm->metype >= 9 && mm->metype <= 18) { } else if (mm->metype >= 9 && mm->metype <= 18) {
if ( (a->modeCcount) // if we've a modeCcount already if ( (a->modeCcount) // if we've a modeCcount already
&& (a->modeC != mm->modeC ) // and Altitude has changed && (a->altitude != mm->altitude ) ) // and Altitude has changed
&& (a->modeC != mm->modeC + 1) // and Altitude not changed by +100 feet // && (a->modeC != mm->modeC + 1) // and Altitude not changed by +100 feet
&& (a->modeC + 1 != mm->modeC ) ) // and Altitude not changes by -100 feet // && (a->modeC + 1 != mm->modeC ) ) // and Altitude not changes by -100 feet
{a->modeCcount = 0;} //....zero the hit count {a->modeCcount = 0;} //....zero the hit count
a->altitude = mm->altitude; a->altitude = mm->altitude;
a->modeC = mm->modeC; a->modeC = (mm->altitude + 49) / 100;
if (mm->fflag) { if (mm->fflag) {
a->odd_cprlat = mm->raw_latitude; a->odd_cprlat = mm->raw_latitude;
a->odd_cprlon = mm->raw_longitude; a->odd_cprlon = mm->raw_longitude;
@ -2534,11 +2546,24 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
} }
} }
} else if(mm->msgtype == 32) { } else if(mm->msgtype == 32) {
a->modeACflags = MODEAC_MSG_FLAG;
a->modeA = mm->modeA; int flags = a->modeACflags;
a->modeC = mm->modeC;
a->altitude = mm->altitude; if ((flags & (MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODEC_OLD)) == MODEAC_MSG_MODEC_OLD) {
interactiveUpdateAircraftModeA(a); //
// This Mode-C doesn't currently hit any known Mode-S, but it used to because MODEAC_MSG_MODEC_OLD is
// set So the aircraft it used to match has either changed altitude, or gone out of our receiver range
//
// We've now received this Mode-A/C again, so it must be a new aircraft. It could be another aircraft
// at the same Mode-C altitude, or it could be a new airctraft with a new Mods-A squawk.
//
// To avoid masking this aircraft from the interactive display, clear the MODEAC_MSG_MODES_OLD flag
// and set messages to 1;
//
a->modeACflags = flags & ~MODEAC_MSG_MODEC_OLD;
a->messages = 1;
}
} }
return a; return a;
} }
@ -2573,9 +2598,10 @@ void interactiveShowData(void) {
char gs[5] = " "; char gs[5] = " ";
char spacer = '\0'; char spacer = '\0';
if ( ((a->modeACflags & MODEAC_MSG_FLAG) == 0) if ( (((a->modeACflags & (MODEAC_MSG_FLAG )) == 0 ) )
|| (((a->modeACflags & MODEAC_MSG_MODES_HIT) == 0) && (altitude == 0) && (msgs > 4)) || (((a->modeACflags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEA_ONLY)) == MODEAC_MSG_MODEA_ONLY) && (msgs > 4 ) )
|| (((a->modeACflags & MODEAC_MSG_MODES_HIT) == 0) && (msgs > 127)) ) { || (((a->modeACflags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEC_OLD )) == 0 ) && (msgs > 127) )
) {
/* Convert units to metric if --metric was specified. */ /* Convert units to metric if --metric was specified. */
if (Modes.metric) { if (Modes.metric) {