Add a --no-fix-df option

Usually, all message candidates are speculatively corrected as if
they were DF11/17/18, even if the DF field has a different value. This
allows correction of messages when there is correctable damage to the
DF field.

However, running every message candidate through a couple of CRC checks
is expensive, CPU-wise, when decoding messages off the air, as there are
a large number of message candidates that are actually just junk data, and
computing CRCs for all of those adds up. The --no-fix-df option allows
disabling this sort of correction. The tradeoff is that messages with
damage to the DF field will not be corrected.
This commit is contained in:
Oliver Jowett 2021-03-08 14:23:35 +08:00
parent d90426e1ce
commit a135d2b915
5 changed files with 14 additions and 2 deletions

View File

@ -113,6 +113,7 @@ static void modesInitConfig(void) {
Modes.gain = MODES_MAX_GAIN;
Modes.freq = MODES_DEFAULT_FREQ;
Modes.check_crc = 1;
Modes.fix_df = 1;
Modes.net_heartbeat_interval = MODES_NET_HEARTBEAT_INTERVAL;
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
Modes.json_interval = 1000;
@ -334,6 +335,7 @@ static void showHelp(void)
"--fix Enable single-bit error correction using CRC\n"
"--fix-2bit Enable two-bit error correction using CRC (use with caution)\n"
"--no-fix Disable error correction using CRC\n"
"--no-fix-df Disable error correction of the DF message field (reduces CPU requirements)\n"
"--no-crc-check Disable messages with broken CRC (discouraged)\n"
"--mlat display raw messages in Beast ascii mode\n"
"--stats With --ifile print stats at exit. No other output\n"
@ -547,6 +549,8 @@ int main(int argc, char **argv) {
Modes.nfix_crc = 2;
} else if (!strcmp(argv[j],"--no-fix")) {
Modes.nfix_crc = 0;
} else if (!strcmp(argv[j],"--no-fix-df")) {
Modes.fix_df = 0;
} else if (!strcmp(argv[j],"--no-crc-check")) {
Modes.check_crc = 0;
} else if (!strcmp(argv[j],"--phase-enhance")) {

View File

@ -324,6 +324,7 @@ struct _Modes { // Internal state
sdr_type_t sdr_type; // where are we getting data from?
int nfix_crc; // Number of crc bit error(s) to correct
int check_crc; // Only display messages with good CRC
int fix_df; // Try to correct damage to the DF field, as well as the main message body
int raw; // Raw output format
int mode_ac; // Enable decoding of SSR Modes A & C
int mode_ac_auto; // allow toggling of A/C by Beast commands

View File

@ -71,6 +71,7 @@ static void faupInitConfig(void) {
// Now initialise things that should not be 0/NULL to their defaults
Modes.nfix_crc = 1;
Modes.check_crc = 1;
Modes.fix_df = 1;
Modes.net = 1;
Modes.net_heartbeat_interval = MODES_NET_HEARTBEAT_INTERVAL;
Modes.maxRange = 1852 * 360; // 360NM default max range; this also disables receiver-relative positions

View File

@ -268,8 +268,13 @@ static int correctMessage(const unsigned char *in, unsigned char *out)
const unsigned uncorrected_df = getbits(in, 1, 5);
const uint32_t df_bit = 1 << uncorrected_df;
// Select the right bitset based on the maximum number of bit errors in the DF field that we could correct.
// nb: strictly speaking, --no-fix-df doesn't _entirely_ disable correction of the DF field when nfix_crc == 2
// (DF17 could be corrected to DF18 or vice versa), but it does disable the CPU hungry part of it.
const unsigned fix_df_bits = (Modes.fix_df ? Modes.nfix_crc : 0);
struct errorinfo *long_ei = NULL;
if (df_correctable_long[Modes.nfix_crc] & df_bit) {
if (df_correctable_long[fix_df_bits] & df_bit) {
uint32_t long_syndrome = modesChecksum(in, MODES_LONG_MSG_BITS);
if (isLongPIMessage(in) && long_syndrome == 0) {
// DF17/18 message with correct checksum
@ -281,7 +286,7 @@ static int correctMessage(const unsigned char *in, unsigned char *out)
}
struct errorinfo *short_ei = NULL;
if (df_correctable_short[Modes.nfix_crc] & df_bit) {
if (df_correctable_short[fix_df_bits] & df_bit) {
uint32_t short_syndrome = modesChecksum(in, MODES_SHORT_MSG_BITS);
if (isShortPIMessage(in) && (short_syndrome & 0xFFFF80) == 0) {
// DF11 message with correct checksum

View File

@ -57,6 +57,7 @@ static void view1090InitConfig(void) {
// Now initialise things that should not be 0/NULL to their defaults
Modes.check_crc = 1;
Modes.fix_df = 1;
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
Modes.interactive = 1;
Modes.maxRange = 1852 * 300; // 300NM default max range