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
59
dump1090.c
59
dump1090.c
|
@ -57,6 +57,8 @@
|
|||
#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_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_SAMPLES (MODES_PREAMBLE_US * 2)
|
||||
|
@ -1394,10 +1396,10 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
|||
* 9 -------------------
|
||||
*/
|
||||
for (j = 0; j < mlen; j++) {
|
||||
int low, high, delta, i, errors;
|
||||
int high, i, errors;
|
||||
int good_message = 0;
|
||||
uint16_t *pPreamble, *pPayload, *pPtr;
|
||||
uint8_t theByte;
|
||||
uint8_t theByte;
|
||||
int msglen, sigStrength;
|
||||
|
||||
pPreamble = &m[j];
|
||||
|
@ -1405,6 +1407,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
|||
|
||||
if (!use_correction) // This is not a re-try with phase correction
|
||||
{ // so try to find a new preamble
|
||||
|
||||
/* First check of relations between the first 10 samples
|
||||
* representing a valid preamble. We don't even investigate further
|
||||
* if this simple test is not passed. */
|
||||
|
@ -1429,7 +1432,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
|||
* of the high spikes level. We don't test bits too near to
|
||||
* the high levels as signals can be out of phase so part of the
|
||||
* energy can be in the near samples. */
|
||||
high = (pPreamble[0]+pPreamble[2]+pPreamble[7]+pPreamble[9])/6;
|
||||
high = (pPreamble[0] + pPreamble[2] + pPreamble[7] + pPreamble[9]) / 6;
|
||||
if (pPreamble[4] >= high ||
|
||||
pPreamble[5] >= high)
|
||||
{
|
||||
|
@ -1473,52 +1476,40 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
|||
theByte = 0;
|
||||
errors = 0;
|
||||
sigStrength = 0;
|
||||
msglen = MODES_LONG_MSG_BITS;
|
||||
for (i = 0; i < MODES_LONG_MSG_BITS; i++) {
|
||||
low = *pPtr++;
|
||||
high = *pPtr++;
|
||||
delta = low-high;
|
||||
if (delta < 0) delta = -delta;
|
||||
|
||||
if (i > 0 && delta < 256) {
|
||||
if (theByte & 2)
|
||||
{theByte |= 1;}
|
||||
} else if (low == high) {
|
||||
/* Checking if two adiacent samples have the same magnitude
|
||||
* is an effective way to detect if it's just random noise
|
||||
* that was detected as a valid preamble. */
|
||||
theByte |= 2; /* error */
|
||||
if (i < MODES_SHORT_MSG_BITS) errors++;
|
||||
} else if (low > high) {
|
||||
theByte |= 1;
|
||||
}
|
||||
msglen = MODES_LONG_MSG_BITS;
|
||||
for (i = 0; i < msglen; i++) {
|
||||
uint32_t a = *pPtr++;
|
||||
uint32_t b = *pPtr++;
|
||||
|
||||
if (i < msglen) {
|
||||
sigStrength += delta;
|
||||
}
|
||||
if (a > b)
|
||||
{sigStrength += (a-b); theByte |= 1;}
|
||||
else if (a < b)
|
||||
{sigStrength += (b-a); /*theByte |= 0;*/}
|
||||
else //a == b,
|
||||
{errors++; /*theByte |= 0;*/}
|
||||
|
||||
if (i == 4) {
|
||||
msglen = modesMessageLenByType(theByte);
|
||||
if ((i & 7) == 7)
|
||||
{*pMsg++ = theByte;}
|
||||
else if ((i == 4) /*&& (errors == 0) */)
|
||||
{msglen = modesMessageLenByType(theByte);}
|
||||
|
||||
} else if ((i & 7) == 7) {
|
||||
*pMsg++ = theByte;
|
||||
}
|
||||
theByte = theByte << 1;
|
||||
|
||||
if (errors > MODES_MSG_ENCODER_ERRS)
|
||||
{break;}
|
||||
}
|
||||
|
||||
/* 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
|
||||
* random noise. */
|
||||
sigStrength /= msglen;
|
||||
if (sigStrength < (5*255)) {
|
||||
use_correction = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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 (errors == 0 || (Modes.aggressive && errors < 3)) {
|
||||
if ( (sigStrength > MODES_MSG_SQUELCH_LEVEL) && (errors <= MODES_MSG_ENCODER_ERRS) )
|
||||
{
|
||||
struct modesMessage mm;
|
||||
|
||||
/* Decode the received message and update statistics */
|
||||
|
|
Loading…
Reference in a new issue