diff --git a/mode_s.c b/mode_s.c index 3e7d058..14e895e 100644 --- a/mode_s.c +++ b/mode_s.c @@ -259,12 +259,9 @@ static int correct_aa_field(uint32_t *addr, struct errorinfo *ei) // 350: DF17/18 with 2-bit error and an address not matching a known aircraft // 1600: DF11 with IID==0, good CRC and an address matching a known aircraft -// 800: DF11 with IID==0, 1-bit error and an address matching a known aircraft -// 750: DF11 with IID==0, good CRC and an address not matching a known aircraft -// 375: DF11 with IID==0, 1-bit error and an address not matching a known aircraft - // 1000: DF11 with IID!=0, good CRC and an address matching a known aircraft -// 500: DF11 with IID!=0, 1-bit error and an address matching a known aircraft +// 800: DF11 with 1-bit error and an address matching a known aircraft +// 750: DF11 with IID==0, good CRC and an address not matching a known aircraft // 1000: DF20/21 with a CRC-derived address matching a known aircraft // 500: DF20/21 with a CRC-derived address matching a known aircraft (bottom 16 bits only - overlay control in use) @@ -310,31 +307,40 @@ int scoreModesMessage(unsigned char *msg, int validbits) case 11: // All-call reply iid = crc & 0x7f; - crc = crc & 0xffff80; addr = getbits(msg, 9, 32); - ei = modesChecksumDiagnose(crc, msgbits); - if (!ei) - return -2; // can't correct errors + if (crc & 0xffff80) { + // Try to diagnose based on the _full_ CRC + // i.e. under the assumption that IID = 0 + ei = modesChecksumDiagnose(crc, msgbits); + if (!ei) + return -2; // can't correct errors - // see crc.c comments: we do not attempt to fix - // more than single-bit errors, as two-bit - // errors are ambiguous in DF11. - if (ei->errors > 1) - return -2; // can't correct errors + // see crc.c comments: we do not attempt to fix + // more than single-bit errors, as two-bit + // errors are ambiguous in DF11. + if (ei->errors > 1) + return -2; // can't correct errors - // fix any errors in the address field - correct_aa_field(&addr, ei); + // fix any errors in the address field + correct_aa_field(&addr, ei); - // validate address + // here, IID = 0 implicitly + if (icaoFilterTest(addr)) + return 800; + else + return -1; + } + + // CRC was correct (ish) if (iid == 0) { if (icaoFilterTest(addr)) - return 1600 / (ei->errors + 1); + return 1600; else - return 750 / (ei->errors + 1); - } else { + return 750; + } else { // iid != 0 if (icaoFilterTest(addr)) - return 1000 / (ei->errors + 1); + return 1000; else return -1; } @@ -439,8 +445,11 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg) mm->IID = mm->crc & 0x7f; if (mm->crc & 0xffff80) { + // Try to diagnose based on the _full_ CRC + // i.e. under the assumption that IID = 0 + int addr; - struct errorinfo *ei = modesChecksumDiagnose(mm->crc & 0xffff80, mm->msgbits); + struct errorinfo *ei = modesChecksumDiagnose(mm->crc, mm->msgbits); if (!ei) { return -2; // couldn't fix it } @@ -452,6 +461,7 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg) return -2; // can't correct errors mm->correctedbits = ei->errors; + mm->IID = 0; modesChecksumFix(msg, ei); // check whether the corrected message looks sensible