diff --git a/src/bluetooth.c b/src/bluetooth.c index aa5f05a..cc143b7 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -455,7 +455,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 index d829422..06c2980 100644 --- a/src/descriptor-private.h +++ b/src/descriptor-private.h @@ -33,14 +33,8 @@ typedef struct dc_usb_desc_t { 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); +dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata); #ifdef __cplusplus } diff --git a/src/descriptor.c b/src/descriptor.c index d287393..d90b54e 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -36,36 +36,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_descriptor_t *descriptor, 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_descriptor_t *descriptor, 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, void *params); -static int dc_filter_shearwater (dc_descriptor_t *descriptor, 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, void *params); -static int dc_filter_tecdiving (dc_descriptor_t *descriptor, 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, void *params); -static int dc_filter_divesystem (dc_descriptor_t *descriptor, 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, void *params); -static int dc_filter_mclean (dc_descriptor_t *descriptor, 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, void *params); -static int dc_filter_deepsix (dc_descriptor_t *descriptor, 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, void *params); -static int dc_filter_oceans (dc_descriptor_t *descriptor, 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, 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); @@ -546,16 +536,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; } } @@ -571,7 +558,7 @@ static const char * const rfcomm[] = { }; static int -dc_filter_uwatec (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_uwatec (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const irda[] = { "Aladin Smart Com", @@ -609,7 +596,7 @@ dc_filter_uwatec (dc_descriptor_t *descriptor, dc_transport_t transport, const v } static int -dc_filter_suunto (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_suunto (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const dc_usb_desc_t usbhid[] = { {0x1493, 0x0030}, // Eon Steel @@ -634,7 +621,7 @@ dc_filter_suunto (dc_descriptor_t *descriptor, dc_transport_t transport, const v } static int -dc_filter_hw (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_hw (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "OSTC", @@ -651,7 +638,7 @@ dc_filter_hw (dc_descriptor_t *descriptor, dc_transport_t transport, const void } static int -dc_filter_shearwater (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_shearwater (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "Predator", @@ -675,7 +662,7 @@ dc_filter_shearwater (dc_descriptor_t *descriptor, dc_transport_t transport, con } static int -dc_filter_tecdiving (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_tecdiving (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "DiveComputer", @@ -691,7 +678,7 @@ dc_filter_tecdiving (dc_descriptor_t *descriptor, dc_transport_t transport, cons } static int -dc_filter_mares (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_mares (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "Mares bluelink pro", @@ -706,7 +693,7 @@ dc_filter_mares (dc_descriptor_t *descriptor, dc_transport_t transport, const vo } static int -dc_filter_divesystem (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_divesystem (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "DS", @@ -722,7 +709,7 @@ dc_filter_divesystem (dc_descriptor_t *descriptor, dc_transport_t transport, con } static int -dc_filter_oceanic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_oceanic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const unsigned int model[] = { 0x4552, // Oceanic Pro Plus X @@ -750,7 +737,7 @@ dc_filter_oceanic (dc_descriptor_t *descriptor, dc_transport_t transport, const } static int -dc_filter_mclean(dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_mclean(dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "McLean Extreme", @@ -766,25 +753,21 @@ dc_filter_mclean(dc_descriptor_t *descriptor, dc_transport_t transport, const vo } static int -dc_filter_atomic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +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_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_deepsix (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "EXCURSION", @@ -801,7 +784,7 @@ dc_filter_deepsix (dc_descriptor_t *descriptor, dc_transport_t transport, const } static int -dc_filter_deepblu (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_deepblu (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "COSMIQ", @@ -815,7 +798,7 @@ dc_filter_deepblu (dc_descriptor_t *descriptor, dc_transport_t transport, const } static int -dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "S1", @@ -829,7 +812,7 @@ dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transport, const v } static int -dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params) +dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const char * const bluetooth[] = { "Freedom", @@ -935,10 +918,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 (descriptor, transport, userdata, params); + return descriptor->filter (descriptor, transport, userdata); } diff --git a/src/irda.c b/src/irda.c index a5bb8e4..6bd927c 100644 --- a/src/irda.c +++ b/src/irda.c @@ -226,7 +226,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/serial_posix.c b/src/serial_posix.c index a189e15..51b1037 100644 --- a/src/serial_posix.c +++ b/src/serial_posix.c @@ -230,7 +230,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..30fe0e9 100644 --- a/src/serial_win32.c +++ b/src/serial_win32.c @@ -228,7 +228,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..80083f6 100644 --- a/src/usb.c +++ b/src/usb.c @@ -42,9 +42,21 @@ #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 +132,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 +337,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 +359,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 +384,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..3ed94d7 100644 --- a/src/usbhid.c +++ b/src/usbhid.c @@ -439,7 +439,7 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out) } dc_usb_desc_t usb = {dev.idVendor, dev.idProduct}; - if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb, NULL)) { + if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb)) { continue; } @@ -523,7 +523,7 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out) 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)) { + if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb)) { continue; }