diff --git a/contrib/msvc/libdivecomputer.vcxproj b/contrib/msvc/libdivecomputer.vcxproj
index 7f1335c..704ef8b 100644
--- a/contrib/msvc/libdivecomputer.vcxproj
+++ b/contrib/msvc/libdivecomputer.vcxproj
@@ -331,7 +331,6 @@
-
diff --git a/include/libdivecomputer/descriptor.h b/include/libdivecomputer/descriptor.h
index a2b4495..bdd8c73 100644
--- a/include/libdivecomputer/descriptor.h
+++ b/include/libdivecomputer/descriptor.h
@@ -29,29 +29,96 @@
extern "C" {
#endif /* __cplusplus */
+/**
+ * Opaque object representing a supported dive computer.
+ */
typedef struct dc_descriptor_t dc_descriptor_t;
+/**
+ * Create an iterator to enumerate the supported dive computers.
+ *
+ * @param[out] iterator A location to store the iterator.
+ * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code
+ * on failure.
+ */
dc_status_t
dc_descriptor_iterator (dc_iterator_t **iterator);
+/**
+ * Free the device descriptor.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ */
void
dc_descriptor_free (dc_descriptor_t *descriptor);
+/**
+ * Get the vendor name of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The vendor name of the dive computer on success, or NULL on failure.
+ */
const char *
dc_descriptor_get_vendor (dc_descriptor_t *descriptor);
+/**
+ * Get the product name of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The product name of the dive computer on success, or NULL on
+ * failure.
+ */
const char *
dc_descriptor_get_product (dc_descriptor_t *descriptor);
+/**
+ * Get the family type of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The family type of the dive computer on success, or DC_FAMILY_NULL
+ * on failure.
+ */
dc_family_t
dc_descriptor_get_type (dc_descriptor_t *descriptor);
+/**
+ * Get the model number of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The model number of the dive computer on success, or zero on
+ * failure.
+ */
unsigned int
dc_descriptor_get_model (dc_descriptor_t *descriptor);
+/**
+ * Get all transports supported by the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns A bitmask with all the transports supported by the dive computer on
+ * success, or DC_TRANSPORT_NONE on failure.
+ */
unsigned int
dc_descriptor_get_transports (dc_descriptor_t *descriptor);
+/**
+ * Check if a low-level I/O device matches a supported dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @param[in] transport The transport type of the I/O device.
+ * @param[in] userdata A pointer to a transport specific data structure:
+ * - DC_TRANSPORT_SERIAL: Name of the device node (string)
+ * - DC_TRANSPORT_USB: USB VID/PID (#dc_usb_desc_t)
+ * - DC_TRANSPORT_USBHID: USB VID/PID (#dc_usbhid_desc_t)
+ * - DC_TRANSPORT_IRDA: IrDA device name (string)
+ * - DC_TRANSPORT_BLUETOOTH: Bluetooth device name (string)
+ * - DC_TRANSPORT_BLE: Bluetooth device name (string)
+ * @returns Non-zero if the device matches a supported dive computer, or zero if
+ * there is no match.
+ */
+int
+dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/libdivecomputer/usb.h b/include/libdivecomputer/usb.h
index 6d13813..82e5881 100644
--- a/include/libdivecomputer/usb.h
+++ b/include/libdivecomputer/usb.h
@@ -86,6 +86,14 @@ typedef enum dc_usb_recipient_t {
DC_USB_RECIPIENT_OTHER = 0x03,
} dc_usb_recipient_t;
+/**
+ * USB device descriptor.
+ */
+typedef struct dc_usb_desc_t {
+ unsigned short vid;
+ unsigned short pid;
+} dc_usb_desc_t;
+
/**
* Opaque object representing a USB device.
*/
diff --git a/include/libdivecomputer/usbhid.h b/include/libdivecomputer/usbhid.h
index f1c542a..245adf0 100644
--- a/include/libdivecomputer/usbhid.h
+++ b/include/libdivecomputer/usbhid.h
@@ -32,6 +32,14 @@
extern "C" {
#endif /* __cplusplus */
+/**
+ * USB HID device descriptor.
+ */
+typedef struct dc_usbhid_desc_t {
+ unsigned short vid;
+ unsigned short pid;
+} dc_usbhid_desc_t;
+
/**
* Opaque object representing a USB HID device.
*/
diff --git a/src/Makefile.am b/src/Makefile.am
index de59dd6..be3f2e3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,7 +16,7 @@ endif
libdivecomputer_la_SOURCES = \
version.c \
- descriptor-private.h descriptor.c \
+ descriptor.c \
iostream-private.h iostream.c \
iterator-private.h iterator.c \
common-private.h common.c \
diff --git a/src/bluetooth.c b/src/bluetooth.c
index aa5f05a..309953c 100644
--- a/src/bluetooth.c
+++ b/src/bluetooth.c
@@ -51,7 +51,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "platform.h"
#ifdef _WIN32
@@ -455,7 +454,7 @@ dc_bluetooth_iterator_next (dc_iterator_t *abstract, void *out)
INFO (abstract->context, "Discover: address=" DC_ADDRESS_FORMAT ", name=%s",
address, name ? name : "");
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_BLUETOOTH, name, NULL)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_BLUETOOTH, name)) {
continue;
}
diff --git a/src/descriptor-private.h b/src/descriptor-private.h
deleted file mode 100644
index d829422..0000000
--- a/src/descriptor-private.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * libdivecomputer
- *
- * Copyright (C) 2017 Jef Driesen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#ifndef DC_DESCRIPTOR_PRIVATE_H
-#define DC_DESCRIPTOR_PRIVATE_H
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-typedef struct dc_usb_desc_t {
- unsigned short vid;
- unsigned short pid;
-} dc_usb_desc_t;
-
-typedef struct dc_usb_params_t {
- unsigned int interface;
- unsigned char endpoint_in;
- unsigned char endpoint_out;
-} dc_usb_params_t;
-
-int
-dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* DC_DESCRIPTOR_PRIVATE_H */
diff --git a/src/descriptor.c b/src/descriptor.c
index 794fd1d..77d55f6 100644
--- a/src/descriptor.c
+++ b/src/descriptor.c
@@ -23,7 +23,10 @@
#include
#include
-#include "descriptor-private.h"
+#include
+#include
+#include
+
#include "iterator-private.h"
#include "platform.h"
@@ -36,36 +39,26 @@
values, \
C_ARRAY_SIZE(values) - isnullterminated, \
C_ARRAY_ITEMSIZE(values), \
- match, \
- NULL, NULL, 0)
-
-#define DC_FILTER_INTERNAL_WITH_PARAMS(key, values, isnullterminated, match, params_dst, params_src) \
- dc_filter_internal( \
- key, \
- values, \
- C_ARRAY_SIZE(values) - isnullterminated, \
- C_ARRAY_ITEMSIZE(values), \
- match, \
- params_dst, params_src, sizeof *(params_src))
+ match)
typedef int (*dc_match_t)(const void *, const void *);
-typedef int (*dc_filter_t) (dc_transport_t transport, const void *userdata, void *params);
+typedef int (*dc_filter_t) (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
-static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_suunto (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_shearwater (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_hw (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_mares (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_divesystem (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_oceanic (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_mclean (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_atomic (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_deepsix (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_deepblu (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_oceans (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_divesoft (dc_transport_t transport, const void *userdata, void *params);
+static int dc_filter_uwatec (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_suunto (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_shearwater (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_hw (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_tecdiving (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_mares (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_divesystem (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_oceanic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_mclean (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_atomic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_deepsix (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_deepblu (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item);
@@ -506,6 +499,15 @@ dc_match_usb (const void *key, const void *value)
return k->vid == v->vid && k->pid == v->pid;
}
+static int
+dc_match_usbhid (const void *key, const void *value)
+{
+ const dc_usbhid_desc_t *k = (const dc_usbhid_desc_t *) key;
+ const dc_usbhid_desc_t *v = (const dc_usbhid_desc_t *) value;
+
+ return k->vid == v->vid && k->pid == v->pid;
+}
+
static int
dc_match_number_with_prefix (const void *key, const void *value)
{
@@ -546,16 +548,13 @@ dc_match_oceanic (const void *key, const void *value)
}
static int
-dc_filter_internal (const void *key, const void *values, size_t count, size_t size, dc_match_t match, void *params_dst, const void *params_src, size_t params_size)
+dc_filter_internal (const void *key, const void *values, size_t count, size_t size, dc_match_t match)
{
if (key == NULL)
return 1;
for (size_t i = 0; i < count; ++i) {
if (match (key, (const unsigned char *) values + i * size)) {
- if (params_src && params_dst) {
- memcpy (params_dst, params_src, params_size);
- }
return 1;
}
}
@@ -570,7 +569,8 @@ static const char * const rfcomm[] = {
NULL
};
-static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_uwatec (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const irda[] = {
"Aladin Smart Com",
@@ -581,7 +581,7 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, voi
"UWATEC Galileo",
"UWATEC Galileo Sol",
};
- static const dc_usb_desc_t usbhid[] = {
+ static const dc_usbhid_desc_t usbhid[] = {
{0x2e6c, 0x3201}, // G2, G2 TEK
{0x2e6c, 0x3211}, // G2 Console
{0x2e6c, 0x4201}, // G2 HUD
@@ -599,7 +599,7 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, voi
if (transport == DC_TRANSPORT_IRDA) {
return DC_FILTER_INTERNAL (userdata, irda, 0, dc_match_name);
} else if (transport == DC_TRANSPORT_USBHID) {
- return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usb);
+ return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usbhid);
} else if (transport == DC_TRANSPORT_BLE) {
return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name);
}
@@ -607,9 +607,10 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, voi
return 1;
}
-static int dc_filter_suunto (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_suunto (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
- static const dc_usb_desc_t usbhid[] = {
+ static const dc_usbhid_desc_t usbhid[] = {
{0x1493, 0x0030}, // Eon Steel
{0x1493, 0x0033}, // Eon Core
{0x1493, 0x0035}, // D5
@@ -623,7 +624,7 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata, voi
};
if (transport == DC_TRANSPORT_USBHID) {
- return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usb);
+ return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usbhid);
} else if (transport == DC_TRANSPORT_BLE) {
return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_prefix);
}
@@ -631,7 +632,8 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata, voi
return 1;
}
-static int dc_filter_hw (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_hw (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"OSTC",
@@ -647,7 +649,8 @@ static int dc_filter_hw (dc_transport_t transport, const void *userdata, void *p
return 1;
}
-static int dc_filter_shearwater (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_shearwater (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"Predator",
@@ -670,7 +673,8 @@ static int dc_filter_shearwater (dc_transport_t transport, const void *userdata,
return 1;
}
-static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_tecdiving (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"DiveComputer",
@@ -685,7 +689,8 @@ static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata,
return 1;
}
-static int dc_filter_mares (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_mares (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"Mares bluelink pro",
@@ -699,7 +704,8 @@ static int dc_filter_mares (dc_transport_t transport, const void *userdata, void
return 1;
}
-static int dc_filter_divesystem (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_divesystem (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"DS",
@@ -714,7 +720,8 @@ static int dc_filter_divesystem (dc_transport_t transport, const void *userdata,
return 1;
}
-static int dc_filter_oceanic (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_oceanic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const unsigned int model[] = {
0x4552, // Oceanic Pro Plus X
@@ -741,7 +748,8 @@ static int dc_filter_oceanic (dc_transport_t transport, const void *userdata, vo
return 1;
}
-static int dc_filter_mclean(dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_mclean(dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"McLean Extreme",
@@ -756,24 +764,22 @@ static int dc_filter_mclean(dc_transport_t transport, const void *userdata, void
return 1;
}
-static int dc_filter_atomic (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_atomic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const dc_usb_desc_t usb[] = {
{0x0471, 0x0888}, // Atomic Aquatics Cobalt
};
- static const dc_usb_params_t usb_params = {
- 0, 0x82, 0x02
- };
-
if (transport == DC_TRANSPORT_USB) {
- return DC_FILTER_INTERNAL_WITH_PARAMS (userdata, usb, 0, dc_match_usb, params, &usb_params);
+ return DC_FILTER_INTERNAL (userdata, usb, 0, dc_match_usb);
}
return 1;
}
-static int dc_filter_deepsix (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_deepsix (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"EXCURSION",
@@ -789,7 +795,8 @@ static int dc_filter_deepsix (dc_transport_t transport, const void *userdata, vo
return 1;
}
-static int dc_filter_deepblu (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_deepblu (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"COSMIQ",
@@ -802,7 +809,8 @@ static int dc_filter_deepblu (dc_transport_t transport, const void *userdata, vo
return 1;
}
-static int dc_filter_oceans (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"S1",
@@ -815,7 +823,8 @@ static int dc_filter_oceans (dc_transport_t transport, const void *userdata, voi
return 1;
}
-static int dc_filter_divesoft (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"Freedom",
@@ -921,10 +930,10 @@ dc_descriptor_get_transports (dc_descriptor_t *descriptor)
}
int
-dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params)
+dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
if (descriptor == NULL || descriptor->filter == NULL || userdata == NULL)
return 1;
- return descriptor->filter (transport, userdata, params);
+ return descriptor->filter (descriptor, transport, userdata);
}
diff --git a/src/irda.c b/src/irda.c
index a5bb8e4..dd5397b 100644
--- a/src/irda.c
+++ b/src/irda.c
@@ -47,7 +47,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "array.h"
#include "platform.h"
@@ -226,7 +225,7 @@ dc_irda_iterator_new (dc_iterator_t **out, dc_context_t *context, dc_descriptor_
INFO (context, "Discover: address=%08x, name=%s, charset=%02x, hints=%04x",
address, name, charset, hints);
- if (!dc_descriptor_filter (descriptor, DC_TRANSPORT_IRDA, name, NULL)) {
+ if (!dc_descriptor_filter (descriptor, DC_TRANSPORT_IRDA, name)) {
continue;
}
diff --git a/src/libdivecomputer.symbols b/src/libdivecomputer.symbols
index 477f1ec..c829852 100644
--- a/src/libdivecomputer.symbols
+++ b/src/libdivecomputer.symbols
@@ -34,6 +34,7 @@ dc_descriptor_get_product
dc_descriptor_get_type
dc_descriptor_get_model
dc_descriptor_get_transports
+dc_descriptor_filter
dc_iostream_get_transport
dc_iostream_set_timeout
diff --git a/src/serial_posix.c b/src/serial_posix.c
index a189e15..792a1c9 100644
--- a/src/serial_posix.c
+++ b/src/serial_posix.c
@@ -57,7 +57,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "platform.h"
#include "timer.h"
@@ -230,7 +229,7 @@ dc_serial_iterator_next (dc_iterator_t *abstract, void *out)
return DC_STATUS_NOMEMORY;
}
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, filename, NULL)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, filename)) {
continue;
}
diff --git a/src/serial_win32.c b/src/serial_win32.c
index aeeeb83..e506cbd 100644
--- a/src/serial_win32.c
+++ b/src/serial_win32.c
@@ -31,7 +31,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "platform.h"
static dc_status_t dc_serial_iterator_next (dc_iterator_t *iterator, void *item);
@@ -228,7 +227,7 @@ dc_serial_iterator_next (dc_iterator_t *abstract, void *out)
// Null terminate the string.
data[data_len] = 0;
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, data, NULL)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, data)) {
continue;
}
diff --git a/src/usb.c b/src/usb.c
index 758c604..d7074cb 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -39,12 +39,23 @@
#include "common-private.h"
#include "context-private.h"
#include "iostream-private.h"
-#include "descriptor-private.h"
#include "iterator-private.h"
#include "platform.h"
+#include "array.h"
#define ISINSTANCE(device) dc_iostream_isinstance((device), &dc_usb_vtable)
+typedef struct dc_usb_params_t {
+ unsigned int interface;
+ unsigned char endpoint_in;
+ unsigned char endpoint_out;
+} dc_usb_params_t;
+
+typedef struct dc_usb_config_t {
+ dc_usb_desc_t desc;
+ dc_usb_params_t params;
+} dc_usb_config_t;
+
typedef struct dc_usb_session_t {
size_t refcount;
#ifdef HAVE_LIBUSB
@@ -120,6 +131,26 @@ static const dc_iostream_vtable_t dc_usb_vtable = {
dc_usb_close, /* close */
};
+static const dc_usb_config_t g_usb_config[] = {
+ // Atomic Aquatics Cobalt
+ {{0x0471, 0x0888}, {0, 0x82, 0x02}},
+};
+
+static const dc_usb_params_t *
+dc_usb_params_find (const dc_usb_desc_t *desc)
+{
+ if (desc == NULL)
+ return NULL;
+
+ for (size_t i = 0; i < C_ARRAY_SIZE(g_usb_config); ++i) {
+ if (g_usb_config[i].desc.vid == desc->vid &&
+ g_usb_config[i].desc.pid == desc->pid)
+ return &g_usb_config[i].params;
+ }
+
+ return NULL;
+}
+
static dc_status_t
syserror(int errcode)
{
@@ -305,11 +336,13 @@ dc_usb_iterator_next (dc_iterator_t *abstract, void *out)
}
dc_usb_desc_t usb = {dev.idVendor, dev.idProduct};
- dc_usb_params_t params = {0, 0, 0};
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USB, &usb, ¶ms)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USB, &usb)) {
continue;
}
+ // Check for known USB parameters.
+ const dc_usb_params_t *params = dc_usb_params_find (&usb);
+
// Get the active configuration descriptor.
struct libusb_config_descriptor *config = NULL;
rc = libusb_get_active_config_descriptor (current, &config);
@@ -325,7 +358,8 @@ dc_usb_iterator_next (dc_iterator_t *abstract, void *out)
const struct libusb_interface *iface = &config->interface[i];
for (int j = 0; j < iface->num_altsetting; j++) {
const struct libusb_interface_descriptor *desc = &iface->altsetting[j];
- if (interface == NULL && desc->bInterfaceNumber == params.interface) {
+ if (interface == NULL &&
+ (params == NULL || params->interface == desc->bInterfaceNumber)) {
interface = desc;
}
}
@@ -349,12 +383,12 @@ dc_usb_iterator_next (dc_iterator_t *abstract, void *out)
}
if (ep_in == NULL && direction == LIBUSB_ENDPOINT_IN &&
- (params.endpoint_in == 0 || params.endpoint_in == desc->bEndpointAddress)) {
+ (params == NULL || params->endpoint_in == desc->bEndpointAddress)) {
ep_in = desc;
}
if (ep_out == NULL && direction == LIBUSB_ENDPOINT_OUT &&
- (params.endpoint_out == 0 || params.endpoint_out == desc->bEndpointAddress)) {
+ (params == NULL || params->endpoint_out == desc->bEndpointAddress)) {
ep_out = desc;
}
}
diff --git a/src/usbhid.c b/src/usbhid.c
index acd20ef..b7818e0 100644
--- a/src/usbhid.c
+++ b/src/usbhid.c
@@ -57,7 +57,6 @@
#include "common-private.h"
#include "context-private.h"
#include "iostream-private.h"
-#include "descriptor-private.h"
#include "iterator-private.h"
#include "platform.h"
@@ -438,8 +437,8 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out)
return syserror (rc);
}
- dc_usb_desc_t usb = {dev.idVendor, dev.idProduct};
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb, NULL)) {
+ dc_usbhid_desc_t usb = {dev.idVendor, dev.idProduct};
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb)) {
continue;
}
@@ -522,8 +521,8 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out)
struct hid_device_info *current = iterator->current;
iterator->current = current->next;
- dc_usb_desc_t usb = {current->vendor_id, current->product_id};
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb, NULL)) {
+ dc_usbhid_desc_t usb = {current->vendor_id, current->product_id};
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb)) {
continue;
}