From 047032ee46ef00d924dea0ee68b0f2726975fcd6 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 18 May 2014 13:29:40 +0900 Subject: [PATCH] Divecomputer download: try to offer only those devices that make sense If the user selects a Uemis divecomputer, don't show serial devices. If the user selects a serial divecomputer, don't show the Uemis filesystem. Signed-off-by: Dirk Hohndel --- android.cpp | 2 +- display.h | 7 +- linux.c | 104 ++++++++++++++-------------- macos.c | 55 ++++++++++----- qt-ui/downloadfromdivecomputer.cpp | 13 ++-- qt-ui/downloadfromdivecomputer.h | 2 +- windows.c | 106 +++++++++++++++++++---------- 7 files changed, 178 insertions(+), 111 deletions(-) diff --git a/android.cpp b/android.cpp index 15de9e65d..4dfaccb07 100644 --- a/android.cpp +++ b/android.cpp @@ -29,7 +29,7 @@ const char *system_default_filename(void) return strdup(system_default_filename.toUtf8().data()); } -int enumerate_devices (device_callback_t callback, void *userdata) +int enumerate_devices (device_callback_t callback, void *userdata, int dc_type) { /* FIXME: we need to enumerate in some other way on android */ /* qtserialport maybee? */ diff --git a/display.h b/display.h index 65820f075..08c63da04 100644 --- a/display.h +++ b/display.h @@ -55,7 +55,12 @@ extern int is_default_dive_computer_device(const char *); extern int is_default_dive_computer(const char *, const char *); typedef void (*device_callback_t)(const char *name, void *userdata); -int enumerate_devices(device_callback_t callback, void *userdata); + +#define DC_TYPE_SERIAL 1 +#define DC_TYPE_UEMIS 2 +#define DC_TYPE_OTHER 3 + +int enumerate_devices(device_callback_t callback, void *userdata, int dc_type); extern const char *default_dive_computer_vendor; extern const char *default_dive_computer_product; diff --git a/linux.c b/linux.c index 8c79a3f2d..c694d5d67 100644 --- a/linux.c +++ b/linux.c @@ -49,78 +49,80 @@ const char *system_default_filename(void) return buffer; } -int enumerate_devices(device_callback_t callback, void *userdata) +int enumerate_devices(device_callback_t callback, void *userdata, int dc_type) { int index = -1; DIR *dp = NULL; struct dirent *ep = NULL; size_t i; - const char *dirname = "/dev"; - const char *patterns[] = { - "ttyUSB*", - "ttyS*", - "ttyACM*", - "rfcomm*", - NULL - }; FILE *file; char *line = NULL; char *fname; size_t len; + if (dc_type != DC_TYPE_UEMIS) { + const char *dirname = "/dev"; + const char *patterns[] = { + "ttyUSB*", + "ttyS*", + "ttyACM*", + "rfcomm*", + NULL + }; - dp = opendir(dirname); - if (dp == NULL) { - return -1; - } + dp = opendir(dirname); + if (dp == NULL) { + return -1; + } - while ((ep = readdir(dp)) != NULL) { - for (i = 0; patterns[i] != NULL; ++i) { - if (fnmatch(patterns[i], ep->d_name, 0) == 0) { - char filename[1024]; - int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name); - if (n >= sizeof(filename)) { - closedir(dp); - return -1; + while ((ep = readdir(dp)) != NULL) { + for (i = 0; patterns[i] != NULL; ++i) { + if (fnmatch(patterns[i], ep->d_name, 0) == 0) { + char filename[1024]; + int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name); + if (n >= sizeof(filename)) { + closedir(dp); + return -1; + } + callback(filename, userdata); + if (is_default_dive_computer_device(filename)) + index = i; + break; } - callback(filename, userdata); - if (is_default_dive_computer_device(filename)) - index = i; - break; } } + closedir(dp); } - closedir(dp); + if (dc_type != DC_TYPE_SERIAL) { + file = fopen("/proc/mounts", "r"); + if (file == NULL) + return index; - file = fopen("/proc/mounts", "r"); - if (file == NULL) - return index; + while ((getline(&line, &len, file)) != -1) { + char *ptr = strstr(line, "UEMISSDA"); + if (ptr) { + char *end = ptr, *start = ptr; + while (start > line && *start != ' ') + start--; + if (*start == ' ') + start++; + while (*end != ' ' && *end != '\0') + end++; - while ((getline(&line, &len, file)) != -1) { - char *ptr = strstr(line, "UEMISSDA"); - if (ptr) { - char *end = ptr, *start = ptr; - while (start > line && *start != ' ') - start--; - if (*start == ' ') - start++; - while (*end != ' ' && *end != '\0') - end++; + *end = '\0'; + fname = strdup(start); - *end = '\0'; - fname = strdup(start); + callback(fname, userdata); - callback(fname, userdata); - - if (is_default_dive_computer_device(fname)) - index = i; - i++; - free((void *)fname); + if (is_default_dive_computer_device(fname)) + index = i; + i++; + free((void *)fname); + } } + + free(line); + fclose(file); } - - free(line); - fclose(file); - return index; } diff --git a/macos.c b/macos.c index 25d6fd73f..8b2f122dc 100644 --- a/macos.c +++ b/macos.c @@ -45,27 +45,52 @@ const char *system_default_filename(void) return buffer; } -int enumerate_devices(device_callback_t callback, void *userdata) +int enumerate_devices(device_callback_t callback, void *userdata, int dc_type) { int index = -1; DIR *dp = NULL; struct dirent *ep = NULL; size_t i; - const char *dirname = "/dev"; - const char *patterns[] = { - "tty.*", - "usbserial", - NULL - }; + if (dc_type != DC_TYPE_UEMIS) { + const char *dirname = "/dev"; + const char *patterns[] = { + "tty.*", + "usbserial", + NULL + }; - dp = opendir(dirname); - if (dp == NULL) { - return -1; + dp = opendir(dirname); + if (dp == NULL) { + return -1; + } + + while ((ep = readdir(dp)) != NULL) { + for (i = 0; patterns[i] != NULL; ++i) { + if (fnmatch(patterns[i], ep->d_name, 0) == 0) { + char filename[1024]; + int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name); + if (n >= sizeof(filename)) { + closedir(dp); + return -1; + } + callback(filename, userdata); + if (is_default_dive_computer_device(filename)) + index = i; + break; + } + } + } + closedir(dp); } + if (dc_type != DC_TYPE_SERIAL) { + const char *dirname = "/Volumes"; + dp = opendir(dirname); + if (dp == NULL) { + return -1; + } - while ((ep = readdir(dp)) != NULL) { - for (i = 0; patterns[i] != NULL; ++i) { - if (fnmatch(patterns[i], ep->d_name, 0) == 0) { + while ((ep = readdir(dp)) != NULL) { + if (fnmatch("UEMISSDA", ep->d_name, 0) == 0) { char filename[1024]; int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name); if (n >= sizeof(filename)) { @@ -78,10 +103,8 @@ int enumerate_devices(device_callback_t callback, void *userdata) break; } } + closedir(dp); } - // TODO: list UEMIS mount point from /proc/mounts - - closedir(dp); return index; } diff --git a/qt-ui/downloadfromdivecomputer.cpp b/qt-ui/downloadfromdivecomputer.cpp index 17c2a4eaa..0347932d5 100644 --- a/qt-ui/downloadfromdivecomputer.cpp +++ b/qt-ui/downloadfromdivecomputer.cpp @@ -56,7 +56,7 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : progress_bar_text = ""; - fill_device_list(); + fill_device_list(DC_TYPE_OTHER); fill_computer_list(); ui.chooseDumpFile->setEnabled(ui.dumpToFile->isChecked()); @@ -104,7 +104,7 @@ void DownloadFromDCWidget::updateState(states state) return; if (state == INITIAL) { - fill_device_list(); + fill_device_list(DC_TYPE_OTHER); ui.progressBar->hide(); markChildrenAsEnabled(); timer->stop(); @@ -176,6 +176,7 @@ void DownloadFromDCWidget::updateState(states state) void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor) { + int dcType = DC_TYPE_SERIAL; QAbstractItemModel *currentModel = ui.product->model(); if (!currentModel) return; @@ -183,6 +184,10 @@ void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor) productModel = new QStringListModel(productList[vendor]); ui.product->setModel(productModel); + if (vendor == QString("Uemis")) + dcType = DC_TYPE_UEMIS; + fill_device_list(dcType); + // Memleak - but deleting gives me a crash. //currentModel->deleteLater(); } @@ -429,11 +434,11 @@ static void fillDeviceList(const char *name, void *data) comboBox->addItem(name); } -void DownloadFromDCWidget::fill_device_list() +void DownloadFromDCWidget::fill_device_list(int dc_type) { int deviceIndex; ui.device->clear(); - deviceIndex = enumerate_devices(fillDeviceList, ui.device); + deviceIndex = enumerate_devices(fillDeviceList, ui.device, dc_type); if (deviceIndex >= 0) ui.device->setCurrentIndex(deviceIndex); } diff --git a/qt-ui/downloadfromdivecomputer.h b/qt-ui/downloadfromdivecomputer.h index e20ba3051..955322232 100644 --- a/qt-ui/downloadfromdivecomputer.h +++ b/qt-ui/downloadfromdivecomputer.h @@ -68,7 +68,7 @@ private: QStringListModel *vendorModel; QStringListModel *productModel; void fill_computer_list(); - void fill_device_list(); + void fill_device_list(int dc_type); QString logFile; QString dumpFile; QTimer *timer; diff --git a/windows.c b/windows.c index d2ba119ed..da7e9005b 100644 --- a/windows.c +++ b/windows.c @@ -36,56 +36,88 @@ const char *system_default_filename(void) return buffer; } -int enumerate_devices(device_callback_t callback, void *userdata) +int enumerate_devices(device_callback_t callback, void *userdata, int dc_type) { - // Open the registry key. - HKEY hKey; int index = -1; - LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey); - if (rc != ERROR_SUCCESS) { - return -1; - } - - // Get the number of values. - DWORD count = 0; - rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL); - if (rc != ERROR_SUCCESS) { - RegCloseKey(hKey); - return -1; - } DWORD i; - for (i = 0; i < count; ++i) { - // Get the value name, data and type. - char name[512], data[512]; - DWORD name_len = sizeof(name); - DWORD data_len = sizeof(data); - DWORD type = 0; - rc = RegEnumValue(hKey, i, name, &name_len, NULL, &type, (LPBYTE)data, &data_len); + if (dc_type != DC_TYPE_UEMIS) { + // Open the registry key. + HKEY hKey; + LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey); + if (rc != ERROR_SUCCESS) { + return -1; + } + + // Get the number of values. + DWORD count = 0; + rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL); if (rc != ERROR_SUCCESS) { RegCloseKey(hKey); return -1; } + for (i = 0; i < count; ++i) { + // Get the value name, data and type. + char name[512], data[512]; + DWORD name_len = sizeof(name); + DWORD data_len = sizeof(data); + DWORD type = 0; + rc = RegEnumValue(hKey, i, name, &name_len, NULL, &type, (LPBYTE)data, &data_len); + if (rc != ERROR_SUCCESS) { + RegCloseKey(hKey); + return -1; + } - // Ignore non-string values. - if (type != REG_SZ) - continue; + // Ignore non-string values. + if (type != REG_SZ) + continue; - // Prevent a possible buffer overflow. - if (data_len >= sizeof(data)) { - RegCloseKey(hKey); - return -1; + // Prevent a possible buffer overflow. + if (data_len >= sizeof(data)) { + RegCloseKey(hKey); + return -1; + } + + // Null terminate the string. + data[data_len] = 0; + + callback(data, userdata); + index++; + if (is_default_dive_computer_device(name)) + index = i; } - // Null terminate the string. - data[data_len] = 0; - - callback(data, userdata); - index++; - if (is_default_dive_computer_device(name)) - index = i; + RegCloseKey(hKey); } + if (dc_type != DC_TYPE_SERIAL) { + int i; + const int bufdef = 512; + const char *dlabels[] = {"UEMISSDA", NULL}; + char bufname[bufdef], bufval[bufdef], *p; + DWORD bufname_len; - RegCloseKey(hKey); + /* add drive letters that match labels */ + memset(bufname, 0, bufdef); + bufname_len = bufdef; + if (GetLogicalDriveStringsA(bufname_len, bufname)) { + p = bufname; + + while (*p) { + memset(bufval, 0, bufdef); + if (GetVolumeInformationA(p, bufval, bufdef, NULL, NULL, NULL, NULL, 0)) { + for (i = 0; dlabels[i] != NULL; i++) + if (!strcmp(bufval, dlabels[i])) { + char data[512]; + snprintf(data, sizeof(data), "%s (%s)", p, dlabels[i]); + callback(data, userdata); + if (is_default_dive_computer_device(p)) + index = i; + i++; + } + } + p = &p[strlen(p) + 1]; + } + } + } return index; }