Replace the filter parameters with an alternative
The USB I/O backend needs some additional information (e.g. interface number and in/out endpoints) to setup the USB connection. This info is currently maintained inside the descriptor filter function and gets passed to the USB backend by means of the filter parameters. This approach is not only unnecessary complex, but also makes it very difficult to expose the filter function in the public api because the data structures for those parameters are private. Therefore, this data exchange is replaced with a direct mapping between the USB VID/PID and the configuration info in the USB backend itself.
This commit is contained in:
parent
b2310e62d6
commit
a985b11859
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
45
src/usb.c
45
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user