[hamradio-commits] [dump1090] 215/389: UKUEHN : Various Improvements
Matthew Ernisse
mernisse-guest at moszumanska.debian.org
Wed Nov 5 00:19:56 UTC 2014
This is an automated email from the git hooks/post-receive script.
mernisse-guest pushed a commit to branch master
in repository dump1090.
commit 9edba9332aa475d364fe7363815cd57e7e677e6b
Author: Malcolm Robb <Support at ATTAvionics.com>
Date: Fri May 24 21:24:16 2013 +0100
UKUEHN : Various Improvements
Sorry Ulrich - I can't get Github to resolve the merge errors and
preserve your commit notes, so I'll add them here.
Improvements on bit error correction, doc update, preparation for
program installation/package build
Hi,
I committed some further improvements on the bit error correction code,
updated the readme, and implemented a way to install the program in the
linux file system hierarchy (allows for package building).
Regards,
Ulrich
---
Makefile | 16 +++++++-
README.md | 25 ++++++++-----
dump1090.c | 124 ++++++++++++++++++++++++++++++++++++++-----------------------
3 files changed, 107 insertions(+), 58 deletions(-)
diff --git a/Makefile b/Makefile
index c6084a0..8382ff0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,24 @@
+#
+# When building a package or installing otherwise in the system, make
+# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
+#
+PROGNAME=dump1090
+
+ifdef PREFIX
+BINDIR=$(PREFIX)/bin
+SHAREDIR=$(PREFIX)/share/$(PROGNAME)
+EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\"
+endif
+
CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
LIBS=`pkg-config --libs librtlsdr` -lpthread -lm
CC=gcc
-PROGNAME=dump1090
+
all: dump1090
%.o: %.c
- $(CC) $(CFLAGS) -c $<
+ $(CC) $(CFLAGS) $(EXTRACFLAGS) -c $<
dump1090: dump1090.o anet.o
$(CC) -g -o dump1090 dump1090.o anet.o $(LIBS)
diff --git a/README.md b/README.md
index 8a9f752..3fdd396 100644
--- a/README.md
+++ b/README.md
@@ -86,9 +86,13 @@ it without arguments at all is the best thing to do.
Reliability
---
-By default Dump1090 tries to fix single bit errors using the checksum.
-Basically the program will try to flip every bit of the message and check if
-the checksum of the resulting message matches.
+By default Dump1090 checks for decoding errors using the 24-bit CRC checksum,
+where available. Messages with errors are discarded.
+
+The --fix command line switch enables fixing single bit error correction
+based on the CRC checksum. Technically, it uses a table of precomputed
+checksum differences resulting from single bit errors to look up the
+wrong bit position.
This is indeed able to fix errors and works reliably in my experience,
however if you are interested in very reliable data I suggest to use
@@ -190,18 +194,19 @@ Aggressive mode
With --aggressive it is possible to activate the *aggressive mode* that is a
modified version of the Mode S packet detection and decoding.
-THe aggresive mode uses more CPU usually (especially if there are many planes
+The aggresive mode uses more CPU usually (especially if there are many planes
sending DF17 packets), but can detect a few more messages.
The algorithm in aggressive mode is modified in the following ways:
-* Up to two demodulation errors are tolerated (adjacent entires in the magnitude
- vector with the same eight). Normally only messages without errors are
- checked.
-* It tries to fix DF17 messages trying every two bits combination.
+* Up to two demodulation errors are tolerated (adjacent entires in the
+ magnitude vector with the same eight). Normally only messages without
+ errors are checked.
+* It tries to fix DF17 messages with CRC errors resulting from any two bit
+ errors.
-The use of aggressive mdoe is only advised in places where there is low traffic
-in order to have a chance to capture some more messages.
+The use of aggressive mdoe is only advised in places where there is
+low traffic in order to have a chance to capture some more messages.
Debug mode
---
diff --git a/dump1090.c b/dump1090.c
index e7eb5b3..089fab3 100644
--- a/dump1090.c
+++ b/dump1090.c
@@ -72,6 +72,9 @@
#define MODES_MSG_SQUELCH_LEVEL 0x02FF /* Average signal strength limit */
#define MODES_MSG_ENCODER_ERRS 3 /* Maximum number of encoding errors */
+/* When changing, change also fixBitErrors() and modesInitErrorTable() !! */
+#define MODES_MAX_BITERRORS 2 /* Global max for fixable bit erros */
+
#define MODEAC_MSG_SAMPLES (25 * 2) /* include up to the SPI bit */
#define MODEAC_MSG_BYTES 2
#define MODEAC_MSG_SQUELCH_LEVEL 0x07FF /* Average signal strength limit */
@@ -150,6 +153,10 @@
#define MODES_CLIENT_BUF_SIZE 1024
#define MODES_NET_SNDBUF_SIZE (1024*64)
+#ifndef HTMLPATH
+#define HTMLPATH "./public_html" /* default path for gmap.html etc. */
+#endif
+
#define MODES_NOTUSED(V) ((void) V)
/* Structure used to describe a networking client. */
@@ -229,7 +236,7 @@ struct {
/* Configuration */
char *filename; /* Input form file, --ifile option. */
int phase_enhance; /* Enable phase enhancement if true */
- int fix_errors; /* Single bit error correction if true. */
+ int fix_errors; /* If > 0 no of bit errors to fix */
int check_crc; /* Only display messages with good CRC. */
int raw; /* Raw output format. */
int beast; /* Beast binary format output. */
@@ -273,8 +280,12 @@ struct {
unsigned int stat_goodcrc;
unsigned int stat_badcrc;
unsigned int stat_fixed;
- unsigned int stat_single_bit_fix;
- unsigned int stat_two_bits_fix;
+
+ /* Histogram of fixed bit errors: index 0 for single bit erros,
+ * index 1 for double bit errors etc.
+ */
+ unsigned int stat_bit_fix[MODES_MAX_BITERRORS];
+
unsigned int stat_http_requests;
unsigned int stat_sbs_connections;
unsigned int stat_out_of_phase;
@@ -300,7 +311,8 @@ struct modesMessage {
int msgtype; // Downlink format #
int crcok; // True if CRC was valid
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
uint32_t addr; // ICAO Address from bytes 1 2 and 3
int phase_corrected; // True if phase correction was applied
uint64_t timestampMsg; // Timestamp of the message
@@ -341,7 +353,7 @@ void modesSendRawOutput(struct modesMessage *mm);
void modesSendBeastOutput(struct modesMessage *mm);
void modesSendSBSOutput(struct modesMessage *mm);
void useModesMessage(struct modesMessage *mm);
-int fixBitErrors(unsigned char *msg, int bits);
+int fixBitErrors(unsigned char *msg, int bits, int maxfixable, int *bitpos);
int fixSingleBitErrors(unsigned char *msg, int bits);
int fixTwoBitsErrors(unsigned char *msg, int bits);
void modesInitErrorInfo();
@@ -672,7 +684,7 @@ void dumpMagnitudeVector(uint16_t *m, uint32_t offset) {
/* Produce a raw representation of the message as a Javascript file
* loadable by debug.html. */
void dumpRawMessageJS(char *descr, unsigned char *msg,
- uint16_t *m, uint32_t offset, int fixable)
+ uint16_t *m, uint32_t offset, int fixable, int *bitpos)
{
int padding = 5; /* Show a few samples before the actual start. */
int start = offset - padding;
@@ -680,6 +692,7 @@ void dumpRawMessageJS(char *descr, unsigned char *msg,
FILE *fp;
int j;
+ MODES_NOTUSED(fixable);
if ((fp = fopen("frames.js","a")) == NULL) {
fprintf(stderr, "Error opening frames.js: %s\n", strerror(errno));
exit(1);
@@ -690,8 +703,8 @@ void dumpRawMessageJS(char *descr, unsigned char *msg,
fprintf(fp,"%d", j < 0 ? 0 : m[j]);
if (j != end) fprintf(fp,",");
}
- fprintf(fp,"], \"fixed\": %d, \"bits\": %d, \"hex\": \"",
- fixable, modesMessageLenByType(msg[0]>>3));
+ fprintf(fp,"], \"fix1\": %d, \"fix2\": %d, \"bits\": %d, \"hex\": \"",
+ bitpos[0], bitpos[1] , modesMessageLenByType(msg[0]>>3));
for (j = 0; j < MODES_LONG_MSG_BYTES; j++)
fprintf(fp,"\\x%02x",msg[j]);
fprintf(fp,"\"});\n");
@@ -716,13 +729,18 @@ void dumpRawMessage(char *descr, unsigned char *msg,
int j;
int msgtype = msg[0] >> 3;
int fixable = 0;
+ int bitpos[MODES_MAX_BITERRORS];
+ for (j = 0; j < MODES_MAX_BITERRORS; j++) {
+ bitpos[j] = -1;
+ }
if (msgtype == 17) {
- fixable = fixBitErrors(msg, MODES_LONG_MSG_BITS);
+ fixable = fixBitErrors(msg, MODES_LONG_MSG_BITS,
+ MODES_MAX_BITERRORS, bitpos);
}
if (Modes.debug & MODES_DEBUG_JS) {
- dumpRawMessageJS(descr, msg, m, offset, fixable);
+ dumpRawMessageJS(descr, msg, m, offset, fixable, bitpos);
return;
}
@@ -1253,8 +1271,8 @@ int fixTwoBitsErrors(unsigned char *msg, int bits) {
*/
struct errorinfo {
uint32_t syndrome; /* CRC syndrome */
- int pos0; /* bit position of first error */
- int pos1; /* bit position of second error, or -1 */
+ int bits; /* No of bit positions to fix */
+ int pos[MODES_MAX_BITERRORS]; /* bit positions */
};
#define NERRORINFO \
@@ -1290,8 +1308,9 @@ void modesInitErrorInfo() {
msg[bytepos0] ^= mask0; // create error0
crc = modesChecksum(msg, MODES_LONG_MSG_BITS);
bitErrorTable[n].syndrome = crc; // single bit error case
- bitErrorTable[n].pos0 = i;
- bitErrorTable[n].pos1 = -1;
+ bitErrorTable[n].bits = 1;
+ bitErrorTable[n].pos[0] = i;
+ bitErrorTable[n].pos[1] = -1;
n += 1;
if (Modes.aggressive) {
@@ -1308,9 +1327,10 @@ void modesInitErrorInfo() {
*/
break;
}
- bitErrorTable[n].syndrome = crc; // two bit error case
- bitErrorTable[n].pos0 = i;
- bitErrorTable[n].pos1 = j;
+ bitErrorTable[n].syndrome = crc; // two bit error case
+ bitErrorTable[n].bits = 2;
+ bitErrorTable[n].pos[0] = i;
+ bitErrorTable[n].pos[1] = j;
n += 1;
msg[bytepos1] ^= mask1; // revert error1
}
@@ -1362,35 +1382,43 @@ int flipBit(unsigned char *msg, int nbits, int bit) {
// 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
+// fixed bit positions in corrected[]. This array can be NULL, otherwise
+// must be of length at least maxcorrected.
// Return number of fixed bits.
//
-int fixBitErrors(unsigned char *msg, int bits) {
+int fixBitErrors(unsigned char *msg, int bits,
+ int maxfixable, int *fixedbitpos) {
struct errorinfo *pei;
struct errorinfo ei;
- int bitpos0, bitpos1, offset, res;
+ int bitpos, offset, res, i;
+ memset(&ei, 0, sizeof(struct errorinfo));
ei.syndrome = modesChecksum(msg, bits);
- ei.pos0 = -1;
- ei.pos1 = -1;
pei = bsearch(&ei, bitErrorTable, NERRORINFO,
sizeof(struct errorinfo), cmpErrorInfo);
if (pei == NULL) {
return 0; // No syndrome found
}
+ if (maxfixable < pei->bits) {
+ return 0;
+ }
res = 0;
offset = MODES_LONG_MSG_BITS-bits;
- bitpos0 = pei->pos0 - offset;
- if ((bitpos0 < 0) || (bitpos0 >= bits)) {
- return 0;
+ /* Check that all bit positions are inside message boundaries */
+ for (i = 0; i < pei->bits; i++) {
+ bitpos = pei->pos[i] - offset;
+ if ((bitpos < 0) || (bitpos >= bits)) {
+ return 0;
+ }
}
- msg[(bitpos0 >> 3)] ^= (1 << (7 - (bitpos0 & 7)));
- res++;
- if (pei->pos1 >= 0) { /* two-bit error pattern */
- bitpos1 = pei->pos1 - offset;
- if ((bitpos1 < 0) || (bitpos1 >= bits)) {
- return 0;
- }
- msg[(bitpos1 >> 3)] ^= (1 << (7 - (bitpos1 & 7)));
- res++;
+ /* Fix the bits */
+ for (i = 0; i < pei->bits; i++) {
+ bitpos = pei->pos[i] - offset;
+ msg[(bitpos >> 3)] ^= (1 << (7 - (bitpos & 7)));
+ if (fixedbitpos != NULL) {
+ fixedbitpos[res] = bitpos;
+ }
+ res++;
}
return res;
}
@@ -1492,7 +1520,8 @@ void testAndTimeBitCorrection() {
inittmsg1();
gettimeofday(&starttv, NULL);
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);
}
gettimeofday(&endtv, NULL);
printf(" New code: 1-bit errors on %d msgs: %ld usecs\n",
@@ -1511,7 +1540,8 @@ void testAndTimeBitCorrection() {
inittmsg2();
gettimeofday(&starttv, NULL);
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);
}
gettimeofday(&endtv, NULL);
printf(" New code: 2-bit errors on %d msgs: %ld usecs\n",
@@ -1745,7 +1775,8 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
// using the results. Perhaps check the ICAO against known aircraft, and check
// IID against known good IID's. That's a TODO.
//
- mm->correctedbits = fixBitErrors(msg, mm->msgbits);
+ mm->correctedbits = fixBitErrors(msg, mm->msgbits,
+ Modes.fix_errors, mm->corrected);
// If we correct, validate ICAO addr to help filter birthday paradox solutions.
if (mm->correctedbits) {
uint32_t addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
@@ -2601,11 +2632,10 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
} else {
Modes.stat_badcrc++;
- Modes.stat_fixed++;
- if (mm.correctedbits == 1) {
- Modes.stat_single_bit_fix++;
- } else if (mm.correctedbits == 2) {
- Modes.stat_two_bits_fix++;
+ Modes.stat_fixed += 1;
+ if ((mm.correctedbits > 0) &&
+ (mm.correctedbits <= MODES_MAX_BITERRORS)) {
+ Modes.stat_bit_fix[mm.correctedbits-1] += 1;
}
}
}
@@ -3858,9 +3888,10 @@ int handleHTTPRequest(struct client *c) {
}
if (strlen(url) < 2) {
- snprintf(getFile, sizeof getFile, "./public_html/gmap.html"); // Default file
+ snprintf(getFile, sizeof getFile, "%s/%s",
+ HTMLPATH, "gmap.html"); // Default file
} else {
- snprintf(getFile, sizeof getFile, "./public_html%s", url);
+ snprintf(getFile, sizeof getFile, "%s/%s", HTMLPATH, url);
}
/* Select the content to send, we have just two so far:
@@ -4155,7 +4186,7 @@ int main(int argc, char **argv) {
Modes.metric = 1;
} else if (!strcmp(argv[j],"--aggressive")) {
Modes.aggressive = 1;
- Modes.fix_errors = 1;
+ Modes.fix_errors = MODES_MAX_BITERRORS;
} else if (!strcmp(argv[j],"--interactive")) {
Modes.interactive = 1;
} else if (!strcmp(argv[j],"--interactive-rows") && more) {
@@ -4280,8 +4311,9 @@ int main(int argc, char **argv) {
printf("%d with good crc\n", Modes.stat_goodcrc);
printf("%d with bad crc\n", Modes.stat_badcrc);
printf("%d errors corrected\n", Modes.stat_fixed);
- printf("%d single bit errors\n", Modes.stat_single_bit_fix);
- printf("%d two bits errors\n", Modes.stat_two_bits_fix);
+ 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 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 1 error\n", Modes.stat_ph_demodulated1);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/dump1090.git
More information about the pkg-hamradio-commits
mailing list