Add some testing code that looks for ambiguous syndromes that
could confuse the partial correction used in DF11. That code shows that yes, there are ambiguous syndromes in the 2-bit correction case only, so disable corrections of more than 1 bit in DF11.
This commit is contained in:
parent
5ac90e30a8
commit
26feb1d078
124
crc.c
124
crc.c
|
@ -421,7 +421,9 @@ void modesChecksumFix(uint8_t *msg, struct errorinfo *info)
|
||||||
#ifdef CRCDEBUG
|
#ifdef CRCDEBUG
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int len;
|
int shortlen, longlen;
|
||||||
|
int i;
|
||||||
|
struct errorinfo *shorttable, *longtable;
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "syntax: crctests <ncorrect> <ndetect>\n");
|
fprintf(stderr, "syntax: crctests <ncorrect> <ndetect>\n");
|
||||||
|
@ -429,8 +431,124 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
initLookupTables();
|
initLookupTables();
|
||||||
prepareErrorTable(MODES_SHORT_MSG_BITS, atoi(argv[1]), atoi(argv[2]), &len);
|
shorttable = prepareErrorTable(MODES_SHORT_MSG_BITS, atoi(argv[1]), atoi(argv[2]), &shortlen);
|
||||||
prepareErrorTable(MODES_LONG_MSG_BITS, atoi(argv[1]), atoi(argv[2]), &len);
|
longtable = prepareErrorTable(MODES_LONG_MSG_BITS, atoi(argv[1]), atoi(argv[2]), &longlen);
|
||||||
|
|
||||||
|
// check for DF11 correction syndromes where there is a syndrome with lower 7 bits all zero
|
||||||
|
// (which would be used for DF11 error correction), but there's also a syndrome which has
|
||||||
|
// the same upper 17 bits but nonzero lower 7 bits.
|
||||||
|
|
||||||
|
// empirically, with ncorrect=1 ndetect=2 we get no ambiguous syndromes;
|
||||||
|
// for ncorrect=2 ndetect=4 we get 11 ambiguous syndromes:
|
||||||
|
|
||||||
|
/*
|
||||||
|
syndrome 1 = 000C00 bits=[ 44 45 ]
|
||||||
|
syndrome 2 = 000C1B bits=[ 30 43 ]
|
||||||
|
|
||||||
|
syndrome 1 = 001400 bits=[ 43 45 ]
|
||||||
|
syndrome 2 = 00141B bits=[ 30 44 ]
|
||||||
|
|
||||||
|
syndrome 1 = 001800 bits=[ 43 44 ]
|
||||||
|
syndrome 2 = 00181B bits=[ 30 45 ]
|
||||||
|
|
||||||
|
syndrome 1 = 001800 bits=[ 43 44 ]
|
||||||
|
syndrome 2 = 001836 bits=[ 29 42 ]
|
||||||
|
|
||||||
|
syndrome 1 = 002400 bits=[ 42 45 ]
|
||||||
|
syndrome 2 = 00242D bits=[ 29 30 ]
|
||||||
|
|
||||||
|
syndrome 1 = 002800 bits=[ 42 44 ]
|
||||||
|
syndrome 2 = 002836 bits=[ 29 43 ]
|
||||||
|
|
||||||
|
syndrome 1 = 003000 bits=[ 42 43 ]
|
||||||
|
syndrome 2 = 003036 bits=[ 29 44 ]
|
||||||
|
|
||||||
|
syndrome 1 = 003000 bits=[ 42 43 ]
|
||||||
|
syndrome 2 = 00306C bits=[ 28 41 ]
|
||||||
|
|
||||||
|
syndrome 1 = 004800 bits=[ 41 44 ]
|
||||||
|
syndrome 2 = 00485A bits=[ 28 29 ]
|
||||||
|
|
||||||
|
syndrome 1 = 005000 bits=[ 41 43 ]
|
||||||
|
syndrome 2 = 00506C bits=[ 28 42 ]
|
||||||
|
|
||||||
|
syndrome 1 = 006000 bits=[ 41 42 ]
|
||||||
|
syndrome 2 = 00606C bits=[ 28 43 ]
|
||||||
|
*/
|
||||||
|
|
||||||
|
// So in the DF11 correction logic, we just discard messages that require more than a 1 bit fix.
|
||||||
|
|
||||||
|
fprintf(stderr, "checking %d syndromes for DF11 collisions..\n", shortlen);
|
||||||
|
for (i = 0; i < shortlen; ++i) {
|
||||||
|
if ((shorttable[i].syndrome & 0xFF) == 0) {
|
||||||
|
int j;
|
||||||
|
// all syndromes with the same first 17 bits should sort immediately after entry i,
|
||||||
|
// so this is fairly easy
|
||||||
|
for (j = i+1; j < shortlen; ++j) {
|
||||||
|
if ((shorttable[i].syndrome & 0xFFFF80) == (shorttable[j].syndrome & 0xFFFF80)) {
|
||||||
|
int k;
|
||||||
|
int mismatch = 0;
|
||||||
|
|
||||||
|
// we don't care if the only differences are in bits that lie in the checksum
|
||||||
|
for (k = 0; k < shorttable[i].errors; ++k) {
|
||||||
|
int l, matched = 0;
|
||||||
|
|
||||||
|
if (shorttable[i].bit[k] >= 49)
|
||||||
|
continue; // bit is in the final 7 bits, we don't care
|
||||||
|
|
||||||
|
for (l = 0; l < shorttable[j].errors; ++l) {
|
||||||
|
if (shorttable[i].bit[k] == shorttable[j].bit[l]) {
|
||||||
|
matched = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matched)
|
||||||
|
mismatch = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = 0; k < shorttable[j].errors; ++k) {
|
||||||
|
int l, matched = 0;
|
||||||
|
|
||||||
|
if (shorttable[j].bit[k] >= 49)
|
||||||
|
continue; // bit is in the final 7 bits, we don't care
|
||||||
|
|
||||||
|
for (l = 0; l < shorttable[i].errors; ++l) {
|
||||||
|
if (shorttable[j].bit[k] == shorttable[i].bit[l]) {
|
||||||
|
matched = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matched)
|
||||||
|
mismatch = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mismatch) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"DF11 correction collision: \n"
|
||||||
|
" syndrome 1 = %06X bits=[",
|
||||||
|
shorttable[i].syndrome);
|
||||||
|
for (k = 0; k < shorttable[i].errors; ++k)
|
||||||
|
fprintf(stderr, " %d", shorttable[i].bit[k]);
|
||||||
|
fprintf(stderr, " ]\n");
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
" syndrome 2 = %06X bits=[",
|
||||||
|
shorttable[j].syndrome);
|
||||||
|
for (k = 0; k < shorttable[j].errors; ++k)
|
||||||
|
fprintf(stderr, " %d", shorttable[j].bit[k]);
|
||||||
|
fprintf(stderr, " ]\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(shorttable);
|
||||||
|
free(longtable);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
9
mode_s.c
9
mode_s.c
|
@ -301,13 +301,10 @@ static int correct_aa_field(uint32_t *addr, struct errorinfo *ei)
|
||||||
// 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
|
// 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
|
// 750: DF11 with IID==0, good CRC and an address not matching a known aircraft
|
||||||
// 400: DF11 with IID==0, 2-bit error and an address matching a known aircraft
|
|
||||||
// 375: DF11 with IID==0, 1-bit error and an address not matching a known aircraft
|
// 375: DF11 with IID==0, 1-bit error and an address not matching a known aircraft
|
||||||
// 187: DF11 with IID==0, 2-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
|
// 500: DF11 with IID!=0, 1-bit error and an address matching a known aircraft
|
||||||
// 250: DF11 with IID!=0, 2-bit error and an address 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)
|
||||||
|
@ -349,6 +346,12 @@ int scoreModesMessage(unsigned char *msg, int validbits)
|
||||||
if (!ei)
|
if (!ei)
|
||||||
return -2; // can't correct errors
|
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
|
// fix any errors in the address field
|
||||||
correct_aa_field(&addr, ei);
|
correct_aa_field(&addr, ei);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue