Change the message bit decoder
Change (and hopefully improve) the Message bit decoder. When decoding bits, a "0" is encoded as (m[j]<m[j+1]), and a "1" is (m[j]>m[j+1]) . However, there is a problem if mpj[ == m[j+1] because we can't decide what it's supposed to be. Antirez's original code defaults to a '1', and then lets the bit error detection code sort it out. I *think* it's better to default to '0' because it's more likely that noise added to the signal will produce a spurious '1' rathar than anything subtracting from the signal to produce a spurious '0' Also, Antirez''s code only looks for errors in the first bit of the message. I don't know why this is. There is a potential problem in deciding the message length if there are any errors in the first 5 bits decoded, because this defines the message type (the DF-??), and it's the DF that determines how many bits the message shall contain. If there is an error in the first 5 bits, then we could ignore the DF, and continue decoding a long format (112 bits). However, for weak signals, if the message is a short one (56 bits) this results in the sigStrength decaying to the point where it's level drops below squelch, so we discard a possibly decodeable 56bit However, if we assume it's a short message, and only decode 56 bits, and it's really a long message we won't have decoded all the bits. Not sure what to do about this
This commit is contained in:
parent
ff697dbb51
commit
63622355e3
55
dump1090.c
55
dump1090.c
|
@ -57,6 +57,8 @@
|
||||||
#define MODES_ASYNC_BUF_SAMPLES (MODES_ASYNC_BUF_SIZE / 2) /* Each sample is 2 bytes */
|
#define MODES_ASYNC_BUF_SAMPLES (MODES_ASYNC_BUF_SIZE / 2) /* Each sample is 2 bytes */
|
||||||
#define MODES_AUTO_GAIN -100 /* Use automatic gain. */
|
#define MODES_AUTO_GAIN -100 /* Use automatic gain. */
|
||||||
#define MODES_MAX_GAIN 999999 /* Use max available gain. */
|
#define MODES_MAX_GAIN 999999 /* Use max available gain. */
|
||||||
|
#define MODES_MSG_SQUELCH_LEVEL 0x02FF /* Average signal strength limit */
|
||||||
|
#define MODES_MSG_ENCODER_ERRS 3 /* Maximum number of encoding errors */
|
||||||
|
|
||||||
#define MODES_PREAMBLE_US 8 /* microseconds = bits */
|
#define MODES_PREAMBLE_US 8 /* microseconds = bits */
|
||||||
#define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2)
|
#define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2)
|
||||||
|
@ -1394,7 +1396,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
* 9 -------------------
|
* 9 -------------------
|
||||||
*/
|
*/
|
||||||
for (j = 0; j < mlen; j++) {
|
for (j = 0; j < mlen; j++) {
|
||||||
int low, high, delta, i, errors;
|
int high, i, errors;
|
||||||
int good_message = 0;
|
int good_message = 0;
|
||||||
uint16_t *pPreamble, *pPayload, *pPtr;
|
uint16_t *pPreamble, *pPayload, *pPtr;
|
||||||
uint8_t theByte;
|
uint8_t theByte;
|
||||||
|
@ -1405,6 +1407,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
|
|
||||||
if (!use_correction) // This is not a re-try with phase correction
|
if (!use_correction) // This is not a re-try with phase correction
|
||||||
{ // so try to find a new preamble
|
{ // so try to find a new preamble
|
||||||
|
|
||||||
/* First check of relations between the first 10 samples
|
/* First check of relations between the first 10 samples
|
||||||
* representing a valid preamble. We don't even investigate further
|
* representing a valid preamble. We don't even investigate further
|
||||||
* if this simple test is not passed. */
|
* if this simple test is not passed. */
|
||||||
|
@ -1473,52 +1476,40 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
theByte = 0;
|
theByte = 0;
|
||||||
errors = 0;
|
errors = 0;
|
||||||
sigStrength = 0;
|
sigStrength = 0;
|
||||||
|
|
||||||
msglen = MODES_LONG_MSG_BITS;
|
msglen = MODES_LONG_MSG_BITS;
|
||||||
for (i = 0; i < MODES_LONG_MSG_BITS; i++) {
|
for (i = 0; i < msglen; i++) {
|
||||||
low = *pPtr++;
|
uint32_t a = *pPtr++;
|
||||||
high = *pPtr++;
|
uint32_t b = *pPtr++;
|
||||||
delta = low-high;
|
|
||||||
if (delta < 0) delta = -delta;
|
|
||||||
|
|
||||||
if (i > 0 && delta < 256) {
|
if (a > b)
|
||||||
if (theByte & 2)
|
{sigStrength += (a-b); theByte |= 1;}
|
||||||
{theByte |= 1;}
|
else if (a < b)
|
||||||
} else if (low == high) {
|
{sigStrength += (b-a); /*theByte |= 0;*/}
|
||||||
/* Checking if two adiacent samples have the same magnitude
|
else //a == b,
|
||||||
* is an effective way to detect if it's just random noise
|
{errors++; /*theByte |= 0;*/}
|
||||||
* that was detected as a valid preamble. */
|
|
||||||
theByte |= 2; /* error */
|
|
||||||
if (i < MODES_SHORT_MSG_BITS) errors++;
|
|
||||||
} else if (low > high) {
|
|
||||||
theByte |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < msglen) {
|
if ((i & 7) == 7)
|
||||||
sigStrength += delta;
|
{*pMsg++ = theByte;}
|
||||||
}
|
else if ((i == 4) /*&& (errors == 0) */)
|
||||||
|
{msglen = modesMessageLenByType(theByte);}
|
||||||
|
|
||||||
if (i == 4) {
|
|
||||||
msglen = modesMessageLenByType(theByte);
|
|
||||||
|
|
||||||
} else if ((i & 7) == 7) {
|
|
||||||
*pMsg++ = theByte;
|
|
||||||
}
|
|
||||||
theByte = theByte << 1;
|
theByte = theByte << 1;
|
||||||
|
|
||||||
|
if (errors > MODES_MSG_ENCODER_ERRS)
|
||||||
|
{break;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter for an average delta of three is small enough to let almost
|
/* Filter for an average delta of three is small enough to let almost
|
||||||
* every kind of message to pass, but high enough to filter some
|
* every kind of message to pass, but high enough to filter some
|
||||||
* random noise. */
|
* random noise. */
|
||||||
sigStrength /= msglen;
|
sigStrength /= msglen;
|
||||||
if (sigStrength < (5*255)) {
|
|
||||||
use_correction = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we reached this point, and error is zero, we are very likely
|
/* 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
|
* 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. */
|
* and CRC may not be correct. This is handled by the next layer. */
|
||||||
if (errors == 0 || (Modes.aggressive && errors < 3)) {
|
if ( (sigStrength > MODES_MSG_SQUELCH_LEVEL) && (errors <= MODES_MSG_ENCODER_ERRS) )
|
||||||
|
{
|
||||||
struct modesMessage mm;
|
struct modesMessage mm;
|
||||||
|
|
||||||
/* Decode the received message and update statistics */
|
/* Decode the received message and update statistics */
|
||||||
|
|
Loading…
Reference in a new issue