[hamradio-commits] [dump1090] 118/389: DF Error detection and Correction
Matthew Ernisse
mernisse-guest at moszumanska.debian.org
Wed Nov 5 00:19:46 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 e161b7662c1bc3ef13f0d63aebfa2ae853e55bb1
Author: Malcolm Robb <Support at ATTAvionics.com>
Date: Mon Apr 29 01:30:12 2013 +0100
DF Error detection and Correction
Added additional error detection and correction to the DF field of the
first byte in every ModeS frame.
---
dump1090.c | 113 +++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 72 insertions(+), 41 deletions(-)
diff --git a/dump1090.c b/dump1090.c
index 6937f13..c0c966d 100644
--- a/dump1090.c
+++ b/dump1090.c
@@ -243,7 +243,8 @@ struct {
unsigned int stat_http_requests;
unsigned int stat_sbs_connections;
unsigned int stat_out_of_phase;
- unsigned int stat_DF_Corrected;
+ unsigned int stat_DF_Len_Corrected;
+ unsigned int stat_DF_Type_Corrected;
unsigned int stat_ModeAC;
} Modes;
@@ -462,7 +463,8 @@ void modesInit(void) {
Modes.stat_http_requests = 0;
Modes.stat_sbs_connections = 0;
Modes.stat_out_of_phase = 0;
- Modes.stat_DF_Corrected = 0;
+ Modes.stat_DF_Len_Corrected = 0;
+ Modes.stat_DF_Type_Corrected = 0;
Modes.stat_ModeAC = 0;
Modes.exit = 0;
}
@@ -1892,7 +1894,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
int good_message = 0;
uint16_t *pPreamble, *pPayload, *pPtr;
uint8_t theByte, theErrs;
- int msglen, sigStrength;
+ int msglen, scanlen, sigStrength;
pPreamble = &m[j];
pPayload = &m[j+MODES_PREAMBLE_SAMPLES];
@@ -1997,69 +1999,97 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
+ (pPreamble[7]-pPreamble[6])
+ (pPreamble[9]-pPreamble[8]);
- msglen = MODES_LONG_MSG_BITS;
- for (i = 0; i < msglen; i++) {
+ msglen = scanlen = MODES_LONG_MSG_BITS;
+ for (i = 0; i < scanlen; i++) {
uint32_t a = *pPtr++;
uint32_t b = *pPtr++;
if (a > b)
- {sigStrength += (a-b); theByte |= 1;}
+ {theByte |= 1; if (i < 56) {sigStrength += (a-b);}}
else if (a < b)
- {sigStrength += (b-a); /*theByte |= 0;*/}
+ {/*theByte |= 0;*/ if (i < 56) {sigStrength += (b-a);}}
else if (i >= MODES_SHORT_MSG_BITS) //(a == b), and we're in the long part of a frame
{errors++; /*theByte |= 0;*/}
else if (i >= 5) //(a == b), and we're in the short part of a frame
- {errors56 = ++errors;/*theByte |= 0;*/}
- else //(a == b), and we're in the message type part of a frame
+ {scanlen = MODES_LONG_MSG_BITS; errors56 = ++errors;/*theByte |= 0;*/}
+ else if (i) //(a == b), and we're in the message type part of a frame
{errorsTy = errors56 = ++errors; theErrs |= 1; /*theByte |= 0;*/}
+ else //(a == b), and we're in the first bit of the message type part of a frame
+ {errorsTy = errors56 = ++errors; theErrs |= 1; theByte |= 1;}
if ((i & 7) == 7)
{*pMsg++ = theByte;}
- else if ((i == 4) && (errors == 0))
- {msglen = modesMessageLenByType(theByte);}
+ else if (i == 4) {
+ msglen = modesMessageLenByType(theByte);
+ if (errors == 0)
+ {scanlen = msglen;}
+ }
theByte = theByte << 1;
- if (i < 8)
+ if (i < 7)
{theErrs = theErrs << 1;}
-
// If we've exceeded the permissible number of encoding errors, abandon ship now
- if (errors > MODES_MSG_ENCODER_ERRS)
- {
- // If we're in the long frame when it went to pot, but it was still ok-ish when we
- // were in the short part of the frame, then try for a mis-identified short frame
- // we must believe that this should've been a long frame to get this far.
- if (i >= MODES_SHORT_MSG_BITS)
- {
- // If we did see some errors in the first byte of the frame, then it's possible
- // we guessed wrongly about the value of the bit. If we only saw one error, we may
- // be able to correct it by guessing the other way.
- if (errorsTy == 1)
- {
- // See if inverting the bit we guessed at would change the message type from a
- // long to a short. If it would, invert the bit, cross your fingers and carry on.
- theByte = pMsg[0] ^ theErrs;
- if (MODES_SHORT_MSG_BITS == modesMessageLenByType(theByte))
- {
- pMsg[0] = theByte; // write the modified type back to the msg buffer
- errors = errors56; // revert to the number of errors prior to bit 56
- msglen = MODES_SHORT_MSG_BITS;
- i--; // this latest sample was zero, so we can ignore it.
- Modes.stat_DF_Corrected++;
- }
- }
+ if (errors > MODES_MSG_ENCODER_ERRS) {
+
+ if (i < MODES_SHORT_MSG_BITS) {
+ msglen = 0;
+
+ } else if ((errorsTy == 1) && (theErrs == 0x80)) {
+ // If we only saw one error in the first bit of the byte of the frame, then it's possible
+ // we guessed wrongly about the value of the bit. We may be able to correct it by guessing
+ // the other way.
+ //
+ // We guessed a '1' at bit 7, which is the DF length bit == 112 Bits.
+ // Inverting bit 7 will change the message type from a long to a short.
+ // Invert the bit, cross your fingers and carry on.
+ msglen = MODES_SHORT_MSG_BITS;
+ msg[0] ^= theErrs; errorsTy = 0;
+ errors = errors56; // revert to the number of errors prior to bit 56
+ Modes.stat_DF_Len_Corrected++;
+
+ } else if (i < MODES_LONG_MSG_BITS) {
+ msglen = MODES_SHORT_MSG_BITS;
+ errors = errors56;
+
+ } else {
+ msglen = MODES_LONG_MSG_BITS;
+ }
+
+ break;
+ }
+ }
+
+ if (msglen == modesMessageLenByType(theByte = msg[0])) {
+ // The msglen is consistent with the DF type
+ if ((errorsTy == 1) && (theErrs & 0x78)) {
+ // We guessed at one of the message type bits. See if our guess is "likely"
+ // to be correct by comparing the DF against a list of known good DF's
+ int DF = ((theByte = msg[0]) >> 3) & 0x1f;
+ if ( (DF != 0) && (DF != 4) && (DF != 5) && (DF != 11)
+ && (DF != 16) && (DF != 17) && (DF != 18) && (DF != 19) && (DF != 20) && (DF != 21) && (DF != 22) && (DF != 24) ) {
+ // Other DF values are probably errors. Toggle the bit we guessed at and see if the resultant DF is more likely
+ theByte ^= theErrs;
+ DF = (theByte >> 3) & 0x1f;
+ // if this DF any more likely??
+ if ( (DF == 0) || (DF == 4) || (DF == 5) || (DF == 11)
+ || (DF == 16) || (DF == 17) || (DF == 18) || (DF == 19) || (DF == 20) || (DF == 21) || (DF == 22) || (DF == 24) ) {
+ // Yep, more likely, so update the main message
+ msg[0] = theByte;
+ Modes.stat_DF_Type_Corrected++;
+ errors--; // decrease the error count so we attempt to use the modified DF.
}
- break;
}
+ }
}
// Don't forget to add 4 for the preamble samples. This also removes any risk of dividing by zero.
- sigStrength /= (msglen+4);
+ sigStrength /= 60;
/* If we reached this point, and error is zero, we are very likely
* with a Mode S message in our hands, but it may still be broken
* and CRC may not be correct. This is handled by the next layer. */
- if ( (sigStrength > MODES_MSG_SQUELCH_LEVEL) && (errors <= MODES_MSG_ENCODER_ERRS) )
+ if ((msglen) && (sigStrength > MODES_MSG_SQUELCH_LEVEL) && (errors <= MODES_MSG_ENCODER_ERRS) )
{
struct modesMessage mm;
@@ -3580,7 +3610,8 @@ int main(int argc, char **argv) {
if (Modes.stats && Modes.filename) {
printf("%d ModeA/C detected\n", Modes.stat_ModeAC);
printf("%d valid preambles\n", Modes.stat_valid_preamble);
- printf("%d DF-?? fields corrected for length\n", Modes.stat_DF_Corrected);
+ printf("%d DF-?? fields corrected for length\n", Modes.stat_DF_Len_Corrected);
+ printf("%d DF-?? fields corrected for type\n", Modes.stat_DF_Type_Corrected);
printf("%d demodulated again after phase correction\n", Modes.stat_out_of_phase);
printf("%d demodulated with zero errors\n", Modes.stat_demodulated);
printf("%d with good crc\n", Modes.stat_goodcrc);
--
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