Merge branch 'upstream'
This commit is contained in:
commit
bdc1613512
294
demod_2400.c
294
demod_2400.c
|
@ -470,3 +470,297 @@ void demodulate2400(struct mag_buf *mag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////
|
||||||
|
////////// MODE A/C
|
||||||
|
//////////
|
||||||
|
|
||||||
|
// Mode A/C bits are 1.45us wide, consisting of 0.45us on and 1.0us off
|
||||||
|
// We track this in terms of a (virtual) 60MHz clock, which is the lowest common multiple
|
||||||
|
// of the bit frequency and the 2.4MHz sampling frequency
|
||||||
|
//
|
||||||
|
// 0.45us = 27 cycles }
|
||||||
|
// 1.00us = 60 cycles } one bit period = 1.45us = 87 cycles
|
||||||
|
//
|
||||||
|
// one 2.4MHz sample = 25 cycles
|
||||||
|
|
||||||
|
void demodulate2400AC(struct mag_buf *mag)
|
||||||
|
{
|
||||||
|
struct modesMessage mm;
|
||||||
|
uint16_t *m = mag->data;
|
||||||
|
uint32_t mlen = mag->length;
|
||||||
|
unsigned f1_sample;
|
||||||
|
|
||||||
|
memset(&mm, 0, sizeof(mm));
|
||||||
|
|
||||||
|
for (f1_sample = 1; f1_sample < mlen; ++f1_sample) {
|
||||||
|
// Mode A/C messages should match this bit sequence:
|
||||||
|
|
||||||
|
// bit # value
|
||||||
|
// -1 0 quiet zone
|
||||||
|
// 0 1 framing pulse (F1)
|
||||||
|
// 1 C1
|
||||||
|
// 2 A1
|
||||||
|
// 3 C2
|
||||||
|
// 4 A2
|
||||||
|
// 5 C4
|
||||||
|
// 6 A4
|
||||||
|
// 7 0 quiet zone (X1)
|
||||||
|
// 8 B1
|
||||||
|
// 9 D1
|
||||||
|
// 10 B2
|
||||||
|
// 11 D2
|
||||||
|
// 12 B4
|
||||||
|
// 13 D4
|
||||||
|
// 14 1 framing pulse (F2)
|
||||||
|
// 15 0 quiet zone (X2)
|
||||||
|
// 16 0 quiet zone (X3)
|
||||||
|
// 17 SPI
|
||||||
|
// 18 0 quiet zone (X4)
|
||||||
|
// 19 0 quiet zone (X5)
|
||||||
|
// 20 0 quiet zone (X6)
|
||||||
|
// 21 0 quiet zone (X7)
|
||||||
|
// 22 0 quiet zone (X8)
|
||||||
|
// 23 0 quiet zone (X9)
|
||||||
|
|
||||||
|
// Look for a F1 and F2 pair,
|
||||||
|
// with F1 starting at offset f1_sample.
|
||||||
|
|
||||||
|
// the first framing pulse covers 3.5 samples:
|
||||||
|
//
|
||||||
|
// |----| |----|
|
||||||
|
// | F1 |________| C1 |_
|
||||||
|
//
|
||||||
|
// | 0 | 1 | 2 | 3 | 4 |
|
||||||
|
//
|
||||||
|
// and there is some unknown phase offset of the
|
||||||
|
// leading edge e.g.:
|
||||||
|
//
|
||||||
|
// |----| |----|
|
||||||
|
// __| F1 |________| C1 |_
|
||||||
|
//
|
||||||
|
// | 0 | 1 | 2 | 3 | 4 |
|
||||||
|
//
|
||||||
|
// in theory the "on" period can straddle 3 samples
|
||||||
|
// but it's not a big deal as at most 4% of the power
|
||||||
|
// is in the third sample.
|
||||||
|
|
||||||
|
if (!(m[f1_sample-1] < m[f1_sample+0]))
|
||||||
|
continue; // not a rising edge
|
||||||
|
|
||||||
|
if (m[f1_sample+2] > m[f1_sample+0] || m[f1_sample+2] > m[f1_sample+1])
|
||||||
|
continue; // quiet part of bit wasn't sufficiently quiet
|
||||||
|
|
||||||
|
unsigned f1_noise = (m[f1_sample-1] + m[f1_sample+2]) / 2;
|
||||||
|
unsigned f1_signal = (m[f1_sample+0] + m[f1_sample+1]) / 2;
|
||||||
|
|
||||||
|
if (f1_noise * 4 > f1_signal) {
|
||||||
|
// require 12dB SNR
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// estimate initial clock phase based on the amount of power
|
||||||
|
// that ended up in the second sample
|
||||||
|
unsigned f1_clock = 25 * f1_sample;
|
||||||
|
if (m[f1_sample+1] > f1_noise) {
|
||||||
|
f1_clock += 25 * (m[f1_sample+1] - f1_noise) / (2*(f1_signal - f1_noise));
|
||||||
|
}
|
||||||
|
|
||||||
|
// same again for F2
|
||||||
|
// F2 is 20.3us / 14 bit periods after F1
|
||||||
|
|
||||||
|
unsigned f2_clock = f1_clock + (87 * 14);
|
||||||
|
unsigned f2_sample = f2_clock / 25;
|
||||||
|
|
||||||
|
if (!(m[f2_sample-1] < m[f2_sample+0]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m[f2_sample+2] > m[f2_sample+0] || m[f2_sample+2] > m[f2_sample+1])
|
||||||
|
continue; // quiet part of bit wasn't sufficiently quiet
|
||||||
|
|
||||||
|
unsigned f2_noise = (m[f2_sample-1] + m[f2_sample+2]) / 2;
|
||||||
|
unsigned f2_signal = (m[f2_sample+0] + m[f2_sample+1]) / 2;
|
||||||
|
|
||||||
|
if (f2_noise * 4 > f2_signal) {
|
||||||
|
// require 12dB SNR
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned f1f2_signal = (f1_signal + f2_signal) / 2;
|
||||||
|
|
||||||
|
// look at X1, X2, X3 which should be quiet
|
||||||
|
// (sample 0 may have part of the previous bit, but
|
||||||
|
// it always covers the quiet part of it)
|
||||||
|
unsigned x1_clock = f1_clock + (87 * 7);
|
||||||
|
unsigned x1_sample = x1_clock / 25;
|
||||||
|
unsigned x1_noise = (m[x1_sample + 0] + m[x1_sample + 1] + m[x1_sample + 2]) / 3;
|
||||||
|
if (x1_noise * 4 >= f1f2_signal)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned x2_clock = f1_clock + (87 * 15);
|
||||||
|
unsigned x2_sample = x2_clock / 25;
|
||||||
|
unsigned x2_noise = (m[x2_sample + 0] + m[x2_sample + 1] + m[x2_sample + 2]) / 3;
|
||||||
|
if (x2_noise * 4 >= f1f2_signal)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned x3_clock = f1_clock + (87 * 16);
|
||||||
|
unsigned x3_sample = x3_clock / 25;
|
||||||
|
unsigned x3_noise = (m[x3_sample + 0] + m[x3_sample + 1] + m[x3_sample + 2]) / 3;
|
||||||
|
if (x3_noise * 4 >= f1f2_signal)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned x1x2x3_noise = (x1_noise + x2_noise + x3_noise) / 3;
|
||||||
|
if (x1x2x3_noise * 4 >= f1f2_signal) // require 12dB separation
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// ----- F1/F2 average signal
|
||||||
|
// ^
|
||||||
|
// | at least 3dB
|
||||||
|
// v
|
||||||
|
// ----- minimum signal level we accept as "on"
|
||||||
|
// ^
|
||||||
|
// | 3dB
|
||||||
|
// v
|
||||||
|
// ---- midpoint between F1/F2 and X1/X2/X3
|
||||||
|
// ^
|
||||||
|
// | 3dB
|
||||||
|
// v
|
||||||
|
// ----- maximum signal level we accept as "off"
|
||||||
|
// ^
|
||||||
|
// | at least 3dB
|
||||||
|
// v
|
||||||
|
// ----- X1/X2/X3 average noise
|
||||||
|
|
||||||
|
float midpoint = sqrtf(x1x2x3_noise * f1f2_signal); // so that signal/midpoint == midpoint/noise
|
||||||
|
unsigned noise_threshold = (unsigned) (midpoint * 0.707107 + 0.5); // -3dB from midpoint
|
||||||
|
unsigned signal_threshold = (unsigned) (midpoint * 1.414214 + 0.5); // +3dB from midpoint
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr, "f1f2 %u x1x2x3 %u midpoint %.0f noise_threshold %u signal_threshold %u\n",
|
||||||
|
f1f2_signal, x1x2x3_noise, midpoint, noise_threshold, signal_threshold);
|
||||||
|
|
||||||
|
fprintf(stderr, "f1 %u f2 %u x1 %u x2 %u x3 %u\n",
|
||||||
|
f1_signal, f2_signal, x1_noise, x2_noise, x3_noise);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// recheck F/X bits just in case
|
||||||
|
if (f1_signal < signal_threshold)
|
||||||
|
continue;
|
||||||
|
if (f2_signal < signal_threshold)
|
||||||
|
continue;
|
||||||
|
if (x1_noise > noise_threshold)
|
||||||
|
continue;
|
||||||
|
if (x2_noise > noise_threshold)
|
||||||
|
continue;
|
||||||
|
if (x3_noise > noise_threshold)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Looks like a real signal. Demodulate all the bits.
|
||||||
|
unsigned noisy_bits = 0;
|
||||||
|
unsigned bits = 0;
|
||||||
|
unsigned bit;
|
||||||
|
unsigned clock;
|
||||||
|
for (bit = 0, clock = f1_clock; bit < 24; ++bit, clock += 87) {
|
||||||
|
unsigned sample = clock / 25;
|
||||||
|
|
||||||
|
bits <<= 1;
|
||||||
|
noisy_bits <<= 1;
|
||||||
|
|
||||||
|
// check for excessive noise in the quiet period
|
||||||
|
if (m[sample+2] >= noise_threshold) {
|
||||||
|
//fprintf(stderr, "bit %u was not quiet (%u > %u)\n", bit, m[sample+2], signal_threshold);
|
||||||
|
noisy_bits |= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decide if this bit is on or off
|
||||||
|
unsigned bit_signal = (m[sample+0] + m[sample+1]) / 2;
|
||||||
|
if (bit_signal >= signal_threshold) {
|
||||||
|
bits |= 1;
|
||||||
|
} else if (bit_signal > noise_threshold) {
|
||||||
|
/* not certain about this bit */
|
||||||
|
//fprintf(stderr, "bit %u was uncertain (%u < %u < %u)\n", bit, noise_threshold, bit_signal, signal_threshold);
|
||||||
|
noisy_bits |= 1;
|
||||||
|
} else {
|
||||||
|
/* this bit is off */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr, "bits: %06X noisy: %06X\n", bits, noisy_bits);
|
||||||
|
|
||||||
|
unsigned j, sample;
|
||||||
|
static const char *names[24] = {
|
||||||
|
"F1", "C1", "A1", "C2",
|
||||||
|
"A2", "C4", "A4", "X1",
|
||||||
|
"B1", "D1", "B2", "D2",
|
||||||
|
"B4", "D4", "F2", "X2",
|
||||||
|
"X3", "SPI", "X4", "X5",
|
||||||
|
"X6", "X7", "X8", "X9"
|
||||||
|
};
|
||||||
|
|
||||||
|
fprintf(stderr, "-1 ... %6u\n", m[f1_sample-1]);
|
||||||
|
for (j = 0; j < 24; ++j) {
|
||||||
|
clock = f1_clock + 87 * j;
|
||||||
|
sample = clock / 25;
|
||||||
|
fprintf(stderr, "%2u %-3s %6u %6u %6u %6u ", j, names[j], m[sample+0], m[sample+1], m[sample+2], m[sample+3]);
|
||||||
|
if ((m[sample+0] + m[sample+1])/2 >= signal_threshold) {
|
||||||
|
fprintf(stderr, "ON\n");
|
||||||
|
} else if ((m[sample+0] + m[sample+1])/2 <= noise_threshold) {
|
||||||
|
fprintf(stderr, "OFF\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "UNCERTAIN\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (noisy_bits) {
|
||||||
|
/* XX debug */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// framing bits must be on
|
||||||
|
if ((bits & 0x800200) != 0x800200) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// quiet bits must be off
|
||||||
|
if ((bits & 0x0101BF) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to the form that we use elsewhere:
|
||||||
|
// 00 A4 A2 A1 00 B4 B2 B1 SPI C4 C2 C1 00 D4 D2 D1
|
||||||
|
unsigned modeac =
|
||||||
|
((bits & 0x400000) ? 0x0010 : 0) | // C1
|
||||||
|
((bits & 0x200000) ? 0x1000 : 0) | // A1
|
||||||
|
((bits & 0x100000) ? 0x0020 : 0) | // C2
|
||||||
|
((bits & 0x080000) ? 0x2000 : 0) | // A2
|
||||||
|
((bits & 0x040000) ? 0x0040 : 0) | // C4
|
||||||
|
((bits & 0x020000) ? 0x4000 : 0) | // A4
|
||||||
|
((bits & 0x008000) ? 0x0100 : 0) | // B1
|
||||||
|
((bits & 0x004000) ? 0x0001 : 0) | // D1
|
||||||
|
((bits & 0x002000) ? 0x0200 : 0) | // B2
|
||||||
|
((bits & 0x001000) ? 0x0002 : 0) | // D2
|
||||||
|
((bits & 0x000800) ? 0x0400 : 0) | // B4
|
||||||
|
((bits & 0x000400) ? 0x0004 : 0) | // D4
|
||||||
|
((bits & 0x000040) ? 0x0080 : 0); // SPI
|
||||||
|
|
||||||
|
// This message looks good, submit it
|
||||||
|
|
||||||
|
// compute message receive time as block-start-time + difference in the 12MHz clock
|
||||||
|
mm.timestampMsg = mag->sampleTimestamp + f1_clock / 5; // 60MHz -> 12MHz
|
||||||
|
mm.sysTimestampMsg = mag->sysTimestamp; // start of block time
|
||||||
|
mm.sysTimestampMsg.tv_nsec += receiveclock_ns_elapsed(mag->sampleTimestamp, mm.timestampMsg);
|
||||||
|
normalize_timespec(&mm.sysTimestampMsg);
|
||||||
|
|
||||||
|
decodeModeAMessage(&mm, modeac);
|
||||||
|
|
||||||
|
// Pass data to the next layer
|
||||||
|
useModesMessage(&mm);
|
||||||
|
|
||||||
|
f1_sample += (24*87 / 25);
|
||||||
|
Modes.stats_current.demod_modeac++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -25,5 +25,6 @@
|
||||||
struct mag_buf;
|
struct mag_buf;
|
||||||
|
|
||||||
void demodulate2400(struct mag_buf *mag);
|
void demodulate2400(struct mag_buf *mag);
|
||||||
|
void demodulate2400AC(struct mag_buf *mag);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
25
dump1090.c
25
dump1090.c
|
@ -294,9 +294,12 @@ int modesInitRTLSDR(void) {
|
||||||
|
|
||||||
fprintf(stderr, "Found %d device(s):\n", device_count);
|
fprintf(stderr, "Found %d device(s):\n", device_count);
|
||||||
for (j = 0; j < device_count; j++) {
|
for (j = 0; j < device_count; j++) {
|
||||||
rtlsdr_get_device_usb_strings(j, vendor, product, serial);
|
if (rtlsdr_get_device_usb_strings(j, vendor, product, serial) != 0) {
|
||||||
fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial,
|
fprintf(stderr, "%d: unable to read device details\n", j);
|
||||||
(j == dev_index) ? "(currently selected)" : "");
|
} else {
|
||||||
|
fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial,
|
||||||
|
(j == dev_index) ? "(currently selected)" : "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtlsdr_open(&Modes.dev, dev_index) < 0) {
|
if (rtlsdr_open(&Modes.dev, dev_index) < 0) {
|
||||||
|
@ -860,8 +863,11 @@ int verbose_device_search(char *s)
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Found %d device(s):\n", device_count);
|
fprintf(stderr, "Found %d device(s):\n", device_count);
|
||||||
for (i = 0; i < device_count; i++) {
|
for (i = 0; i < device_count; i++) {
|
||||||
rtlsdr_get_device_usb_strings(i, vendor, product, serial);
|
if (rtlsdr_get_device_usb_strings(i, vendor, product, serial) != 0) {
|
||||||
fprintf(stderr, " %d: %s, %s, SN: %s\n", i, vendor, product, serial);
|
fprintf(stderr, " %d: unable to read device details\n", i);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, " %d: %s, %s, SN: %s\n", i, vendor, product, serial);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
/* does string look like raw id number */
|
/* does string look like raw id number */
|
||||||
|
@ -1106,12 +1112,6 @@ int main(int argc, char **argv) {
|
||||||
if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);}
|
if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Modes.mode_ac && Modes.oversample) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Warning: --modeac is currently ignored when --oversample is used;\n"
|
|
||||||
" no ModeA/C messages will be decoded.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
log_with_timestamp("%s %s starting up.", MODES_DUMP1090_VARIANT, MODES_DUMP1090_VERSION);
|
log_with_timestamp("%s %s starting up.", MODES_DUMP1090_VARIANT, MODES_DUMP1090_VERSION);
|
||||||
modesInit();
|
modesInit();
|
||||||
|
@ -1209,6 +1209,9 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
if (Modes.oversample) {
|
if (Modes.oversample) {
|
||||||
demodulate2400(buf);
|
demodulate2400(buf);
|
||||||
|
if (Modes.mode_ac) {
|
||||||
|
demodulate2400AC(buf);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
demodulate2000(buf);
|
demodulate2000(buf);
|
||||||
}
|
}
|
||||||
|
|
43
mode_ac.c
43
mode_ac.c
|
@ -75,28 +75,37 @@ int ModeAToModeC(unsigned int ModeA)
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
void decodeModeAMessage(struct modesMessage *mm, int ModeA)
|
void decodeModeAMessage(struct modesMessage *mm, int ModeA)
|
||||||
{
|
{
|
||||||
mm->msgtype = 32; // Valid Mode S DF's are DF-00 to DF-31.
|
mm->msgtype = 32; // Valid Mode S DF's are DF-00 to DF-31.
|
||||||
// so use 32 to indicate Mode A/C
|
// so use 32 to indicate Mode A/C
|
||||||
|
|
||||||
mm->msgbits = 16; // Fudge up a Mode S style data stream
|
mm->msgbits = 16; // Fudge up a Mode S style data stream
|
||||||
mm->msg[0] = (ModeA >> 8);
|
mm->msg[0] = mm->verbatim[0] = (ModeA >> 8);
|
||||||
mm->msg[1] = (ModeA);
|
mm->msg[1] = mm->verbatim[1] = (ModeA);
|
||||||
|
|
||||||
// Fudge an address based on Mode A (remove the Ident bit)
|
// Fudge an address based on Mode A (remove the Ident bit)
|
||||||
mm->addr = (ModeA & 0x0000FF7F) | MODES_NON_ICAO_ADDRESS;
|
mm->addr = (ModeA & 0x0000FF7F) | MODES_NON_ICAO_ADDRESS;
|
||||||
|
|
||||||
// Set the Identity field to ModeA
|
// Set the Identity field to ModeA
|
||||||
mm->modeA = ModeA & 0x7777;
|
mm->modeA = ModeA & 0x7777;
|
||||||
mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID;
|
mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID;
|
||||||
|
|
||||||
// Flag ident in flight status
|
// Flag ident in flight status
|
||||||
mm->fs = ModeA & 0x0080;
|
mm->fs = ModeA & 0x0080;
|
||||||
|
|
||||||
// Not much else we can tell from a Mode A/C reply.
|
// Decode an altitude if this looks like a possible mode C
|
||||||
// Just fudge up a few bits to keep other code happy
|
if (!mm->fs) {
|
||||||
mm->correctedbits = 0;
|
int modeC = ModeAToModeC(ModeA);
|
||||||
}
|
if (modeC >= -12) {
|
||||||
|
mm->altitude = modeC * 100;
|
||||||
|
mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not much else we can tell from a Mode A/C reply.
|
||||||
|
// Just fudge up a few bits to keep other code happy
|
||||||
|
mm->correctedbits = 0;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// ===================== Mode A/C detection and decoding ===================
|
// ===================== Mode A/C detection and decoding ===================
|
||||||
//
|
//
|
||||||
|
|
13
net_io.c
13
net_io.c
|
@ -676,12 +676,21 @@ static void send_sbs_heartbeat(struct net_service *service)
|
||||||
void modesQueueOutput(struct modesMessage *mm, struct aircraft *a) {
|
void modesQueueOutput(struct modesMessage *mm, struct aircraft *a) {
|
||||||
int is_mlat = ((mm->bFlags & MODES_ACFLAGS_FROM_MLAT) != 0);
|
int is_mlat = ((mm->bFlags & MODES_ACFLAGS_FROM_MLAT) != 0);
|
||||||
|
|
||||||
if (!is_mlat) {
|
if (!is_mlat && mm->correctedbits < 2) {
|
||||||
|
// Don't ever forward 2-bit-corrected messages via SBS output.
|
||||||
|
// Don't ever forward mlat messages via SBS output.
|
||||||
modesSendSBSOutput(mm, a);
|
modesSendSBSOutput(mm, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_mlat && (Modes.net_verbatim || mm->correctedbits < 2)) {
|
||||||
|
// Forward 2-bit-corrected messages via raw output only if --net-verbatim is set
|
||||||
|
// Don't ever forward mlat messages via raw output.
|
||||||
modesSendRawOutput(mm);
|
modesSendRawOutput(mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_mlat || Modes.forward_mlat) {
|
if ((!is_mlat || Modes.forward_mlat) && (Modes.net_verbatim || mm->correctedbits < 2)) {
|
||||||
|
// Forward 2-bit-corrected messages via beast output only if --net-verbatim is set
|
||||||
|
// Forward mlat messages via beast output only if --forward-mlat is set
|
||||||
modesSendBeastOutput(mm);
|
modesSendBeastOutput(mm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
track.c
6
track.c
|
@ -73,13 +73,9 @@ struct aircraft *trackCreateAircraft(struct modesMessage *mm) {
|
||||||
// set them once here during initialisation, and don't bother to set them every
|
// set them once here during initialisation, and don't bother to set them every
|
||||||
// time this ModeA/C is received again in the future
|
// time this ModeA/C is received again in the future
|
||||||
if (mm->msgtype == 32) {
|
if (mm->msgtype == 32) {
|
||||||
int modeC = ModeAToModeC(mm->modeA | mm->fs);
|
|
||||||
a->modeACflags = MODEAC_MSG_FLAG;
|
a->modeACflags = MODEAC_MSG_FLAG;
|
||||||
if (modeC < -12) {
|
if (!(mm->bFlags & MODES_ACFLAGS_ALTITUDE_VALID)) {
|
||||||
a->modeACflags |= MODEAC_MSG_MODEA_ONLY;
|
a->modeACflags |= MODEAC_MSG_MODEA_ONLY;
|
||||||
} else {
|
|
||||||
mm->altitude = modeC * 100;
|
|
||||||
mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue