Decoder cleanups from experimental branch.

This commit is contained in:
Oliver Jowett 2015-01-21 00:23:48 +00:00
parent 0433ed3f5d
commit 5e522fe8db
8 changed files with 588 additions and 477 deletions

View file

@ -317,6 +317,7 @@ void demodulate2000(uint16_t *m, uint32_t mlen) {
int msglen, scanlen; int msglen, scanlen;
uint32_t sigLevel, noiseLevel; uint32_t sigLevel, noiseLevel;
uint16_t snr; uint16_t snr;
int message_ok;
pPreamble = &m[j]; pPreamble = &m[j];
pPayload = &m[j+MODES_PREAMBLE_SAMPLES]; pPayload = &m[j+MODES_PREAMBLE_SAMPLES];
@ -325,7 +326,6 @@ void demodulate2000(uint16_t *m, uint32_t mlen) {
// is required for every bit of the input stream, and we don't want to be memset-ing the whole // is required for every bit of the input stream, and we don't want to be memset-ing the whole
// modesMessage structure two million times per second if we don't have to.. // modesMessage structure two million times per second if we don't have to..
mm.bFlags = mm.bFlags =
mm.crcok =
mm.correctedbits = 0; mm.correctedbits = 0;
if (!use_correction) // This is not a re-try with phase correction if (!use_correction) // This is not a re-try with phase correction
@ -544,7 +544,7 @@ void demodulate2000(uint16_t *m, uint32_t mlen) {
mm.phase_corrected = use_correction; mm.phase_corrected = use_correction;
// Decode the received message // Decode the received message
decodeModesMessage(&mm, msg); message_ok = (decodeModesMessage(&mm, msg) >= 0);
// Update statistics // Update statistics
if (Modes.stats) { if (Modes.stats) {
@ -557,16 +557,16 @@ void demodulate2000(uint16_t *m, uint32_t mlen) {
default: dstats->demodulated3++; break; default: dstats->demodulated3++; break;
} }
if (mm.crcok) { if (!message_ok) {
dstats->badcrc++;
} else if (mm.correctedbits == 0) {
dstats->goodcrc++; dstats->goodcrc++;
dstats->goodcrc_byphase[0]++; dstats->goodcrc_byphase[0]++;
} else if (mm.correctedbits > 0) { } else {
dstats->badcrc++; dstats->badcrc++;
dstats->fixed++; dstats->fixed++;
if (mm.correctedbits <= MODES_MAX_BITERRORS) if (mm.correctedbits <= MODES_MAX_BITERRORS)
dstats->bit_fix[mm.correctedbits-1] += 1; dstats->bit_fix[mm.correctedbits-1] += 1;
} else {
dstats->badcrc++;
} }
} }
@ -576,22 +576,23 @@ void demodulate2000(uint16_t *m, uint32_t mlen) {
dumpRawMessage("Demodulated with 0 errors", msg, m, j); dumpRawMessage("Demodulated with 0 errors", msg, m, j);
else if (Modes.debug & MODES_DEBUG_BADCRC && else if (Modes.debug & MODES_DEBUG_BADCRC &&
mm.msgtype == 17 && mm.msgtype == 17 &&
(!mm.crcok || mm.correctedbits != 0)) (!message_ok || mm.correctedbits > 0))
dumpRawMessage("Decoded with bad CRC", msg, m, j); dumpRawMessage("Decoded with bad CRC", msg, m, j);
else if (Modes.debug & MODES_DEBUG_GOODCRC && mm.crcok && else if (Modes.debug & MODES_DEBUG_GOODCRC &&
message_ok &&
mm.correctedbits == 0) mm.correctedbits == 0)
dumpRawMessage("Decoded with good CRC", msg, m, j); dumpRawMessage("Decoded with good CRC", msg, m, j);
} }
// Skip this message if we are sure it's fine // Skip this message if we are sure it's fine
if (mm.crcok || mm.correctedbits) { if (message_ok) {
j += (MODES_PREAMBLE_US+msglen)*2 - 1; j += (MODES_PREAMBLE_US+msglen)*2 - 1;
// Pass data to the next layer
useModesMessage(&mm);
} }
// Pass data to the next layer
useModesMessage(&mm);
} else { } else {
message_ok = 0;
if (Modes.debug & MODES_DEBUG_DEMODERR && use_correction) { if (Modes.debug & MODES_DEBUG_DEMODERR && use_correction) {
printf("The following message has %d demod errors\n", errors); printf("The following message has %d demod errors\n", errors);
dumpRawMessage("Demodulated with errors", msg, m, j); dumpRawMessage("Demodulated with errors", msg, m, j);
@ -599,7 +600,7 @@ void demodulate2000(uint16_t *m, uint32_t mlen) {
} }
// Retry with phase correction if enabled, necessary and possible. // Retry with phase correction if enabled, necessary and possible.
if (Modes.phase_enhance && !mm.crcok && !mm.correctedbits && !use_correction && j && detectOutOfPhase(pPreamble)) { if (Modes.phase_enhance && (!message_ok || mm.correctedbits > 0) && !use_correction && j && detectOutOfPhase(pPreamble)) {
use_correction = 1; j--; use_correction = 1; j--;
} else { } else {
use_correction = 0; use_correction = 0;

View file

@ -273,7 +273,6 @@ void demodulate2400(uint16_t *m, uint32_t mlen)
// is required for every possible preamble, and we don't want to be memset-ing the whole // is required for every possible preamble, and we don't want to be memset-ing the whole
// modesMessage structure if we don't have to.. // modesMessage structure if we don't have to..
mm.bFlags = mm.bFlags =
mm.crcok =
mm.correctedbits = 0; mm.correctedbits = 0;
// Decode all the next 112 bits, regardless of the actual message // Decode all the next 112 bits, regardless of the actual message
@ -456,13 +455,15 @@ void demodulate2400(uint16_t *m, uint32_t mlen)
if ( (msglen) if ( (msglen)
// && ((2 * snr) > (int) (MODES_MSG_SQUELCH_DB * 10)) // && ((2 * snr) > (int) (MODES_MSG_SQUELCH_DB * 10))
&& (errors <= MODES_MSG_ENCODER_ERRS) ) { && (errors <= MODES_MSG_ENCODER_ERRS) ) {
int message_ok;
// Set initial mm structure details // Set initial mm structure details
mm.timestampMsg = Modes.timestampBlk + (j*5) + try_phase; mm.timestampMsg = Modes.timestampBlk + (j*5) + try_phase;
mm.signalLevel = (snr > 255 ? 255 : (uint8_t)snr); mm.signalLevel = (snr > 255 ? 255 : (uint8_t)snr);
mm.phase_corrected = (initial_phase != try_phase); mm.phase_corrected = (initial_phase != try_phase);
// Decode the received message // Decode the received message
decodeModesMessage(&mm, msg); message_ok = (decodeModesMessage(&mm, msg) >= 0);
// Update statistics // Update statistics
if (Modes.stats) { if (Modes.stats) {
@ -475,16 +476,16 @@ void demodulate2400(uint16_t *m, uint32_t mlen)
default: dstats->demodulated3++; break; default: dstats->demodulated3++; break;
} }
if (mm.crcok) { if (!message_ok) {
dstats->goodcrc++; dstats->badcrc++;
dstats->goodcrc_byphase[try_phase%MODES_MAX_PHASE_STATS]++;
} else if (mm.correctedbits > 0) { } else if (mm.correctedbits > 0) {
dstats->badcrc++; dstats->badcrc++;
dstats->fixed++; dstats->fixed++;
if (mm.correctedbits <= MODES_MAX_BITERRORS) if (mm.correctedbits <= MODES_MAX_BITERRORS)
dstats->bit_fix[mm.correctedbits-1] += 1; dstats->bit_fix[mm.correctedbits-1] += 1;
} else { } else {
dstats->badcrc++; dstats->goodcrc++;
dstats->goodcrc_byphase[try_phase%MODES_MAX_PHASE_STATS]++;
} }
} }
@ -494,7 +495,7 @@ void demodulate2400(uint16_t *m, uint32_t mlen)
// where the preamble of the second message clobbered the last // where the preamble of the second message clobbered the last
// few bits of the first message, but the message bits didn't // few bits of the first message, but the message bits didn't
// overlap) // overlap)
if (mm.crcok || mm.correctedbits) { if (message_ok) {
j += (8 + msglen - 8)*12/5 - 1; j += (8 + msglen - 8)*12/5 - 1;
} }
@ -506,7 +507,7 @@ void demodulate2400(uint16_t *m, uint32_t mlen)
// where trying different phases actually helps, and is much // where trying different phases actually helps, and is much
// cheaper than trying it on every single candidate that passes // cheaper than trying it on every single candidate that passes
// peak detection // peak detection
if (Modes.phase_enhance && !mm.crcok && !mm.correctedbits) { if (Modes.phase_enhance && !message_ok) {
if (try_phase == initial_phase) if (try_phase == initial_phase)
++Modes.stats_current.out_of_phase; ++Modes.stats_current.out_of_phase;
try_phase++; try_phase++;

View file

@ -406,7 +406,6 @@ struct modesMessage {
unsigned char msg[MODES_LONG_MSG_BYTES]; // Binary message. unsigned char msg[MODES_LONG_MSG_BYTES]; // Binary message.
int msgbits; // Number of bits in message int msgbits; // Number of bits in message
int msgtype; // Downlink format # int msgtype; // Downlink format #
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
char corrected[MODES_MAX_BITERRORS]; // corrected bit positions char corrected[MODES_MAX_BITERRORS]; // corrected bit positions
@ -416,7 +415,7 @@ struct modesMessage {
int remote; // If set this message is from a remote station int remote; // If set this message is from a remote station
unsigned char signalLevel; // Signal Amplitude unsigned char signalLevel; // Signal Amplitude
// DF 11 // DF 11, DF 17
int ca; // Responder capabilities int ca; // Responder capabilities
int iid; int iid;
@ -434,10 +433,16 @@ struct modesMessage {
int vert_rate; // Vertical rate. int vert_rate; // Vertical rate.
int velocity; // Reported by aircraft, or computed from from EW and NS velocity int velocity; // Reported by aircraft, or computed from from EW and NS velocity
// DF 18
int cf; // Control Field
// DF4, DF5, DF20, DF21 // DF4, DF5, DF20, DF21
int fs; // Flight status for DF4,5,20,21 int fs; // Flight status for DF4,5,20,21
int modeA; // 13 bits identity (Squawk). int modeA; // 13 bits identity (Squawk).
// DF20, DF21
int bds; // BDS value implied if overlay control was used
// Fields used by multiple message types. // Fields used by multiple message types.
int altitude; int altitude;
int unit; int unit;
@ -462,7 +467,7 @@ int ModeAToModeC (unsigned int ModeA);
// //
int modesMessageLenByType(int type); int modesMessageLenByType(int type);
void detectModeS_oversample (uint16_t *m, uint32_t mlen); void detectModeS_oversample (uint16_t *m, uint32_t mlen);
void decodeModesMessage (struct modesMessage *mm, unsigned char *msg); int decodeModesMessage (struct modesMessage *mm, unsigned char *msg);
void displayModesMessage(struct modesMessage *mm); void displayModesMessage(struct modesMessage *mm);
void useModesMessage (struct modesMessage *mm); void useModesMessage (struct modesMessage *mm);
void computeMagnitudeVector(uint16_t *pData); void computeMagnitudeVector(uint16_t *pData);

View file

@ -26,7 +26,7 @@
#define MODES_ICAO_FILTER_TTL 60 #define MODES_ICAO_FILTER_TTL 60
// Open-addressed hash table with linear probing. // Open-addressed hash table with linear probing.
// We store each address twice to handle Address/Parity and Data/Parity // We store each address twice to handle Data/Parity
// which need to match on a partial address (top 16 bits only). // which need to match on a partial address (top 16 bits only).
// Maintain two tables and switch between them to age out entries. // Maintain two tables and switch between them to age out entries.

View file

@ -380,13 +380,7 @@ static void updatePosition(struct aircraft *a, struct modesMessage *mm, time_t n
struct aircraft *interactiveReceiveData(struct modesMessage *mm) { struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
struct aircraft *a, *aux; struct aircraft *a, *aux;
time_t now; time_t now = time(NULL);
// Return if (checking crc) AND (not crcok) AND (not fixed)
if (Modes.check_crc && (mm->crcok == 0) && (mm->correctedbits == 0))
return NULL;
now = time(NULL);
// Lookup our aircraft or create a new one // Lookup our aircraft or create a new one
a = interactiveFindAircraft(mm->addr); a = interactiveFindAircraft(mm->addr);

View file

@ -385,7 +385,6 @@ void decodeModeAMessage(struct modesMessage *mm, int ModeA)
// Not much else we can tell from a Mode A/C reply. // Not much else we can tell from a Mode A/C reply.
// Just fudge up a few bits to keep other code happy // Just fudge up a few bits to keep other code happy
mm->crcok = 1;
mm->correctedbits = 0; mm->correctedbits = 0;
} }
// //

983
mode_s.c

File diff suppressed because it is too large Load diff

View file

@ -579,7 +579,12 @@ int decodeBinMessage(struct client *c, char *p) {
if (msgLen == MODEAC_MSG_BYTES) { // ModeA or ModeC if (msgLen == MODEAC_MSG_BYTES) { // ModeA or ModeC
decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1])); decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1]));
} else { } else {
decodeModesMessage(&mm, msg); if (decodeModesMessage(&mm, msg) < 0) {
Modes.stats_current.remote_rejected++;
return 0;
} else {
Modes.stats_current.remote_accepted++;
}
} }
useModesMessage(&mm); useModesMessage(&mm);
@ -678,7 +683,12 @@ int decodeHexMessage(struct client *c, char *hex) {
if (l == (MODEAC_MSG_BYTES * 2)) { // ModeA or ModeC if (l == (MODEAC_MSG_BYTES * 2)) { // ModeA or ModeC
decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1])); decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1]));
} else { // Assume ModeS } else { // Assume ModeS
decodeModesMessage(&mm, msg); if (decodeModesMessage(&mm, msg) < 0) {
Modes.stats_current.remote_rejected++;
return 0;
} else {
Modes.stats_current.remote_accepted++;
}
} }
useModesMessage(&mm); useModesMessage(&mm);