Notice if we lose the RTLSDR device and reconnect.

Fix some of the more glaring pthread bugs.
This commit is contained in:
Oliver Jowett 2015-01-02 22:29:29 +00:00
parent 5dd1c39710
commit 07bc762055
3 changed files with 49 additions and 13 deletions

10
debian/changelog vendored
View file

@ -1,3 +1,13 @@
dump1090-mutability (1.08.2302.14+1mu-7) UNRELEASED; urgency=medium
* Notice if we lose the RTLSDR device, and try to reconnect when that happens.
This lets you unplug/replug the RTLSDR without dump1090 exiting, and also
lets dump1090 tolerate occasional USB glitches that make the dongle reset
itself.
* Fix some of the more glaring pthread bugs.
-- Oliver Jowett <oliver@mutability.co.uk> Fri, 02 Jan 2015 22:27:44 +0000
dump1090-mutability (1.08.2302.14+1mu-6) unstable; urgency=medium dump1090-mutability (1.08.2302.14+1mu-6) unstable; urgency=medium
* Add support for LOG_DECODED_MESSAGES option to log all messages (disables --quiet). * Add support for LOG_DECODED_MESSAGES option to log all messages (disables --quiet).

View file

@ -200,28 +200,33 @@ void modesInit(void) {
// //
// =============================== RTLSDR handling ========================== // =============================== RTLSDR handling ==========================
// //
void modesInitRTLSDR(void) { int modesInitRTLSDR(void) {
int j; int j;
int device_count; int device_count, dev_index = 0;
char vendor[256], product[256], serial[256]; char vendor[256], product[256], serial[256];
if (Modes.dev_name) {
if ( (dev_index = verbose_device_search(Modes.dev_name)) < 0 )
return -1;
}
device_count = rtlsdr_get_device_count(); device_count = rtlsdr_get_device_count();
if (!device_count) { if (!device_count) {
fprintf(stderr, "No supported RTLSDR devices found.\n"); fprintf(stderr, "No supported RTLSDR devices found.\n");
exit(1); return -1;
} }
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); rtlsdr_get_device_usb_strings(j, vendor, product, serial);
fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial, fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial,
(j == Modes.dev_index) ? "(currently selected)" : ""); (j == dev_index) ? "(currently selected)" : "");
} }
if (rtlsdr_open(&Modes.dev, Modes.dev_index) < 0) { if (rtlsdr_open(&Modes.dev, dev_index) < 0) {
fprintf(stderr, "Error opening the RTLSDR device: %s\n", fprintf(stderr, "Error opening the RTLSDR device: %s\n",
strerror(errno)); strerror(errno));
exit(1); return -1;
} }
// Set gain, frequency, sample rate, and reset the device // Set gain, frequency, sample rate, and reset the device
@ -357,19 +362,36 @@ void readDataFromFile(void) {
// We read data using a thread, so the main thread only handles decoding // We read data using a thread, so the main thread only handles decoding
// without caring about data acquisition // without caring about data acquisition
// //
void *readerThreadEntryPoint(void *arg) { void *readerThreadEntryPoint(void *arg) {
MODES_NOTUSED(arg); MODES_NOTUSED(arg);
if (Modes.filename == NULL) { if (Modes.filename == NULL) {
rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL, while (!Modes.exit) {
rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL,
MODES_ASYNC_BUF_NUMBER, MODES_ASYNC_BUF_NUMBER,
MODES_ASYNC_BUF_SIZE); MODES_ASYNC_BUF_SIZE);
if (!Modes.exit) {
fprintf(stderr, "Warning: lost the connection to the RTLSDR device.\n");
rtlsdr_close(Modes.dev);
do {
sleep(5);
fprintf(stderr, "Trying to reconnect to the RTLSDR device..\n");
} while (!Modes.exit && modesInitRTLSDR() < 0);
}
}
} else { } else {
readDataFromFile(); readDataFromFile();
} }
// Signal to the other thread that new data is ready - dummy really so threads don't mutually lock
// Wake the main thread (if it's still waiting)
pthread_mutex_lock(&Modes.data_mutex);
Modes.exit = 1;
pthread_cond_signal(&Modes.data_cond); pthread_cond_signal(&Modes.data_cond);
pthread_mutex_unlock(&Modes.data_mutex); pthread_mutex_unlock(&Modes.data_mutex);
#ifndef _WIN32 #ifndef _WIN32
pthread_exit(NULL); pthread_exit(NULL);
#else #else
@ -721,7 +743,7 @@ int main(int argc, char **argv) {
int more = j+1 < argc; // There are more arguments int more = j+1 < argc; // There are more arguments
if (!strcmp(argv[j],"--device-index") && more) { if (!strcmp(argv[j],"--device-index") && more) {
Modes.dev_index = verbose_device_search(argv[++j]); Modes.dev_name = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--gain") && more) { } else if (!strcmp(argv[j],"--gain") && more) {
Modes.gain = (int) (atof(argv[++j])*10); // Gain is in tens of DBs Modes.gain = (int) (atof(argv[++j])*10); // Gain is in tens of DBs
} else if (!strcmp(argv[j],"--enable-agc")) { } else if (!strcmp(argv[j],"--enable-agc")) {
@ -879,7 +901,9 @@ int main(int argc, char **argv) {
if (Modes.net_only) { if (Modes.net_only) {
fprintf(stderr,"Net-only mode, no RTL device or file open.\n"); fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
} else if (Modes.filename == NULL) { } else if (Modes.filename == NULL) {
modesInitRTLSDR(); if (modesInitRTLSDR() < 0) {
exit(1);
}
} else { } else {
if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') { if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
Modes.fd = STDIN_FILENO; Modes.fd = STDIN_FILENO;
@ -991,9 +1015,11 @@ int main(int argc, char **argv) {
rtlsdr_cancel_async(Modes.dev); // Cancel rtlsdr_read_async will cause data input thread to terminate cleanly rtlsdr_cancel_async(Modes.dev); // Cancel rtlsdr_read_async will cause data input thread to terminate cleanly
rtlsdr_close(Modes.dev); rtlsdr_close(Modes.dev);
} }
pthread_cond_destroy(&Modes.data_cond); // Thread cleanup
pthread_mutex_destroy(&Modes.data_mutex);
pthread_join(Modes.reader_thread,NULL); // Wait on reader thread exit pthread_join(Modes.reader_thread,NULL); // Wait on reader thread exit
pthread_cond_destroy(&Modes.data_cond); // Thread cleanup - only after the reader thread is dead!
pthread_mutex_destroy(&Modes.data_mutex);
#ifndef _WIN32 #ifndef _WIN32
pthread_exit(0); pthread_exit(0);
#else #else

View file

@ -311,7 +311,7 @@ struct { // Internal state
int exit; // Exit from the main loop when true int exit; // Exit from the main loop when true
// RTLSDR // RTLSDR
int dev_index; char * dev_name;
int gain; int gain;
int enable_agc; int enable_agc;
rtlsdr_dev_t *dev; rtlsdr_dev_t *dev;