Merge branch 'master' into latlon
This commit is contained in:
commit
ffd083c2e6
|
|
@ -12,6 +12,7 @@ dump1090-mutability (1.15~dev) UNRELEASED; urgency=medium
|
||||||
received data clobbering old data under CPU overload.
|
received data clobbering old data under CPU overload.
|
||||||
* Fix endian issues affecting big-endian hosts in Beast input/output
|
* Fix endian issues affecting big-endian hosts in Beast input/output
|
||||||
and avrmlat output. (github issue #44)
|
and avrmlat output. (github issue #44)
|
||||||
|
* Fix queueing/resending very old Mode A/C messages (github issue #47)
|
||||||
|
|
||||||
-- Oliver Jowett <oliver@mutability.co.uk> Thu, 19 Feb 2015 22:39:19 +0000
|
-- Oliver Jowett <oliver@mutability.co.uk> Thu, 19 Feb 2015 22:39:19 +0000
|
||||||
|
|
||||||
|
|
|
||||||
87
dump1090.c
87
dump1090.c
|
|
@ -50,6 +50,7 @@
|
||||||
#include "dump1090.h"
|
#include "dump1090.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <endian.h>
|
||||||
|
|
||||||
static int verbose_device_search(char *s);
|
static int verbose_device_search(char *s);
|
||||||
|
|
||||||
|
|
@ -494,17 +495,37 @@ void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) {
|
||||||
void readDataFromFile(void) {
|
void readDataFromFile(void) {
|
||||||
int eof = 0;
|
int eof = 0;
|
||||||
struct timespec next_buffer_delivery;
|
struct timespec next_buffer_delivery;
|
||||||
|
void *readbuf;
|
||||||
|
int bytes_per_sample = 0;
|
||||||
|
|
||||||
|
switch (Modes.file_format) {
|
||||||
|
case INPUT_UC8:
|
||||||
|
bytes_per_sample = 2;
|
||||||
|
break;
|
||||||
|
case INPUT_SC16:
|
||||||
|
case INPUT_SC16Q11:
|
||||||
|
bytes_per_sample = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(readbuf = malloc(MODES_MAG_BUF_SAMPLES * bytes_per_sample))) {
|
||||||
|
fprintf(stderr, "failed to allocate read buffer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &next_buffer_delivery);
|
clock_gettime(CLOCK_MONOTONIC, &next_buffer_delivery);
|
||||||
|
|
||||||
pthread_mutex_lock(&Modes.data_mutex);
|
pthread_mutex_lock(&Modes.data_mutex);
|
||||||
while (!Modes.exit && !eof) {
|
while (!Modes.exit && !eof) {
|
||||||
ssize_t nread, toread;
|
ssize_t nread, toread;
|
||||||
|
|
||||||
void *r;
|
void *r;
|
||||||
uint16_t *p;
|
uint16_t *in, *out;
|
||||||
|
|
||||||
struct mag_buf *outbuf, *lastbuf;
|
struct mag_buf *outbuf, *lastbuf;
|
||||||
unsigned next_free_buffer;
|
unsigned next_free_buffer;
|
||||||
unsigned slen;
|
unsigned slen;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
next_free_buffer = (Modes.first_free_buffer + 1) % MODES_MAG_BUFFERS;
|
next_free_buffer = (Modes.first_free_buffer + 1) % MODES_MAG_BUFFERS;
|
||||||
if (next_free_buffer == Modes.first_filled_buffer) {
|
if (next_free_buffer == Modes.first_filled_buffer) {
|
||||||
|
|
@ -528,15 +549,15 @@ void readDataFromFile(void) {
|
||||||
if (lastbuf->length >= Modes.trailing_samples) {
|
if (lastbuf->length >= Modes.trailing_samples) {
|
||||||
memcpy(outbuf->data, lastbuf->data + lastbuf->length - Modes.trailing_samples, Modes.trailing_samples * sizeof(uint16_t));
|
memcpy(outbuf->data, lastbuf->data + lastbuf->length - Modes.trailing_samples, Modes.trailing_samples * sizeof(uint16_t));
|
||||||
} else {
|
} else {
|
||||||
memset(outbuf->data, 127, Modes.trailing_samples * sizeof(uint16_t));
|
memset(outbuf->data, 0, Modes.trailing_samples * sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the system time for the start of this block
|
// Get the system time for the start of this block
|
||||||
clock_gettime(CLOCK_REALTIME, &outbuf->sysTimestamp);
|
clock_gettime(CLOCK_REALTIME, &outbuf->sysTimestamp);
|
||||||
|
|
||||||
toread = MODES_RTL_BUF_SIZE;
|
toread = MODES_MAG_BUF_SAMPLES * bytes_per_sample;
|
||||||
r = (void *) (outbuf->data + Modes.trailing_samples);
|
r = readbuf;
|
||||||
while(toread) {
|
while (toread) {
|
||||||
nread = read(Modes.fd, r, toread);
|
nread = read(Modes.fd, r, toread);
|
||||||
if (nread <= 0) {
|
if (nread <= 0) {
|
||||||
// Done.
|
// Done.
|
||||||
|
|
@ -547,13 +568,44 @@ void readDataFromFile(void) {
|
||||||
toread -= nread;
|
toread -= nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
slen = outbuf->length = (MODES_RTL_BUF_SIZE - toread) / 2;
|
slen = outbuf->length = MODES_MAG_BUF_SAMPLES - toread/bytes_per_sample;
|
||||||
|
|
||||||
// Convert the new data
|
// Convert the new data
|
||||||
p = (uint16_t*) (outbuf->data + Modes.trailing_samples);
|
out = outbuf->data + Modes.trailing_samples;
|
||||||
while (slen-- > 0) {
|
in = (uint16_t*)readbuf;
|
||||||
*p = Modes.maglut[*p];
|
switch (Modes.file_format) {
|
||||||
++p;
|
case INPUT_UC8:
|
||||||
|
for (i = 0; i < slen; ++i)
|
||||||
|
*out++ = Modes.maglut[*in++];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_SC16:
|
||||||
|
for (i = 0; i < slen; ++i) {
|
||||||
|
int16_t I, Q;
|
||||||
|
float mag;
|
||||||
|
|
||||||
|
I = (int16_t)le16toh(*in++);
|
||||||
|
Q = (int16_t)le16toh(*in++);
|
||||||
|
mag = sqrtf(I*I + Q*Q) * (65536.0 / 32768.0);
|
||||||
|
if (mag > 65535)
|
||||||
|
mag = 65535;
|
||||||
|
*out++ = (uint16_t)mag;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_SC16Q11:
|
||||||
|
for (i = 0; i < slen; ++i) {
|
||||||
|
int16_t I, Q;
|
||||||
|
float mag;
|
||||||
|
|
||||||
|
I = (int16_t)le16toh(*in++);
|
||||||
|
Q = (int16_t)le16toh(*in++);
|
||||||
|
mag = sqrtf(I*I + Q*Q) * (65536.0 / 2048.0);
|
||||||
|
if (mag > 65535)
|
||||||
|
mag = 65535;
|
||||||
|
*out++ = (uint16_t)mag;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Modes.interactive) {
|
if (Modes.interactive) {
|
||||||
|
|
@ -575,6 +627,8 @@ void readDataFromFile(void) {
|
||||||
pthread_cond_signal(&Modes.data_cond);
|
pthread_cond_signal(&Modes.data_cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(readbuf);
|
||||||
|
|
||||||
// Wait for the main thread to consume all data
|
// Wait for the main thread to consume all data
|
||||||
while (!Modes.exit && Modes.first_filled_buffer != Modes.first_free_buffer)
|
while (!Modes.exit && Modes.first_filled_buffer != Modes.first_free_buffer)
|
||||||
pthread_cond_wait(&Modes.data_cond, &Modes.data_mutex);
|
pthread_cond_wait(&Modes.data_cond, &Modes.data_mutex);
|
||||||
|
|
@ -917,6 +971,19 @@ int main(int argc, char **argv) {
|
||||||
Modes.freq = (int) strtoll(argv[++j],NULL,10);
|
Modes.freq = (int) strtoll(argv[++j],NULL,10);
|
||||||
} else if (!strcmp(argv[j],"--ifile") && more) {
|
} else if (!strcmp(argv[j],"--ifile") && more) {
|
||||||
Modes.filename = strdup(argv[++j]);
|
Modes.filename = strdup(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--iformat") && more) {
|
||||||
|
++j;
|
||||||
|
if (!strcasecmp(argv[j], "uc8")) {
|
||||||
|
Modes.file_format = INPUT_UC8;
|
||||||
|
} else if (!strcasecmp(argv[j], "sc16")) {
|
||||||
|
Modes.file_format = INPUT_SC16;
|
||||||
|
} else if (!strcasecmp(argv[j], "sc16q11")) {
|
||||||
|
Modes.file_format = INPUT_SC16Q11;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Input format '%s' not understood (supported values: UC8, SC16, SC16Q11)\n",
|
||||||
|
argv[j]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
} else if (!strcmp(argv[j],"--fix")) {
|
} else if (!strcmp(argv[j],"--fix")) {
|
||||||
Modes.nfix_crc = 1;
|
Modes.nfix_crc = 1;
|
||||||
} else if (!strcmp(argv[j],"--no-fix")) {
|
} else if (!strcmp(argv[j],"--no-fix")) {
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,8 @@ struct mag_buf {
|
||||||
uint32_t dropped; // Number of dropped samples preceding this buffer
|
uint32_t dropped; // Number of dropped samples preceding this buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum { INPUT_UC8=0, INPUT_SC16, INPUT_SC16Q11 } input_format_t;
|
||||||
|
|
||||||
// Program global state
|
// Program global state
|
||||||
struct { // Internal state
|
struct { // Internal state
|
||||||
pthread_t reader_thread;
|
pthread_t reader_thread;
|
||||||
|
|
@ -265,6 +267,7 @@ struct { // Internal state
|
||||||
unsigned trailing_samples; // extra trailing samples in magnitude buffers
|
unsigned trailing_samples; // extra trailing samples in magnitude buffers
|
||||||
|
|
||||||
int fd; // --ifile option file descriptor
|
int fd; // --ifile option file descriptor
|
||||||
|
input_format_t file_format; // --iformat option
|
||||||
uint16_t *maglut; // I/Q -> Magnitude lookup table
|
uint16_t *maglut; // I/Q -> Magnitude lookup table
|
||||||
uint16_t *log10lut; // Magnitude -> log10 lookup table
|
uint16_t *log10lut; // Magnitude -> log10 lookup table
|
||||||
int exit; // Exit from the main loop when true
|
int exit; // Exit from the main loop when true
|
||||||
|
|
|
||||||
|
|
@ -68,16 +68,27 @@ void icaoFilterInit()
|
||||||
|
|
||||||
void icaoFilterAdd(uint32_t addr)
|
void icaoFilterAdd(uint32_t addr)
|
||||||
{
|
{
|
||||||
uint32_t h = icaoHash(addr);
|
uint32_t h, h0;
|
||||||
while (icao_filter_active[h] && icao_filter_active[h] != addr)
|
h0 = h = icaoHash(addr);
|
||||||
|
while (icao_filter_active[h] && icao_filter_active[h] != addr) {
|
||||||
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
||||||
|
if (h == h0) {
|
||||||
|
fprintf(stderr, "ICAO hash table full, increase ICAO_FILTER_SIZE\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!icao_filter_active[h])
|
if (!icao_filter_active[h])
|
||||||
icao_filter_active[h] = addr;
|
icao_filter_active[h] = addr;
|
||||||
|
|
||||||
// also add with a zeroed top byte, for handling DF20/21 with Data Parity
|
// also add with a zeroed top byte, for handling DF20/21 with Data Parity
|
||||||
h = icaoHash(addr & 0x00ffff);
|
h0 = h = icaoHash(addr & 0x00ffff);
|
||||||
while (icao_filter_active[h] && (icao_filter_active[h] & 0x00ffff) != (addr & 0x00ffff))
|
while (icao_filter_active[h] && (icao_filter_active[h] & 0x00ffff) != (addr & 0x00ffff)) {
|
||||||
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
||||||
|
if (h == h0) {
|
||||||
|
fprintf(stderr, "ICAO hash table full, increase ICAO_FILTER_SIZE\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!icao_filter_active[h])
|
if (!icao_filter_active[h])
|
||||||
icao_filter_active[h] = addr;
|
icao_filter_active[h] = addr;
|
||||||
}
|
}
|
||||||
|
|
@ -87,15 +98,21 @@ int icaoFilterTest(uint32_t addr)
|
||||||
uint32_t h, h0;
|
uint32_t h, h0;
|
||||||
|
|
||||||
h0 = h = icaoHash(addr);
|
h0 = h = icaoHash(addr);
|
||||||
while (icao_filter_a[h] && icao_filter_a[h] != addr)
|
while (icao_filter_a[h] && icao_filter_a[h] != addr) {
|
||||||
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
||||||
if (icao_filter_a[h])
|
if (h == h0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (icao_filter_a[h] == addr)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
h = h0;
|
h = h0;
|
||||||
while (icao_filter_b[h] && icao_filter_b[h] != addr)
|
while (icao_filter_b[h] && icao_filter_b[h] != addr) {
|
||||||
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
||||||
if (icao_filter_b[h])
|
if (h == h0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (icao_filter_b[h] == addr)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -107,15 +124,21 @@ uint32_t icaoFilterTestFuzzy(uint32_t partial)
|
||||||
|
|
||||||
partial &= 0x00ffff;
|
partial &= 0x00ffff;
|
||||||
h0 = h = icaoHash(partial);
|
h0 = h = icaoHash(partial);
|
||||||
while (icao_filter_a[h] && (icao_filter_a[h] & 0x00ffff) != partial)
|
while (icao_filter_a[h] && (icao_filter_a[h] & 0x00ffff) != partial) {
|
||||||
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
||||||
if (icao_filter_a[h])
|
if (h == h0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((icao_filter_a[h] & 0x00ffff) == partial)
|
||||||
return icao_filter_a[h];
|
return icao_filter_a[h];
|
||||||
|
|
||||||
h = h0;
|
h = h0;
|
||||||
while (icao_filter_b[h] && (icao_filter_b[h] & 0x00ffff) != partial)
|
while (icao_filter_b[h] && (icao_filter_b[h] & 0x00ffff) != partial) {
|
||||||
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
h = (h+1) & (ICAO_FILTER_SIZE-1);
|
||||||
if (icao_filter_b[h])
|
if (h == h0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((icao_filter_b[h] & 0x00ffff) == partial)
|
||||||
return icao_filter_b[h];
|
return icao_filter_b[h];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
9
mode_s.c
9
mode_s.c
|
|
@ -1221,18 +1221,17 @@ void useModesMessage(struct modesMessage *mm) {
|
||||||
// Otherwise, apply a sanity-check filter and only
|
// Otherwise, apply a sanity-check filter and only
|
||||||
// forward messages when we have seen two of them.
|
// forward messages when we have seen two of them.
|
||||||
|
|
||||||
// TODO: buffer the original message and forward it when we
|
|
||||||
// see a second message?
|
|
||||||
|
|
||||||
if (Modes.net) {
|
if (Modes.net) {
|
||||||
if (Modes.net_verbatim || a->messages > 1) {
|
if (Modes.net_verbatim || mm->msgtype == 32) {
|
||||||
|
// Unconditionally send
|
||||||
|
modesQueueOutput(mm);
|
||||||
|
} else if (a->messages > 1) {
|
||||||
// If this is the second message, and we
|
// If this is the second message, and we
|
||||||
// squelched the first message, then re-emit the
|
// squelched the first message, then re-emit the
|
||||||
// first message now.
|
// first message now.
|
||||||
if (!Modes.net_verbatim && a->messages == 2) {
|
if (!Modes.net_verbatim && a->messages == 2) {
|
||||||
modesQueueOutput(&a->first_message);
|
modesQueueOutput(&a->first_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
modesQueueOutput(mm);
|
modesQueueOutput(mm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
track.c
5
track.c
|
|
@ -636,10 +636,11 @@ static void trackRemoveStaleAircraft(uint64_t now)
|
||||||
} else {
|
} else {
|
||||||
prev->next = a->next; free(a); a = prev->next;
|
prev->next = a->next; free(a); a = prev->next;
|
||||||
}
|
}
|
||||||
} else if ((a->bFlags & MODES_ACFLAGS_LATLON_VALID) && (now - a->seenLatLon) > TRACK_AIRCRAFT_POSITION_TTL) {
|
} else {
|
||||||
|
if ((a->bFlags & MODES_ACFLAGS_LATLON_VALID) && (now - a->seenLatLon) > TRACK_AIRCRAFT_POSITION_TTL) {
|
||||||
/* Position is too old and no longer valid */
|
/* Position is too old and no longer valid */
|
||||||
a->bFlags &= ~(MODES_ACFLAGS_LATLON_VALID | MODES_ACFLAGS_LATLON_REL_OK);
|
a->bFlags &= ~(MODES_ACFLAGS_LATLON_VALID | MODES_ACFLAGS_LATLON_REL_OK);
|
||||||
} else {
|
}
|
||||||
prev = a; a = a->next;
|
prev = a; a = a->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue