Tidy up of UKUEHN's improvements

Resolves some merge conflicts that I couldn't find a way to fix during
the previous merge.

Remove a few Tabs that escaped in the edit/merge

Rename the fix_errors flag variable to nFix_crc since it now represents
the number of crc errors to attempt to fix.

Remove the aggressive variable since it's now part of nFix_crc

Only print phase correction statistics when phase correction is enabled.

Add an additional Modes.stat_ph_bit_fix[] to count the bits fixed during
phase correction
This commit is contained in:
Malcolm Robb 2013-05-24 21:51:44 +01:00
parent 9edba9332a
commit f64a65b5a2

View file

@ -236,7 +236,7 @@ struct {
/* Configuration */ /* Configuration */
char *filename; /* Input form file, --ifile option. */ char *filename; /* Input form file, --ifile option. */
int phase_enhance; /* Enable phase enhancement if true */ int phase_enhance; /* Enable phase enhancement if true */
int fix_errors; /* If > 0 no of bit errors to fix */ int nfix_crc; /* Number of crc bit error(s) to correct */
int check_crc; /* Only display messages with good CRC. */ int check_crc; /* Only display messages with good CRC. */
int raw; /* Raw output format. */ int raw; /* Raw output format. */
int beast; /* Beast binary format output. */ int beast; /* Beast binary format output. */
@ -258,7 +258,6 @@ struct {
int stats; /* Print stats at exit in --ifile mode. */ int stats; /* Print stats at exit in --ifile mode. */
int onlyaddr; /* Print only ICAO addresses. */ int onlyaddr; /* Print only ICAO addresses. */
int metric; /* Use metric units. */ int metric; /* Use metric units. */
int aggressive; /* Aggressive detection algorithm. */
int mlat; /* Use Beast ascii format for raw data output, i.e. @...; iso *...; */ int mlat; /* Use Beast ascii format for raw data output, i.e. @...; iso *...; */
int interactive_rtl1090; /* flight table in interactive mode is formatted like RTL1090 */ int interactive_rtl1090; /* flight table in interactive mode is formatted like RTL1090 */
@ -281,9 +280,8 @@ struct {
unsigned int stat_badcrc; unsigned int stat_badcrc;
unsigned int stat_fixed; unsigned int stat_fixed;
/* Histogram of fixed bit errors: index 0 for single bit erros, // Histogram of fixed bit errors: index 0 for single bit erros,
* index 1 for double bit errors etc. // index 1 for double bit errors etc.
*/
unsigned int stat_bit_fix[MODES_MAX_BITERRORS]; unsigned int stat_bit_fix[MODES_MAX_BITERRORS];
unsigned int stat_http_requests; unsigned int stat_http_requests;
@ -296,8 +294,10 @@ struct {
unsigned int stat_ph_goodcrc; unsigned int stat_ph_goodcrc;
unsigned int stat_ph_badcrc; unsigned int stat_ph_badcrc;
unsigned int stat_ph_fixed; unsigned int stat_ph_fixed;
unsigned int stat_ph_single_bit_fix; // Histogram of fixed bit errors: index 0 for single bit erros,
unsigned int stat_ph_two_bits_fix; // index 1 for double bit errors etc.
unsigned int stat_ph_bit_fix[MODES_MAX_BITERRORS];
unsigned int stat_DF_Len_Corrected; unsigned int stat_DF_Len_Corrected;
unsigned int stat_DF_Type_Corrected; unsigned int stat_DF_Type_Corrected;
unsigned int stat_ModeAC; unsigned int stat_ModeAC;
@ -312,7 +312,7 @@ struct modesMessage {
int crcok; // True if CRC was valid int crcok; // True if CRC was valid
uint32_t crc; // Message CRC uint32_t crc; // Message CRC
int correctedbits; // No. of bits corrected int correctedbits; // No. of bits corrected
int corrected[MODES_MAX_BITERRORS]; // corrected bit positions char corrected[MODES_MAX_BITERRORS]; // corrected bit positions
uint32_t addr; // ICAO Address from bytes 1 2 and 3 uint32_t addr; // ICAO Address from bytes 1 2 and 3
int phase_corrected; // True if phase correction was applied int phase_corrected; // True if phase correction was applied
uint64_t timestampMsg; // Timestamp of the message uint64_t timestampMsg; // Timestamp of the message
@ -491,7 +491,7 @@ void modesInit(void) {
} }
} }
/* Prepare error correction tables */ // Prepare error correction tables
modesInitErrorInfo(); modesInitErrorInfo();
} }
@ -684,7 +684,7 @@ void dumpMagnitudeVector(uint16_t *m, uint32_t offset) {
/* Produce a raw representation of the message as a Javascript file /* Produce a raw representation of the message as a Javascript file
* loadable by debug.html. */ * loadable by debug.html. */
void dumpRawMessageJS(char *descr, unsigned char *msg, void dumpRawMessageJS(char *descr, unsigned char *msg,
uint16_t *m, uint32_t offset, int fixable, int *bitpos) uint16_t *m, uint32_t offset, int fixable, char *bitpos)
{ {
int padding = 5; /* Show a few samples before the actual start. */ int padding = 5; /* Show a few samples before the actual start. */
int start = offset - padding; int start = offset - padding;
@ -729,14 +729,13 @@ void dumpRawMessage(char *descr, unsigned char *msg,
int j; int j;
int msgtype = msg[0] >> 3; int msgtype = msg[0] >> 3;
int fixable = 0; int fixable = 0;
int bitpos[MODES_MAX_BITERRORS]; char bitpos[MODES_MAX_BITERRORS];
for (j = 0; j < MODES_MAX_BITERRORS; j++) { for (j = 0; j < MODES_MAX_BITERRORS; j++) {
bitpos[j] = -1; bitpos[j] = -1;
} }
if (msgtype == 17) { if (msgtype == 17) {
fixable = fixBitErrors(msg, MODES_LONG_MSG_BITS, fixable = fixBitErrors(msg, MODES_LONG_MSG_BITS, MODES_MAX_BITERRORS, bitpos);
MODES_MAX_BITERRORS, bitpos);
} }
if (Modes.debug & MODES_DEBUG_JS) { if (Modes.debug & MODES_DEBUG_JS) {
@ -1205,7 +1204,7 @@ int fixSingleBitErrors(unsigned char *msg, int bits) {
// Similar to fixSingleBitErrors() but try every possible two bit combination. // Similar to fixSingleBitErrors() but try every possible two bit combination.
// This is very slow and should be tried only against DF17 messages that // This is very slow and should be tried only against DF17 messages that
// don't pass the checksum, and only in Aggressive Mode. // don't pass the checksum, and only in Aggressive Mode.
// /*
int fixTwoBitsErrors(unsigned char *msg, int bits) { int fixTwoBitsErrors(unsigned char *msg, int bits) {
int j, i; int j, i;
unsigned char aux[MODES_LONG_MSG_BYTES]; unsigned char aux[MODES_LONG_MSG_BYTES];
@ -1245,7 +1244,7 @@ int fixTwoBitsErrors(unsigned char *msg, int bits) {
} }
return (-1); return (-1);
} }
*/
/* Code for introducing a less CPU-intensive method of correcting /* Code for introducing a less CPU-intensive method of correcting
* single bit errors. * single bit errors.
* *
@ -1270,9 +1269,9 @@ int fixTwoBitsErrors(unsigned char *msg, int bits) {
* *
*/ */
struct errorinfo { struct errorinfo {
uint32_t syndrome; /* CRC syndrome */ uint32_t syndrome; // CRC syndrome
int bits; /* No of bit positions to fix */ int bits; // Number of bit positions to fix
int pos[MODES_MAX_BITERRORS]; /* bit positions */ int pos[MODES_MAX_BITERRORS]; // Bit positions corrected by this syndrome
}; };
#define NERRORINFO \ #define NERRORINFO \
@ -1313,18 +1312,14 @@ void modesInitErrorInfo() {
bitErrorTable[n].pos[1] = -1; bitErrorTable[n].pos[1] = -1;
n += 1; n += 1;
if (Modes.aggressive) { if (Modes.nfix_crc > 1) {
for (j = i+1; j < MODES_LONG_MSG_BITS; j++) { for (j = i+1; j < MODES_LONG_MSG_BITS; j++) {
int bytepos1 = (j >> 3); int bytepos1 = (j >> 3);
int mask1 = 1 << (7 - (j & 7)); int mask1 = 1 << (7 - (j & 7));
msg[bytepos1] ^= mask1; // create error1 msg[bytepos1] ^= mask1; // create error1
crc = modesChecksum(msg, MODES_LONG_MSG_BITS); crc = modesChecksum(msg, MODES_LONG_MSG_BITS);
if (n >= NERRORINFO) { if (n >= NERRORINFO) {
/* //fprintf(stderr, "Internal error, too many entries, fix NERRORINFO\n");
fprintf(stderr,
"Internal error, too many "
"entries, fix NERRORINFO\n");
*/
break; break;
} }
bitErrorTable[n].syndrome = crc; // two bit error case bitErrorTable[n].syndrome = crc; // two bit error case
@ -1337,23 +1332,19 @@ void modesInitErrorInfo() {
} }
msg[bytepos0] ^= mask0; // revert error0 msg[bytepos0] ^= mask0; // revert error0
} }
qsort(bitErrorTable, NERRORINFO, qsort(bitErrorTable, NERRORINFO, sizeof(struct errorinfo), cmpErrorInfo);
sizeof(struct errorinfo), cmpErrorInfo);
/* Test code: report if any syndrome appears at least twice. In this // Test code: report if any syndrome appears at least twice. In this
* case the correction cannot be done without ambiguity. // case the correction cannot be done without ambiguity.
* Tried it, does not happen for 1- and 2-bit errors. // Tried it, does not happen for 1- and 2-bit errors.
*/
/* /*
for (i = 1; i < NERRORINFO; i++) { for (i = 1; i < NERRORINFO; i++) {
if (bitErrorTable[i-1].syndrome if (bitErrorTable[i-1].syndrome == bitErrorTable[i].syndrome) {
== bitErrorTable[i].syndrome) { fprintf(stderr, "modesInitErrorInfo: Collision for syndrome %06x\n",
fprintf(stderr, "modesInitErrorInfo: "
"Collision for syndrome %06x\n",
(int)bitErrorTable[i].syndrome); (int)bitErrorTable[i].syndrome);
} }
} }
*/
/*
for (i = 0; i < NERRORINFO; i++) { for (i = 0; i < NERRORINFO; i++) {
printf("syndrome %06x bit0 %3d bit1 %3d\n", printf("syndrome %06x bit0 %3d bit1 %3d\n",
bitErrorTable[i].syndrome, bitErrorTable[i].syndrome,
@ -1362,33 +1353,14 @@ void modesInitErrorInfo() {
*/ */
} }
// //
// Flip a bit, but make sure that the DF field (first 5 bits) // Search for syndrome in table and if an entry is found, flip the necessary
// is never changed // bits. Make sure the indices fit into the array
/*
int flipBit(unsigned char *msg, int nbits, int bit) {
int bytepos, mask;
if ((bit < 0) || (bit >= nbits)) {
return 0;
}
if (bit < 5) {
return 0;
}
bytepos = (bit >> 3);
mask = 1 << (7 - (bit & 7));
msg[bytepos] ^= mask;
return 1;
}
*/
// Search syndrome in table and, if an entry is found, flip the necessary
// bits. Make sure the indices fit into the array, and for 2-bit errors,
// are different.
// Additional parameter: fix only less than maxcorrected bits, and record // Additional parameter: fix only less than maxcorrected bits, and record
// fixed bit positions in corrected[]. This array can be NULL, otherwise // fixed bit positions in corrected[]. This array can be NULL, otherwise
// must be of length at least maxcorrected. // must be of length at least maxcorrected.
// Return number of fixed bits. // Return number of fixed bits.
// //
int fixBitErrors(unsigned char *msg, int bits, int fixBitErrors(unsigned char *msg, int bits, int maxfix, char *fixedbits) {
int maxfixable, int *fixedbitpos) {
struct errorinfo *pei; struct errorinfo *pei;
struct errorinfo ei; struct errorinfo ei;
int bitpos, offset, res, i; int bitpos, offset, res, i;
@ -1399,26 +1371,28 @@ int fixBitErrors(unsigned char *msg, int bits,
if (pei == NULL) { if (pei == NULL) {
return 0; // No syndrome found return 0; // No syndrome found
} }
if (maxfixable < pei->bits) {
// Check if the syndrome fixes more bits than we allow
if (maxfix < pei->bits) {
return 0; return 0;
} }
res = 0;
// Check that all bit positions lie inside the message length
offset = MODES_LONG_MSG_BITS-bits; offset = MODES_LONG_MSG_BITS-bits;
/* Check that all bit positions are inside message boundaries */
for (i = 0; i < pei->bits; i++) { for (i = 0; i < pei->bits; i++) {
bitpos = pei->pos[i] - offset; bitpos = pei->pos[i] - offset;
if ((bitpos < 0) || (bitpos >= bits)) { if ((bitpos < 0) || (bitpos >= bits)) {
return 0; return 0;
} }
} }
/* Fix the bits */
for (i = 0; i < pei->bits; i++) { // Fix the bits
for (i = res = 0; i < pei->bits; i++) {
bitpos = pei->pos[i] - offset; bitpos = pei->pos[i] - offset;
msg[(bitpos >> 3)] ^= (1 << (7 - (bitpos & 7))); msg[bitpos >> 3] ^= (1 << (7 - (bitpos & 7)));
if (fixedbitpos != NULL) { if (fixedbits) {
fixedbitpos[res] = bitpos; fixedbits[res++] = bitpos;
} }
res++;
} }
return res; return res;
} }
@ -1520,8 +1494,7 @@ void testAndTimeBitCorrection() {
inittmsg1(); inittmsg1();
gettimeofday(&starttv, NULL); gettimeofday(&starttv, NULL);
for (i = 0; i < MODES_LONG_MSG_BITS; i++) { for (i = 0; i < MODES_LONG_MSG_BITS; i++) {
fixBitErrors(&tmsg1[i][0], MODES_LONG_MSG_BITS, fixBitErrors(&tmsg1[i][0], MODES_LONG_MSG_BITS, MODES_MAX_BITERRORS, NULL);
MODES_MAX_BITERRORS, NULL);
} }
gettimeofday(&endtv, NULL); gettimeofday(&endtv, NULL);
printf(" New code: 1-bit errors on %d msgs: %ld usecs\n", printf(" New code: 1-bit errors on %d msgs: %ld usecs\n",
@ -1540,8 +1513,7 @@ void testAndTimeBitCorrection() {
inittmsg2(); inittmsg2();
gettimeofday(&starttv, NULL); gettimeofday(&starttv, NULL);
for (i = 0; i < NTWOBITS; i++) { for (i = 0; i < NTWOBITS; i++) {
fixBitErrors(&tmsg2[i][0], MODES_LONG_MSG_BITS, fixBitErrors(&tmsg2[i][0], MODES_LONG_MSG_BITS, MODES_MAX_BITERRORS, NULL);
MODES_MAX_BITERRORS, NULL);
} }
gettimeofday(&endtv, NULL); gettimeofday(&endtv, NULL);
printf(" New code: 2-bit errors on %d msgs: %ld usecs\n", printf(" New code: 2-bit errors on %d msgs: %ld usecs\n",
@ -1763,8 +1735,8 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
mm->msgbits = modesMessageLenByType(mm->msgtype); mm->msgbits = modesMessageLenByType(mm->msgtype);
mm->crc = modesChecksum(msg, mm->msgbits); mm->crc = modesChecksum(msg, mm->msgbits);
if ((mm->crc) && (Modes.fix_errors) && ((mm->msgtype == 17) || (mm->msgtype == 18))) { if ((mm->crc) && (Modes.nfix_crc) && ((mm->msgtype == 17) || (mm->msgtype == 18))) {
// if ((mm->crc) && (Modes.fix_errors) && ((mm->msgtype == 11) || (mm->msgtype == 17))) { // if ((mm->crc) && (Modes.nfix_crc) && ((mm->msgtype == 11) || (mm->msgtype == 17))) {
// //
// Fixing single bit errors in DF-11 is a bit dodgy because we have no way to // Fixing single bit errors in DF-11 is a bit dodgy because we have no way to
// know for sure if the crc is supposed to be 0 or not - it could be any value // know for sure if the crc is supposed to be 0 or not - it could be any value
@ -1775,8 +1747,8 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
// using the results. Perhaps check the ICAO against known aircraft, and check // using the results. Perhaps check the ICAO against known aircraft, and check
// IID against known good IID's. That's a TODO. // IID against known good IID's. That's a TODO.
// //
mm->correctedbits = fixBitErrors(msg, mm->msgbits, mm->correctedbits = fixBitErrors(msg, mm->msgbits, Modes.nfix_crc, mm->corrected);
Modes.fix_errors, mm->corrected);
// If we correct, validate ICAO addr to help filter birthday paradox solutions. // If we correct, validate ICAO addr to help filter birthday paradox solutions.
if (mm->correctedbits) { if (mm->correctedbits) {
uint32_t addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); uint32_t addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
@ -2624,17 +2596,16 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
} else if (use_correction) { } else if (use_correction) {
Modes.stat_ph_badcrc++; Modes.stat_ph_badcrc++;
Modes.stat_ph_fixed++; Modes.stat_ph_fixed++;
if (mm.correctedbits == 1) { if ( (mm.correctedbits)
Modes.stat_ph_single_bit_fix++; && (mm.correctedbits <= MODES_MAX_BITERRORS) ) {
} else if (mm.correctedbits == 2) { Modes.stat_ph_bit_fix[mm.correctedbits-1] += 1;
Modes.stat_ph_two_bits_fix++;
} }
} else { } else {
Modes.stat_badcrc++; Modes.stat_badcrc++;
Modes.stat_fixed += 1; Modes.stat_fixed++;
if ((mm.correctedbits > 0) && if ( (mm.correctedbits)
(mm.correctedbits <= MODES_MAX_BITERRORS)) { && (mm.correctedbits <= MODES_MAX_BITERRORS) ) {
Modes.stat_bit_fix[mm.correctedbits-1] += 1; Modes.stat_bit_fix[mm.correctedbits-1] += 1;
} }
} }
@ -3888,8 +3859,7 @@ int handleHTTPRequest(struct client *c) {
} }
if (strlen(url) < 2) { if (strlen(url) < 2) {
snprintf(getFile, sizeof getFile, "%s/%s", snprintf(getFile, sizeof getFile, "%s/gmap.html", HTMLPATH); // Default file
HTMLPATH, "gmap.html"); // Default file
} else { } else {
snprintf(getFile, sizeof getFile, "%s/%s", HTMLPATH, url); snprintf(getFile, sizeof getFile, "%s/%s", HTMLPATH, url);
} }
@ -4149,10 +4119,9 @@ int main(int argc, char **argv) {
} else if (!strcmp(argv[j],"--ifile") && more) { } else if (!strcmp(argv[j],"--ifile") && more) {
Modes.filename = strdup(argv[++j]); Modes.filename = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--fix")) { } else if (!strcmp(argv[j],"--fix")) {
Modes.fix_errors = 1; Modes.nfix_crc = 1;
} else if (!strcmp(argv[j],"--no-fix")) { } else if (!strcmp(argv[j],"--no-fix")) {
Modes.fix_errors = 0; Modes.nfix_crc = 0;
Modes.aggressive = 0;
} else if (!strcmp(argv[j],"--no-crc-check")) { } else if (!strcmp(argv[j],"--no-crc-check")) {
Modes.check_crc = 0; Modes.check_crc = 0;
} else if (!strcmp(argv[j],"--phase-enhance")) { } else if (!strcmp(argv[j],"--phase-enhance")) {
@ -4185,8 +4154,7 @@ int main(int argc, char **argv) {
} else if (!strcmp(argv[j],"--metric")) { } else if (!strcmp(argv[j],"--metric")) {
Modes.metric = 1; Modes.metric = 1;
} else if (!strcmp(argv[j],"--aggressive")) { } else if (!strcmp(argv[j],"--aggressive")) {
Modes.aggressive = 1; Modes.nfix_crc = MODES_MAX_BITERRORS;
Modes.fix_errors = MODES_MAX_BITERRORS;
} else if (!strcmp(argv[j],"--interactive")) { } else if (!strcmp(argv[j],"--interactive")) {
Modes.interactive = 1; Modes.interactive = 1;
} else if (!strcmp(argv[j],"--interactive-rows") && more) { } else if (!strcmp(argv[j],"--interactive-rows") && more) {
@ -4314,6 +4282,7 @@ int main(int argc, char **argv) {
for (j = 0; j < MODES_MAX_BITERRORS; j++) { for (j = 0; j < MODES_MAX_BITERRORS; j++) {
printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors"); printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors");
} }
if (Modes.phase_enhance) {
printf("%d phase enhancement attempts\n", Modes.stat_out_of_phase); printf("%d phase enhancement attempts\n", Modes.stat_out_of_phase);
printf("%d phase enhanced demodulated with 0 errors\n", Modes.stat_ph_demodulated0); printf("%d phase enhanced demodulated with 0 errors\n", Modes.stat_ph_demodulated0);
printf("%d phase enhanced demodulated with 1 error\n", Modes.stat_ph_demodulated1); printf("%d phase enhanced demodulated with 1 error\n", Modes.stat_ph_demodulated1);
@ -4322,8 +4291,10 @@ int main(int argc, char **argv) {
printf("%d phase enhanced with good crc\n", Modes.stat_ph_goodcrc); printf("%d phase enhanced with good crc\n", Modes.stat_ph_goodcrc);
printf("%d phase enhanced with bad crc\n", Modes.stat_ph_badcrc); printf("%d phase enhanced with bad crc\n", Modes.stat_ph_badcrc);
printf("%d phase enhanced errors corrected\n", Modes.stat_ph_fixed); printf("%d phase enhanced errors corrected\n", Modes.stat_ph_fixed);
printf("%d phase enhanced single bit errors\n", Modes.stat_ph_single_bit_fix); for (j = 0; j < MODES_MAX_BITERRORS; j++) {
printf("%d phase enhanced two bits errors\n", Modes.stat_ph_two_bits_fix); printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors");
}
}
printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed); printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed);
} }