Support more DF18 message formats. Test for the IMF bit where appropriate.

Fixes #4.
This commit is contained in:
Oliver Jowett 2015-01-29 23:08:33 +00:00
parent ffd6690063
commit 9381a20198

View file

@ -545,26 +545,9 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
mm->bFlags = 0; mm->bFlags = 0;
// CF (Control field)
// done first so we can use it in AA.
if (mm->msgtype == 18) {
mm->cf = msg[0] & 7;
}
// 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]);
if (mm->msgtype == 18 && (mm->cf != 0 && mm->cf != 6))
mm->addr |= MODES_NON_ICAO_ADDRESS; // don't confuse this with any ICAO address
if (!mm->correctedbits && (mm->msgtype != 11 || mm->iid == 0)) {
// No CRC errors seen, and either it was an DF17/18 extended squitter
// or a DF11 acquisition squitter with II = 0. We probably have the right address.
// NB this is the only place that adds addresses!
icaoFilterAdd(mm->addr);
}
} }
// AC (Altitude Code) // AC (Altitude Code)
@ -590,6 +573,11 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
// CC (Cross-link capability) not decoded // CC (Cross-link capability) not decoded
// CF (Control field)
if (mm->msgtype == 18) {
mm->cf = msg[0] & 7;
}
// DR (Downlink Request) not decoded // DR (Downlink Request) not decoded
// FS (Flight Status) // FS (Flight Status)
@ -624,11 +612,7 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
// ME (message, extended squitter) // ME (message, extended squitter)
if (mm->msgtype == 17 || // Extended squitter if (mm->msgtype == 17 || // Extended squitter
(mm->msgtype == 18 && // Extended squitter/non-transponder: mm->msgtype == 18) { // Extended squitter/non-transponder:
(mm->cf == 0 || // ADS-B ES/NT devices that report the ICAO 24-bit address in the AA field
mm->cf == 1 || // Reserved for ADS-B for ES/NT devices that use other addressing techniques in the AA field
mm->cf == 5 || // TIS-B messages that relay ADS-B Messages using anonymous 24-bit addresses
mm->cf == 6))) { // ADS-B rebroadcast using the same type codes and message formats as defined for DF = 17 ADS-B messages
decodeExtendedSquitter(mm); decodeExtendedSquitter(mm);
} }
@ -645,6 +629,17 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
mm->bFlags |= MODES_ACFLAGS_AOG; mm->bFlags |= MODES_ACFLAGS_AOG;
} }
if (!mm->correctedbits && (mm->msgtype == 17 || mm->msgtype == 18 || (mm->msgtype != 11 || mm->iid == 0))) {
// No CRC errors seen, and either it was an DF17/18 extended squitter
// or a DF11 acquisition squitter with II = 0. We probably have the right address.
// We wait until here to do this as we may have needed to decode an ES to note
// the type of address in DF18 messages.
// NB this is the only place that adds addresses!
icaoFilterAdd(mm->addr);
}
// all done // all done
return 0; return 0;
} }
@ -684,6 +679,39 @@ static void decodeExtendedSquitter(struct modesMessage *mm)
int metype = mm->metype = msg[4] >> 3; // Extended squitter message type int metype = mm->metype = msg[4] >> 3; // Extended squitter message type
int mesub = mm->mesub = (metype == 29 ? ((msg[4]&6)>>1) : (msg[4] & 7)); // Extended squitter message subtype int mesub = mm->mesub = (metype == 29 ? ((msg[4]&6)>>1) : (msg[4] & 7)); // Extended squitter message subtype
int check_imf = 0;
// 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) {
switch (mm->cf) {
case 0: // ADS-B ES/NT devices that report the ICAO 24-bit address in the AA field
break;
case 1: // Reserved for ADS-B for ES/NT devices that use other addressing techniques in the AA field
case 5: // TIS-B messages that relay ADS-B Messages using anonymous 24-bit addresses (format not explicitly defined, but it seems to follow DF17)
mm->addr |= MODES_NON_ICAO_ADDRESS;
break;
case 2: // Fine TIS-B message (formats are close enough to DF17 for our purposes)
case 6: // ADS-B rebroadcast using the same type codes and message formats as defined for DF = 17 ADS-B messages
check_imf = 1;
break;
case 3: // Coarse TIS-B airborne position and velocity.
// TODO: decode me.
// For now we only look at the IMF bit.
if (msg[4] & 0x80)
mm->addr |= MODES_NON_ICAO_ADDRESS;
return;
default: // All others, we don't know the format.
mm->addr |= MODES_NON_ICAO_ADDRESS; // assume non-ICAO
return;
}
}
switch (metype) { switch (metype) {
case 1: case 2: case 3: case 4: { case 1: case 2: case 3: case 4: {
// Aircraft Identification and Category // Aircraft Identification and Category
@ -714,6 +742,9 @@ static void decodeExtendedSquitter(struct modesMessage *mm)
} }
case 19: { // Airborne Velocity Message case 19: { // Airborne Velocity Message
if (check_imf && (msg[5] & 0x80))
mm->addr |= MODES_NON_ICAO_ADDRESS;
// Presumably airborne if we get an Airborne Velocity Message // Presumably airborne if we get an Airborne Velocity Message
mm->bFlags |= MODES_ACFLAGS_AOG_VALID; mm->bFlags |= MODES_ACFLAGS_AOG_VALID;
@ -788,6 +819,9 @@ static void decodeExtendedSquitter(struct modesMessage *mm)
// Ground position // Ground position
int movement; int movement;
if (check_imf && (msg[6] & 0x08))
mm->addr |= MODES_NON_ICAO_ADDRESS;
mm->bFlags |= MODES_ACFLAGS_AOG_VALID | MODES_ACFLAGS_AOG; mm->bFlags |= MODES_ACFLAGS_AOG_VALID | MODES_ACFLAGS_AOG;
mm->raw_latitude = ((msg[6] & 3) << 15) | (msg[7] << 7) | (msg[8] >> 1); mm->raw_latitude = ((msg[6] & 3) << 15) | (msg[7] << 7) | (msg[8] >> 1);
mm->raw_longitude = ((msg[8] & 1) << 16) | (msg[9] << 8) | (msg[10]); mm->raw_longitude = ((msg[8] & 1) << 16) | (msg[9] << 8) | (msg[10]);
@ -813,6 +847,9 @@ static void decodeExtendedSquitter(struct modesMessage *mm)
case 20: case 21: case 22: { // Airborne position, GNSS HAE case 20: case 21: case 22: { // Airborne position, GNSS HAE
int AC12Field = ((msg[5] << 4) | (msg[6] >> 4)) & 0x0FFF; int AC12Field = ((msg[5] << 4) | (msg[6] >> 4)) & 0x0FFF;
if (check_imf && (msg[4] & 0x01))
mm->addr |= MODES_NON_ICAO_ADDRESS;
mm->bFlags |= MODES_ACFLAGS_AOG_VALID; mm->bFlags |= MODES_ACFLAGS_AOG_VALID;
if (metype != 0) { if (metype != 0) {
@ -866,6 +903,9 @@ static void decodeExtendedSquitter(struct modesMessage *mm)
mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID; mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID;
mm->modeA = decodeID13Field(ID13Field); mm->modeA = decodeID13Field(ID13Field);
} }
if (check_imf && (msg[10] & 0x01))
mm->addr |= MODES_NON_ICAO_ADDRESS;
} }
break; break;
} }
@ -877,6 +917,8 @@ static void decodeExtendedSquitter(struct modesMessage *mm)
break; break;
case 31: // Aircraft Operational Status case 31: // Aircraft Operational Status
if (check_imf && (msg[10] & 0x01))
mm->addr |= MODES_NON_ICAO_ADDRESS;
break; break;
default: default: