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:
Jef Driesen 2023-07-05 20:32:41 +02:00
parent b2310e62d6
commit a985b11859
8 changed files with 81 additions and 69 deletions

View File

@ -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;
}

View File

@ -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
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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, &params)) {
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;
}
}

View File

@ -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;
}