When trying to correct a DF11 that had bits set in the top 17 bits of the
residual, use the full 24-bit syndrome. Previously this would mask off the low 7 bits, which isn't particularly great - it doesn't really make sense in that it implies a somewhat random IID value, and it would actually only correct 20 possible bit errors out of the 51 possible errors, 16 of which were errors in the top 16 bits of the CRC itself. It is also risky as it will accept a larger number of possible garbage messages as the lower 7 bits may take any value. Instead, use the full syndrome, assuming that the damaged message had IID=0 - which seems more likely than assuming a random IID, since IID=0 is used for acquisition squitters and should be arriving regularly. The reduced rate of corrections for DF11 messages shouldn't have much of an impact as DF11s carry very little data themselves - they are mainly used to acquire the aircraft address. Once one good message for an aircraft turns up (which would require IID=0 anyway before we'd accept it) it doesn't really matter if we discard more damaged messages, as they're not contributing to anything useful in the aircraft state beyond air/ground status, which is also carried in many other messages.
This commit is contained in:
parent
ae29613d85
commit
f7123c41e5
54
mode_s.c
54
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
|
// 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
|
// 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
|
// 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
|
// 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)
|
// 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
|
case 11: // All-call reply
|
||||||
iid = crc & 0x7f;
|
iid = crc & 0x7f;
|
||||||
crc = crc & 0xffff80;
|
|
||||||
addr = getbits(msg, 9, 32);
|
addr = getbits(msg, 9, 32);
|
||||||
|
|
||||||
ei = modesChecksumDiagnose(crc, msgbits);
|
if (crc & 0xffff80) {
|
||||||
if (!ei)
|
// Try to diagnose based on the _full_ CRC
|
||||||
return -2; // can't correct errors
|
// 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
|
// see crc.c comments: we do not attempt to fix
|
||||||
// more than single-bit errors, as two-bit
|
// more than single-bit errors, as two-bit
|
||||||
// errors are ambiguous in DF11.
|
// errors are ambiguous in DF11.
|
||||||
if (ei->errors > 1)
|
if (ei->errors > 1)
|
||||||
return -2; // can't correct errors
|
return -2; // can't correct errors
|
||||||
|
|
||||||
// fix any errors in the address field
|
// fix any errors in the address field
|
||||||
correct_aa_field(&addr, ei);
|
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 (iid == 0) {
|
||||||
if (icaoFilterTest(addr))
|
if (icaoFilterTest(addr))
|
||||||
return 1600 / (ei->errors + 1);
|
return 1600;
|
||||||
else
|
else
|
||||||
return 750 / (ei->errors + 1);
|
return 750;
|
||||||
} else {
|
} else { // iid != 0
|
||||||
if (icaoFilterTest(addr))
|
if (icaoFilterTest(addr))
|
||||||
return 1000 / (ei->errors + 1);
|
return 1000;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -439,8 +445,11 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
|
||||||
|
|
||||||
mm->IID = mm->crc & 0x7f;
|
mm->IID = mm->crc & 0x7f;
|
||||||
if (mm->crc & 0xffff80) {
|
if (mm->crc & 0xffff80) {
|
||||||
|
// Try to diagnose based on the _full_ CRC
|
||||||
|
// i.e. under the assumption that IID = 0
|
||||||
|
|
||||||
int addr;
|
int addr;
|
||||||
struct errorinfo *ei = modesChecksumDiagnose(mm->crc & 0xffff80, mm->msgbits);
|
struct errorinfo *ei = modesChecksumDiagnose(mm->crc, mm->msgbits);
|
||||||
if (!ei) {
|
if (!ei) {
|
||||||
return -2; // couldn't fix it
|
return -2; // couldn't fix it
|
||||||
}
|
}
|
||||||
|
|
@ -452,6 +461,7 @@ int decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
|
||||||
return -2; // can't correct errors
|
return -2; // can't correct errors
|
||||||
|
|
||||||
mm->correctedbits = ei->errors;
|
mm->correctedbits = ei->errors;
|
||||||
|
mm->IID = 0;
|
||||||
modesChecksumFix(msg, ei);
|
modesChecksumFix(msg, ei);
|
||||||
|
|
||||||
// check whether the corrected message looks sensible
|
// check whether the corrected message looks sensible
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue