Add suport for applying a filter function

The device descriptors are extended with a filter function. During the
device discovery, this filter function is used to return only devices
that match a known dive computer.

The filtering is optional, and can be disabled by passing a NULL pointer
for the device descriptor when creating the iterator with one of the
dc_xxx_iterator_new() functions.
This commit is contained in:
Jef Driesen 2017-07-17 23:41:48 +02:00
parent ca91500ed5
commit 30e4060817
8 changed files with 326 additions and 231 deletions

View File

@ -16,7 +16,7 @@ endif
libdivecomputer_la_SOURCES = \
version.c \
descriptor.c \
descriptor-private.h descriptor.c \
iostream-private.h iostream.c \
iterator-private.h iterator.c \
common-private.h common.c \

View File

@ -51,6 +51,7 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
#include "descriptor-private.h"
#ifdef _WIN32
#define DC_ADDRESS_FORMAT "%012I64X"
@ -76,6 +77,7 @@ static dc_status_t dc_bluetooth_iterator_free (dc_iterator_t *iterator);
typedef struct dc_bluetooth_iterator_t {
dc_iterator_t base;
dc_filter_t filter;
#ifdef _WIN32
HANDLE hLookup;
#else
@ -318,6 +320,7 @@ dc_bluetooth_iterator_new (dc_iterator_t **out, dc_context_t *context, dc_descri
iterator->count = ndevices;
iterator->current = 0;
#endif
iterator->filter = dc_descriptor_get_filter (descriptor);
*out = (dc_iterator_t *) iterator;
@ -395,6 +398,10 @@ dc_bluetooth_iterator_next (dc_iterator_t *abstract, void *out)
INFO (abstract->context, "Discover: address=" DC_ADDRESS_FORMAT ", name=%s",
address, name ? name : "");
if (iterator->filter && !iterator->filter (DC_TRANSPORT_BLUETOOTH, name)) {
continue;
}
device = (dc_bluetooth_device_t *) malloc (sizeof(dc_bluetooth_device_t));
if (device == NULL) {
SYSERROR (abstract->context, S_ENOMEM);

44
src/descriptor-private.h Normal file
View File

@ -0,0 +1,44 @@
/*
* 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 <libdivecomputer/descriptor.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct dc_usb_desc_t {
unsigned short vid;
unsigned short pid;
} dc_usb_desc_t;
typedef int (*dc_filter_t) (dc_transport_t transport, const void *userdata);
dc_filter_t
dc_descriptor_get_filter (dc_descriptor_t *descriptor);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DC_DESCRIPTOR_PRIVATE_H */

View File

@ -42,8 +42,7 @@
#include <stddef.h>
#include <stdlib.h>
#include <libdivecomputer/descriptor.h>
#include "descriptor-private.h"
#include "iterator-private.h"
#define C_ARRAY_SIZE(array) (sizeof (array) / sizeof *(array))
@ -55,6 +54,7 @@ struct dc_descriptor_t {
const char *product;
dc_family_t type;
unsigned int model;
dc_filter_t filter;
};
typedef struct dc_descriptor_iterator_t {
@ -77,271 +77,271 @@ static const dc_iterator_vtable_t dc_descriptor_iterator_vtable = {
static const dc_descriptor_t g_descriptors[] = {
/* Suunto Solution */
{"Suunto", "Solution", DC_FAMILY_SUUNTO_SOLUTION, 0},
{"Suunto", "Solution", DC_FAMILY_SUUNTO_SOLUTION, 0, NULL},
/* Suunto Eon */
{"Suunto", "Eon", DC_FAMILY_SUUNTO_EON, 0},
{"Suunto", "Solution Alpha", DC_FAMILY_SUUNTO_EON, 0},
{"Suunto", "Solution Nitrox", DC_FAMILY_SUUNTO_EON, 0},
{"Suunto", "Eon", DC_FAMILY_SUUNTO_EON, 0, NULL},
{"Suunto", "Solution Alpha", DC_FAMILY_SUUNTO_EON, 0, NULL},
{"Suunto", "Solution Nitrox", DC_FAMILY_SUUNTO_EON, 0, NULL},
/* Suunto Vyper */
{"Suunto", "Spyder", DC_FAMILY_SUUNTO_VYPER, 0x01},
{"Suunto", "Stinger", DC_FAMILY_SUUNTO_VYPER, 0x03},
{"Suunto", "Mosquito", DC_FAMILY_SUUNTO_VYPER, 0x04},
{"Suunto", "D3", DC_FAMILY_SUUNTO_VYPER, 0x05},
{"Suunto", "Vyper", DC_FAMILY_SUUNTO_VYPER, 0x0A},
{"Suunto", "Vytec", DC_FAMILY_SUUNTO_VYPER, 0X0B},
{"Suunto", "Cobra", DC_FAMILY_SUUNTO_VYPER, 0X0C},
{"Suunto", "Gekko", DC_FAMILY_SUUNTO_VYPER, 0X0D},
{"Suunto", "Zoop", DC_FAMILY_SUUNTO_VYPER, 0x16},
{"Suunto", "Spyder", DC_FAMILY_SUUNTO_VYPER, 0x01, NULL},
{"Suunto", "Stinger", DC_FAMILY_SUUNTO_VYPER, 0x03, NULL},
{"Suunto", "Mosquito", DC_FAMILY_SUUNTO_VYPER, 0x04, NULL},
{"Suunto", "D3", DC_FAMILY_SUUNTO_VYPER, 0x05, NULL},
{"Suunto", "Vyper", DC_FAMILY_SUUNTO_VYPER, 0x0A, NULL},
{"Suunto", "Vytec", DC_FAMILY_SUUNTO_VYPER, 0X0B, NULL},
{"Suunto", "Cobra", DC_FAMILY_SUUNTO_VYPER, 0X0C, NULL},
{"Suunto", "Gekko", DC_FAMILY_SUUNTO_VYPER, 0X0D, NULL},
{"Suunto", "Zoop", DC_FAMILY_SUUNTO_VYPER, 0x16, NULL},
/* Suunto Vyper 2 */
{"Suunto", "Vyper 2", DC_FAMILY_SUUNTO_VYPER2, 0x10},
{"Suunto", "Cobra 2", DC_FAMILY_SUUNTO_VYPER2, 0x11},
{"Suunto", "Vyper Air", DC_FAMILY_SUUNTO_VYPER2, 0x13},
{"Suunto", "Cobra 3", DC_FAMILY_SUUNTO_VYPER2, 0x14},
{"Suunto", "HelO2", DC_FAMILY_SUUNTO_VYPER2, 0x15},
{"Suunto", "Vyper 2", DC_FAMILY_SUUNTO_VYPER2, 0x10, NULL},
{"Suunto", "Cobra 2", DC_FAMILY_SUUNTO_VYPER2, 0x11, NULL},
{"Suunto", "Vyper Air", DC_FAMILY_SUUNTO_VYPER2, 0x13, NULL},
{"Suunto", "Cobra 3", DC_FAMILY_SUUNTO_VYPER2, 0x14, NULL},
{"Suunto", "HelO2", DC_FAMILY_SUUNTO_VYPER2, 0x15, NULL},
/* Suunto D9 */
{"Suunto", "D9", DC_FAMILY_SUUNTO_D9, 0x0E},
{"Suunto", "D6", DC_FAMILY_SUUNTO_D9, 0x0F},
{"Suunto", "D4", DC_FAMILY_SUUNTO_D9, 0x12},
{"Suunto", "D4i", DC_FAMILY_SUUNTO_D9, 0x19},
{"Suunto", "D6i", DC_FAMILY_SUUNTO_D9, 0x1A},
{"Suunto", "D9tx", DC_FAMILY_SUUNTO_D9, 0x1B},
{"Suunto", "DX", DC_FAMILY_SUUNTO_D9, 0x1C},
{"Suunto", "Vyper Novo", DC_FAMILY_SUUNTO_D9, 0x1D},
{"Suunto", "Zoop Novo", DC_FAMILY_SUUNTO_D9, 0x1E},
{"Suunto", "D4f", DC_FAMILY_SUUNTO_D9, 0x20},
{"Suunto", "D9", DC_FAMILY_SUUNTO_D9, 0x0E, NULL},
{"Suunto", "D6", DC_FAMILY_SUUNTO_D9, 0x0F, NULL},
{"Suunto", "D4", DC_FAMILY_SUUNTO_D9, 0x12, NULL},
{"Suunto", "D4i", DC_FAMILY_SUUNTO_D9, 0x19, NULL},
{"Suunto", "D6i", DC_FAMILY_SUUNTO_D9, 0x1A, NULL},
{"Suunto", "D9tx", DC_FAMILY_SUUNTO_D9, 0x1B, NULL},
{"Suunto", "DX", DC_FAMILY_SUUNTO_D9, 0x1C, NULL},
{"Suunto", "Vyper Novo", DC_FAMILY_SUUNTO_D9, 0x1D, NULL},
{"Suunto", "Zoop Novo", DC_FAMILY_SUUNTO_D9, 0x1E, NULL},
{"Suunto", "D4f", DC_FAMILY_SUUNTO_D9, 0x20, NULL},
/* Suunto EON Steel */
#ifdef USBHID
{"Suunto", "EON Steel", DC_FAMILY_SUUNTO_EONSTEEL, 0},
{"Suunto", "EON Core", DC_FAMILY_SUUNTO_EONSTEEL, 1},
{"Suunto", "EON Steel", DC_FAMILY_SUUNTO_EONSTEEL, 0, NULL},
{"Suunto", "EON Core", DC_FAMILY_SUUNTO_EONSTEEL, 1, NULL},
#endif
/* Uwatec Aladin */
{"Uwatec", "Aladin Air Twin", DC_FAMILY_UWATEC_ALADIN, 0x1C},
{"Uwatec", "Aladin Sport Plus", DC_FAMILY_UWATEC_ALADIN, 0x3E},
{"Uwatec", "Aladin Pro", DC_FAMILY_UWATEC_ALADIN, 0x3F},
{"Uwatec", "Aladin Air Z", DC_FAMILY_UWATEC_ALADIN, 0x44},
{"Uwatec", "Aladin Air Z O2", DC_FAMILY_UWATEC_ALADIN, 0xA4},
{"Uwatec", "Aladin Air Z Nitrox", DC_FAMILY_UWATEC_ALADIN, 0xF4},
{"Uwatec", "Aladin Pro Ultra", DC_FAMILY_UWATEC_ALADIN, 0xFF},
{"Uwatec", "Aladin Air Twin", DC_FAMILY_UWATEC_ALADIN, 0x1C, NULL},
{"Uwatec", "Aladin Sport Plus", DC_FAMILY_UWATEC_ALADIN, 0x3E, NULL},
{"Uwatec", "Aladin Pro", DC_FAMILY_UWATEC_ALADIN, 0x3F, NULL},
{"Uwatec", "Aladin Air Z", DC_FAMILY_UWATEC_ALADIN, 0x44, NULL},
{"Uwatec", "Aladin Air Z O2", DC_FAMILY_UWATEC_ALADIN, 0xA4, NULL},
{"Uwatec", "Aladin Air Z Nitrox", DC_FAMILY_UWATEC_ALADIN, 0xF4, NULL},
{"Uwatec", "Aladin Pro Ultra", DC_FAMILY_UWATEC_ALADIN, 0xFF, NULL},
/* Uwatec Memomouse */
{"Uwatec", "Memomouse", DC_FAMILY_UWATEC_MEMOMOUSE, 0},
{"Uwatec", "Memomouse", DC_FAMILY_UWATEC_MEMOMOUSE, 0, NULL},
/* Uwatec Smart */
#ifdef IRDA
{"Uwatec", "Smart Pro", DC_FAMILY_UWATEC_SMART, 0x10},
{"Uwatec", "Galileo Sol", DC_FAMILY_UWATEC_SMART, 0x11},
{"Uwatec", "Galileo Luna", DC_FAMILY_UWATEC_SMART, 0x11},
{"Uwatec", "Galileo Terra", DC_FAMILY_UWATEC_SMART, 0x11},
{"Uwatec", "Aladin Tec", DC_FAMILY_UWATEC_SMART, 0x12},
{"Uwatec", "Aladin Prime", DC_FAMILY_UWATEC_SMART, 0x12},
{"Uwatec", "Aladin Tec 2G", DC_FAMILY_UWATEC_SMART, 0x13},
{"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x13},
{"Subgear","XP-10", DC_FAMILY_UWATEC_SMART, 0x13},
{"Uwatec", "Smart Com", DC_FAMILY_UWATEC_SMART, 0x14},
{"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x15},
{"Uwatec", "Aladin Tec 3G", DC_FAMILY_UWATEC_SMART, 0x15},
{"Uwatec", "Aladin Sport", DC_FAMILY_UWATEC_SMART, 0x15},
{"Subgear","XP-3G", DC_FAMILY_UWATEC_SMART, 0x15},
{"Uwatec", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18},
{"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19},
{"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C},
{"Subgear","XP Air", DC_FAMILY_UWATEC_SMART, 0x1C},
{"Uwatec", "Smart Pro", DC_FAMILY_UWATEC_SMART, 0x10, NULL},
{"Uwatec", "Galileo Sol", DC_FAMILY_UWATEC_SMART, 0x11, NULL},
{"Uwatec", "Galileo Luna", DC_FAMILY_UWATEC_SMART, 0x11, NULL},
{"Uwatec", "Galileo Terra", DC_FAMILY_UWATEC_SMART, 0x11, NULL},
{"Uwatec", "Aladin Tec", DC_FAMILY_UWATEC_SMART, 0x12, NULL},
{"Uwatec", "Aladin Prime", DC_FAMILY_UWATEC_SMART, 0x12, NULL},
{"Uwatec", "Aladin Tec 2G", DC_FAMILY_UWATEC_SMART, 0x13, NULL},
{"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x13, NULL},
{"Subgear","XP-10", DC_FAMILY_UWATEC_SMART, 0x13, NULL},
{"Uwatec", "Smart Com", DC_FAMILY_UWATEC_SMART, 0x14, NULL},
{"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x15, NULL},
{"Uwatec", "Aladin Tec 3G", DC_FAMILY_UWATEC_SMART, 0x15, NULL},
{"Uwatec", "Aladin Sport", DC_FAMILY_UWATEC_SMART, 0x15, NULL},
{"Subgear","XP-3G", DC_FAMILY_UWATEC_SMART, 0x15, NULL},
{"Uwatec", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18, NULL},
{"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19, NULL},
{"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C, NULL},
{"Subgear","XP Air", DC_FAMILY_UWATEC_SMART, 0x1C, NULL},
#endif
/* Scubapro/Uwatec Meridian */
{"Scubapro", "Meridian", DC_FAMILY_UWATEC_MERIDIAN, 0x20},
{"Scubapro", "Mantis", DC_FAMILY_UWATEC_MERIDIAN, 0x20},
{"Scubapro", "Chromis", DC_FAMILY_UWATEC_MERIDIAN, 0x24},
{"Scubapro", "Mantis 2", DC_FAMILY_UWATEC_MERIDIAN, 0x26},
{"Scubapro", "Meridian", DC_FAMILY_UWATEC_MERIDIAN, 0x20, NULL},
{"Scubapro", "Mantis", DC_FAMILY_UWATEC_MERIDIAN, 0x20, NULL},
{"Scubapro", "Chromis", DC_FAMILY_UWATEC_MERIDIAN, 0x24, NULL},
{"Scubapro", "Mantis 2", DC_FAMILY_UWATEC_MERIDIAN, 0x26, NULL},
/* Scubapro G2 */
#ifdef USBHID
{"Scubapro", "Aladin Sport Matrix", DC_FAMILY_UWATEC_G2, 0x17},
{"Scubapro", "Aladin Square", DC_FAMILY_UWATEC_G2, 0x22},
{"Scubapro", "G2", DC_FAMILY_UWATEC_G2, 0x32},
{"Scubapro", "Aladin Sport Matrix", DC_FAMILY_UWATEC_G2, 0x17, NULL},
{"Scubapro", "Aladin Square", DC_FAMILY_UWATEC_G2, 0x22, NULL},
{"Scubapro", "G2", DC_FAMILY_UWATEC_G2, 0x32, NULL},
#endif
/* Reefnet */
{"Reefnet", "Sensus", DC_FAMILY_REEFNET_SENSUS, 1},
{"Reefnet", "Sensus Pro", DC_FAMILY_REEFNET_SENSUSPRO, 2},
{"Reefnet", "Sensus Ultra", DC_FAMILY_REEFNET_SENSUSULTRA, 3},
{"Reefnet", "Sensus", DC_FAMILY_REEFNET_SENSUS, 1, NULL},
{"Reefnet", "Sensus Pro", DC_FAMILY_REEFNET_SENSUSPRO, 2, NULL},
{"Reefnet", "Sensus Ultra", DC_FAMILY_REEFNET_SENSUSULTRA, 3, NULL},
/* Oceanic VT Pro */
{"Aeris", "500 AI", DC_FAMILY_OCEANIC_VTPRO, 0x4151},
{"Oceanic", "Versa Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4155},
{"Aeris", "Atmos 2", DC_FAMILY_OCEANIC_VTPRO, 0x4158},
{"Oceanic", "Pro Plus 2", DC_FAMILY_OCEANIC_VTPRO, 0x4159},
{"Aeris", "Atmos AI", DC_FAMILY_OCEANIC_VTPRO, 0x4244},
{"Oceanic", "VT Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4245},
{"Sherwood", "Wisdom", DC_FAMILY_OCEANIC_VTPRO, 0x4246},
{"Aeris", "Elite", DC_FAMILY_OCEANIC_VTPRO, 0x424F},
{"Aeris", "500 AI", DC_FAMILY_OCEANIC_VTPRO, 0x4151, NULL},
{"Oceanic", "Versa Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4155, NULL},
{"Aeris", "Atmos 2", DC_FAMILY_OCEANIC_VTPRO, 0x4158, NULL},
{"Oceanic", "Pro Plus 2", DC_FAMILY_OCEANIC_VTPRO, 0x4159, NULL},
{"Aeris", "Atmos AI", DC_FAMILY_OCEANIC_VTPRO, 0x4244, NULL},
{"Oceanic", "VT Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4245, NULL},
{"Sherwood", "Wisdom", DC_FAMILY_OCEANIC_VTPRO, 0x4246, NULL},
{"Aeris", "Elite", DC_FAMILY_OCEANIC_VTPRO, 0x424F, NULL},
/* Oceanic Veo 250 */
{"Genesis", "React Pro", DC_FAMILY_OCEANIC_VEO250, 0x4247},
{"Oceanic", "Veo 200", DC_FAMILY_OCEANIC_VEO250, 0x424B},
{"Oceanic", "Veo 250", DC_FAMILY_OCEANIC_VEO250, 0x424C},
{"Seemann", "XP5", DC_FAMILY_OCEANIC_VEO250, 0x4251},
{"Oceanic", "Veo 180", DC_FAMILY_OCEANIC_VEO250, 0x4252},
{"Aeris", "XR-2", DC_FAMILY_OCEANIC_VEO250, 0x4255},
{"Sherwood", "Insight", DC_FAMILY_OCEANIC_VEO250, 0x425A},
{"Hollis", "DG02", DC_FAMILY_OCEANIC_VEO250, 0x4352},
{"Genesis", "React Pro", DC_FAMILY_OCEANIC_VEO250, 0x4247, NULL},
{"Oceanic", "Veo 200", DC_FAMILY_OCEANIC_VEO250, 0x424B, NULL},
{"Oceanic", "Veo 250", DC_FAMILY_OCEANIC_VEO250, 0x424C, NULL},
{"Seemann", "XP5", DC_FAMILY_OCEANIC_VEO250, 0x4251, NULL},
{"Oceanic", "Veo 180", DC_FAMILY_OCEANIC_VEO250, 0x4252, NULL},
{"Aeris", "XR-2", DC_FAMILY_OCEANIC_VEO250, 0x4255, NULL},
{"Sherwood", "Insight", DC_FAMILY_OCEANIC_VEO250, 0x425A, NULL},
{"Hollis", "DG02", DC_FAMILY_OCEANIC_VEO250, 0x4352, NULL},
/* Oceanic Atom 2.0 */
{"Oceanic", "Atom 1.0", DC_FAMILY_OCEANIC_ATOM2, 0x4250},
{"Aeris", "Epic", DC_FAMILY_OCEANIC_ATOM2, 0x4257},
{"Oceanic", "VT3", DC_FAMILY_OCEANIC_ATOM2, 0x4258},
{"Aeris", "Elite T3", DC_FAMILY_OCEANIC_ATOM2, 0x4259},
{"Oceanic", "Atom 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4342},
{"Oceanic", "Geo", DC_FAMILY_OCEANIC_ATOM2, 0x4344},
{"Aeris", "Manta", DC_FAMILY_OCEANIC_ATOM2, 0x4345},
{"Aeris", "XR-1 NX", DC_FAMILY_OCEANIC_ATOM2, 0x4346},
{"Oceanic", "Datamask", DC_FAMILY_OCEANIC_ATOM2, 0x4347},
{"Aeris", "Compumask", DC_FAMILY_OCEANIC_ATOM2, 0x4348},
{"Aeris", "F10", DC_FAMILY_OCEANIC_ATOM2, 0x434D},
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x434E},
{"Sherwood", "Wisdom 2", DC_FAMILY_OCEANIC_ATOM2, 0x4350},
{"Sherwood", "Insight 2", DC_FAMILY_OCEANIC_ATOM2, 0x4353},
{"Genesis", "React Pro White", DC_FAMILY_OCEANIC_ATOM2, 0x4354},
{"Tusa", "Element II (IQ-750)", DC_FAMILY_OCEANIC_ATOM2, 0x4357},
{"Oceanic", "Veo 1.0", DC_FAMILY_OCEANIC_ATOM2, 0x4358},
{"Oceanic", "Veo 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4359},
{"Oceanic", "Veo 3.0", DC_FAMILY_OCEANIC_ATOM2, 0x435A},
{"Tusa", "Zen (IQ-900)", DC_FAMILY_OCEANIC_ATOM2, 0x4441},
{"Tusa", "Zen Air (IQ-950)", DC_FAMILY_OCEANIC_ATOM2, 0x4442},
{"Aeris", "Atmos AI 2", DC_FAMILY_OCEANIC_ATOM2, 0x4443},
{"Oceanic", "Pro Plus 2.1", DC_FAMILY_OCEANIC_ATOM2, 0x4444},
{"Oceanic", "Geo 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4446},
{"Oceanic", "VT4", DC_FAMILY_OCEANIC_ATOM2, 0x4447},
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x4449},
{"Beuchat", "Voyager 2G", DC_FAMILY_OCEANIC_ATOM2, 0x444B},
{"Oceanic", "Atom 3.0", DC_FAMILY_OCEANIC_ATOM2, 0x444C},
{"Hollis", "DG03", DC_FAMILY_OCEANIC_ATOM2, 0x444D},
{"Oceanic", "OCS", DC_FAMILY_OCEANIC_ATOM2, 0x4450},
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x4451},
{"Oceanic", "VT 4.1", DC_FAMILY_OCEANIC_ATOM2, 0x4452},
{"Aeris", "Epic", DC_FAMILY_OCEANIC_ATOM2, 0x4453},
{"Aeris", "Elite T3", DC_FAMILY_OCEANIC_ATOM2, 0x4455},
{"Oceanic", "Atom 3.1", DC_FAMILY_OCEANIC_ATOM2, 0x4456},
{"Aeris", "A300 AI", DC_FAMILY_OCEANIC_ATOM2, 0x4457},
{"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458},
{"Aeris", "A300", DC_FAMILY_OCEANIC_ATOM2, 0x445A},
{"Hollis", "TX1", DC_FAMILY_OCEANIC_ATOM2, 0x4542},
{"Beuchat", "Mundial 2", DC_FAMILY_OCEANIC_ATOM2, 0x4543},
{"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545},
{"Sherwood", "Amphos Air", DC_FAMILY_OCEANIC_ATOM2, 0x4546},
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548},
{"Aeris", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4549},
{"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B},
{"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C},
{"Beuchat", "Mundial 3", DC_FAMILY_OCEANIC_ATOM2, 0x4550},
{"Oceanic", "F10", DC_FAMILY_OCEANIC_ATOM2, 0x4553},
{"Oceanic", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4554},
{"Subgear", "XP-Air", DC_FAMILY_OCEANIC_ATOM2, 0x4555},
{"Sherwood", "Vision", DC_FAMILY_OCEANIC_ATOM2, 0x4556},
{"Oceanic", "VTX", DC_FAMILY_OCEANIC_ATOM2, 0x4557},
{"Aqualung", "i300", DC_FAMILY_OCEANIC_ATOM2, 0x4559},
{"Aqualung", "i750TC", DC_FAMILY_OCEANIC_ATOM2, 0x455A},
{"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641},
{"Aqualung", "i550", DC_FAMILY_OCEANIC_ATOM2, 0x4642},
{"Aqualung", "i200", DC_FAMILY_OCEANIC_ATOM2, 0x4646},
{"Oceanic", "Atom 1.0", DC_FAMILY_OCEANIC_ATOM2, 0x4250, NULL},
{"Aeris", "Epic", DC_FAMILY_OCEANIC_ATOM2, 0x4257, NULL},
{"Oceanic", "VT3", DC_FAMILY_OCEANIC_ATOM2, 0x4258, NULL},
{"Aeris", "Elite T3", DC_FAMILY_OCEANIC_ATOM2, 0x4259, NULL},
{"Oceanic", "Atom 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4342, NULL},
{"Oceanic", "Geo", DC_FAMILY_OCEANIC_ATOM2, 0x4344, NULL},
{"Aeris", "Manta", DC_FAMILY_OCEANIC_ATOM2, 0x4345, NULL},
{"Aeris", "XR-1 NX", DC_FAMILY_OCEANIC_ATOM2, 0x4346, NULL},
{"Oceanic", "Datamask", DC_FAMILY_OCEANIC_ATOM2, 0x4347, NULL},
{"Aeris", "Compumask", DC_FAMILY_OCEANIC_ATOM2, 0x4348, NULL},
{"Aeris", "F10", DC_FAMILY_OCEANIC_ATOM2, 0x434D, NULL},
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x434E, NULL},
{"Sherwood", "Wisdom 2", DC_FAMILY_OCEANIC_ATOM2, 0x4350, NULL},
{"Sherwood", "Insight 2", DC_FAMILY_OCEANIC_ATOM2, 0x4353, NULL},
{"Genesis", "React Pro White", DC_FAMILY_OCEANIC_ATOM2, 0x4354, NULL},
{"Tusa", "Element II (IQ-750)", DC_FAMILY_OCEANIC_ATOM2, 0x4357, NULL},
{"Oceanic", "Veo 1.0", DC_FAMILY_OCEANIC_ATOM2, 0x4358, NULL},
{"Oceanic", "Veo 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4359, NULL},
{"Oceanic", "Veo 3.0", DC_FAMILY_OCEANIC_ATOM2, 0x435A, NULL},
{"Tusa", "Zen (IQ-900)", DC_FAMILY_OCEANIC_ATOM2, 0x4441, NULL},
{"Tusa", "Zen Air (IQ-950)", DC_FAMILY_OCEANIC_ATOM2, 0x4442, NULL},
{"Aeris", "Atmos AI 2", DC_FAMILY_OCEANIC_ATOM2, 0x4443, NULL},
{"Oceanic", "Pro Plus 2.1", DC_FAMILY_OCEANIC_ATOM2, 0x4444, NULL},
{"Oceanic", "Geo 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4446, NULL},
{"Oceanic", "VT4", DC_FAMILY_OCEANIC_ATOM2, 0x4447, NULL},
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x4449, NULL},
{"Beuchat", "Voyager 2G", DC_FAMILY_OCEANIC_ATOM2, 0x444B, NULL},
{"Oceanic", "Atom 3.0", DC_FAMILY_OCEANIC_ATOM2, 0x444C, NULL},
{"Hollis", "DG03", DC_FAMILY_OCEANIC_ATOM2, 0x444D, NULL},
{"Oceanic", "OCS", DC_FAMILY_OCEANIC_ATOM2, 0x4450, NULL},
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x4451, NULL},
{"Oceanic", "VT 4.1", DC_FAMILY_OCEANIC_ATOM2, 0x4452, NULL},
{"Aeris", "Epic", DC_FAMILY_OCEANIC_ATOM2, 0x4453, NULL},
{"Aeris", "Elite T3", DC_FAMILY_OCEANIC_ATOM2, 0x4455, NULL},
{"Oceanic", "Atom 3.1", DC_FAMILY_OCEANIC_ATOM2, 0x4456, NULL},
{"Aeris", "A300 AI", DC_FAMILY_OCEANIC_ATOM2, 0x4457, NULL},
{"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458, NULL},
{"Aeris", "A300", DC_FAMILY_OCEANIC_ATOM2, 0x445A, NULL},
{"Hollis", "TX1", DC_FAMILY_OCEANIC_ATOM2, 0x4542, NULL},
{"Beuchat", "Mundial 2", DC_FAMILY_OCEANIC_ATOM2, 0x4543, NULL},
{"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545, NULL},
{"Sherwood", "Amphos Air", DC_FAMILY_OCEANIC_ATOM2, 0x4546, NULL},
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548, NULL},
{"Aeris", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4549, NULL},
{"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B, NULL},
{"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C, NULL},
{"Beuchat", "Mundial 3", DC_FAMILY_OCEANIC_ATOM2, 0x4550, NULL},
{"Oceanic", "F10", DC_FAMILY_OCEANIC_ATOM2, 0x4553, NULL},
{"Oceanic", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4554, NULL},
{"Subgear", "XP-Air", DC_FAMILY_OCEANIC_ATOM2, 0x4555, NULL},
{"Sherwood", "Vision", DC_FAMILY_OCEANIC_ATOM2, 0x4556, NULL},
{"Oceanic", "VTX", DC_FAMILY_OCEANIC_ATOM2, 0x4557, NULL},
{"Aqualung", "i300", DC_FAMILY_OCEANIC_ATOM2, 0x4559, NULL},
{"Aqualung", "i750TC", DC_FAMILY_OCEANIC_ATOM2, 0x455A, NULL},
{"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641, NULL},
{"Aqualung", "i550", DC_FAMILY_OCEANIC_ATOM2, 0x4642, NULL},
{"Aqualung", "i200", DC_FAMILY_OCEANIC_ATOM2, 0x4646, NULL},
/* Mares Nemo */
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Titanium",DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Excel", DC_FAMILY_MARES_NEMO, 17},
{"Mares", "Nemo Apneist", DC_FAMILY_MARES_NEMO, 18},
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0, NULL},
{"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0, NULL},
{"Mares", "Nemo Titanium",DC_FAMILY_MARES_NEMO, 0, NULL},
{"Mares", "Nemo Excel", DC_FAMILY_MARES_NEMO, 17, NULL},
{"Mares", "Nemo Apneist", DC_FAMILY_MARES_NEMO, 18, NULL},
/* Mares Puck */
{"Mares", "Puck", DC_FAMILY_MARES_PUCK, 7},
{"Mares", "Puck Air", DC_FAMILY_MARES_PUCK, 19},
{"Mares", "Nemo Air", DC_FAMILY_MARES_PUCK, 4},
{"Mares", "Nemo Wide", DC_FAMILY_MARES_PUCK, 1},
{"Mares", "Puck", DC_FAMILY_MARES_PUCK, 7, NULL},
{"Mares", "Puck Air", DC_FAMILY_MARES_PUCK, 19, NULL},
{"Mares", "Nemo Air", DC_FAMILY_MARES_PUCK, 4, NULL},
{"Mares", "Nemo Wide", DC_FAMILY_MARES_PUCK, 1, NULL},
/* Mares Darwin */
{"Mares", "Darwin", DC_FAMILY_MARES_DARWIN , 0},
{"Mares", "M1", DC_FAMILY_MARES_DARWIN , 0},
{"Mares", "M2", DC_FAMILY_MARES_DARWIN , 0},
{"Mares", "Darwin Air", DC_FAMILY_MARES_DARWIN , 1},
{"Mares", "Airlab", DC_FAMILY_MARES_DARWIN , 1},
{"Mares", "Darwin", DC_FAMILY_MARES_DARWIN , 0, NULL},
{"Mares", "M1", DC_FAMILY_MARES_DARWIN , 0, NULL},
{"Mares", "M2", DC_FAMILY_MARES_DARWIN , 0, NULL},
{"Mares", "Darwin Air", DC_FAMILY_MARES_DARWIN , 1, NULL},
{"Mares", "Airlab", DC_FAMILY_MARES_DARWIN , 1, NULL},
/* Mares Icon HD */
{"Mares", "Matrix", DC_FAMILY_MARES_ICONHD , 0x0F},
{"Mares", "Smart", DC_FAMILY_MARES_ICONHD , 0x000010},
{"Mares", "Smart Apnea", DC_FAMILY_MARES_ICONHD , 0x010010},
{"Mares", "Icon HD", DC_FAMILY_MARES_ICONHD , 0x14},
{"Mares", "Icon HD Net Ready", DC_FAMILY_MARES_ICONHD , 0x15},
{"Mares", "Puck Pro", DC_FAMILY_MARES_ICONHD , 0x18},
{"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19},
{"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F},
{"Mares", "Quad Air", DC_FAMILY_MARES_ICONHD , 0x23},
{"Mares", "Quad", DC_FAMILY_MARES_ICONHD , 0x29},
{"Mares", "Matrix", DC_FAMILY_MARES_ICONHD , 0x0F, NULL},
{"Mares", "Smart", DC_FAMILY_MARES_ICONHD , 0x000010, NULL},
{"Mares", "Smart Apnea", DC_FAMILY_MARES_ICONHD , 0x010010, NULL},
{"Mares", "Icon HD", DC_FAMILY_MARES_ICONHD , 0x14, NULL},
{"Mares", "Icon HD Net Ready", DC_FAMILY_MARES_ICONHD , 0x15, NULL},
{"Mares", "Puck Pro", DC_FAMILY_MARES_ICONHD , 0x18, NULL},
{"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19, NULL},
{"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F, NULL},
{"Mares", "Quad Air", DC_FAMILY_MARES_ICONHD , 0x23, NULL},
{"Mares", "Quad", DC_FAMILY_MARES_ICONHD , 0x29, NULL},
/* Heinrichs Weikamp */
{"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0},
{"Heinrichs Weikamp", "OSTC Mk2", DC_FAMILY_HW_OSTC, 1},
{"Heinrichs Weikamp", "OSTC 2N", DC_FAMILY_HW_OSTC, 2},
{"Heinrichs Weikamp", "OSTC 2C", DC_FAMILY_HW_OSTC, 3},
{"Heinrichs Weikamp", "Frog", DC_FAMILY_HW_FROG, 0},
{"Heinrichs Weikamp", "OSTC 2", DC_FAMILY_HW_OSTC3, 0x11},
{"Heinrichs Weikamp", "OSTC 2", DC_FAMILY_HW_OSTC3, 0x13},
{"Heinrichs Weikamp", "OSTC 2", DC_FAMILY_HW_OSTC3, 0x1B},
{"Heinrichs Weikamp", "OSTC 3", DC_FAMILY_HW_OSTC3, 0x0A},
{"Heinrichs Weikamp", "OSTC Plus", DC_FAMILY_HW_OSTC3, 0x13},
{"Heinrichs Weikamp", "OSTC Plus", DC_FAMILY_HW_OSTC3, 0x1A},
{"Heinrichs Weikamp", "OSTC 4", DC_FAMILY_HW_OSTC3, 0x3B},
{"Heinrichs Weikamp", "OSTC cR", DC_FAMILY_HW_OSTC3, 0x05},
{"Heinrichs Weikamp", "OSTC cR", DC_FAMILY_HW_OSTC3, 0x07},
{"Heinrichs Weikamp", "OSTC Sport", DC_FAMILY_HW_OSTC3, 0x12},
{"Heinrichs Weikamp", "OSTC Sport", DC_FAMILY_HW_OSTC3, 0x13},
{"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0, NULL},
{"Heinrichs Weikamp", "OSTC Mk2", DC_FAMILY_HW_OSTC, 1, NULL},
{"Heinrichs Weikamp", "OSTC 2N", DC_FAMILY_HW_OSTC, 2, NULL},
{"Heinrichs Weikamp", "OSTC 2C", DC_FAMILY_HW_OSTC, 3, NULL},
{"Heinrichs Weikamp", "Frog", DC_FAMILY_HW_FROG, 0, NULL},
{"Heinrichs Weikamp", "OSTC 2", DC_FAMILY_HW_OSTC3, 0x11, NULL},
{"Heinrichs Weikamp", "OSTC 2", DC_FAMILY_HW_OSTC3, 0x13, NULL},
{"Heinrichs Weikamp", "OSTC 2", DC_FAMILY_HW_OSTC3, 0x1B, NULL},
{"Heinrichs Weikamp", "OSTC 3", DC_FAMILY_HW_OSTC3, 0x0A, NULL},
{"Heinrichs Weikamp", "OSTC Plus", DC_FAMILY_HW_OSTC3, 0x13, NULL},
{"Heinrichs Weikamp", "OSTC Plus", DC_FAMILY_HW_OSTC3, 0x1A, NULL},
{"Heinrichs Weikamp", "OSTC 4", DC_FAMILY_HW_OSTC3, 0x3B, NULL},
{"Heinrichs Weikamp", "OSTC cR", DC_FAMILY_HW_OSTC3, 0x05, NULL},
{"Heinrichs Weikamp", "OSTC cR", DC_FAMILY_HW_OSTC3, 0x07, NULL},
{"Heinrichs Weikamp", "OSTC Sport", DC_FAMILY_HW_OSTC3, 0x12, NULL},
{"Heinrichs Weikamp", "OSTC Sport", DC_FAMILY_HW_OSTC3, 0x13, NULL},
/* Cressi Edy */
{"Tusa", "IQ-700", DC_FAMILY_CRESSI_EDY, 0x05},
{"Cressi", "Edy", DC_FAMILY_CRESSI_EDY, 0x08},
{"Tusa", "IQ-700", DC_FAMILY_CRESSI_EDY, 0x05, NULL},
{"Cressi", "Edy", DC_FAMILY_CRESSI_EDY, 0x08, NULL},
/* Cressi Leonardo */
{"Cressi", "Leonardo", DC_FAMILY_CRESSI_LEONARDO, 1},
{"Cressi", "Giotto", DC_FAMILY_CRESSI_LEONARDO, 4},
{"Cressi", "Newton", DC_FAMILY_CRESSI_LEONARDO, 5},
{"Cressi", "Drake", DC_FAMILY_CRESSI_LEONARDO, 6},
{"Cressi", "Leonardo", DC_FAMILY_CRESSI_LEONARDO, 1, NULL},
{"Cressi", "Giotto", DC_FAMILY_CRESSI_LEONARDO, 4, NULL},
{"Cressi", "Newton", DC_FAMILY_CRESSI_LEONARDO, 5, NULL},
{"Cressi", "Drake", DC_FAMILY_CRESSI_LEONARDO, 6, NULL},
/* Zeagle N2iTiON3 */
{"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Dive Rite", "NiTek Trio", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Scubapro", "XTender 5", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0, NULL},
{"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0, NULL},
{"Dive Rite", "NiTek Trio", DC_FAMILY_ZEAGLE_N2ITION3, 0, NULL},
{"Scubapro", "XTender 5", DC_FAMILY_ZEAGLE_N2ITION3, 0, NULL},
/* Atomic Aquatics Cobalt */
#ifdef HAVE_LIBUSB
{"Atomic Aquatics", "Cobalt", DC_FAMILY_ATOMICS_COBALT, 0},
{"Atomic Aquatics", "Cobalt 2", DC_FAMILY_ATOMICS_COBALT, 2},
{"Atomic Aquatics", "Cobalt", DC_FAMILY_ATOMICS_COBALT, 0, NULL},
{"Atomic Aquatics", "Cobalt 2", DC_FAMILY_ATOMICS_COBALT, 2, NULL},
#endif
/* Shearwater Predator */
{"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2},
{"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2, NULL},
/* Shearwater Petrel */
{"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3},
{"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 3},
{"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 4},
{"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 5},
{"Shearwater", "Perdix AI", DC_FAMILY_SHEARWATER_PETREL, 6},
{"Shearwater", "Nerd 2", DC_FAMILY_SHEARWATER_PETREL, 7},
{"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3, NULL},
{"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 3, NULL},
{"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 4, NULL},
{"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 5, NULL},
{"Shearwater", "Perdix AI", DC_FAMILY_SHEARWATER_PETREL, 6, NULL},
{"Shearwater", "Nerd 2", DC_FAMILY_SHEARWATER_PETREL, 7, NULL},
/* Dive Rite NiTek Q */
{"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0},
{"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0, NULL},
/* Citizen Hyper Aqualand */
{"Citizen", "Hyper Aqualand", DC_FAMILY_CITIZEN_AQUALAND, 0},
{"Citizen", "Hyper Aqualand", DC_FAMILY_CITIZEN_AQUALAND, 0, NULL},
/* DiveSystem/Ratio iDive */
{"DiveSystem", "Orca", DC_FAMILY_DIVESYSTEM_IDIVE, 0x02},
{"DiveSystem", "iDive Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x03},
{"DiveSystem", "iDive DAN", DC_FAMILY_DIVESYSTEM_IDIVE, 0x04},
{"DiveSystem", "iDive Tech", DC_FAMILY_DIVESYSTEM_IDIVE, 0x05},
{"DiveSystem", "iDive Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x06},
{"DiveSystem", "iDive Stealth", DC_FAMILY_DIVESYSTEM_IDIVE, 0x07},
{"DiveSystem", "iDive Free", DC_FAMILY_DIVESYSTEM_IDIVE, 0x08},
{"DiveSystem", "iDive Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x09},
{"DiveSystem", "iDive X3M", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0A},
{"DiveSystem", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0B},
{"Ratio", "iX3M Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x22},
{"Ratio", "iX3M Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x23},
{"Ratio", "iX3M Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x24},
{"Ratio", "iX3M Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x25},
{"Ratio", "iX3M Pro Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x32},
{"Ratio", "iX3M Pro Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x34},
{"Ratio", "iX3M Pro Tech+",DC_FAMILY_DIVESYSTEM_IDIVE, 0x35},
{"Ratio", "iDive Free", DC_FAMILY_DIVESYSTEM_IDIVE, 0x40},
{"Ratio", "iDive Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x42},
{"Ratio", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x44},
{"Ratio", "iDive Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x45},
{"Seac", "Jack", DC_FAMILY_DIVESYSTEM_IDIVE, 0x1000},
{"DiveSystem", "Orca", DC_FAMILY_DIVESYSTEM_IDIVE, 0x02, NULL},
{"DiveSystem", "iDive Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x03, NULL},
{"DiveSystem", "iDive DAN", DC_FAMILY_DIVESYSTEM_IDIVE, 0x04, NULL},
{"DiveSystem", "iDive Tech", DC_FAMILY_DIVESYSTEM_IDIVE, 0x05, NULL},
{"DiveSystem", "iDive Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x06, NULL},
{"DiveSystem", "iDive Stealth", DC_FAMILY_DIVESYSTEM_IDIVE, 0x07, NULL},
{"DiveSystem", "iDive Free", DC_FAMILY_DIVESYSTEM_IDIVE, 0x08, NULL},
{"DiveSystem", "iDive Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x09, NULL},
{"DiveSystem", "iDive X3M", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0A, NULL},
{"DiveSystem", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0B, NULL},
{"Ratio", "iX3M Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x22, NULL},
{"Ratio", "iX3M Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x23, NULL},
{"Ratio", "iX3M Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x24, NULL},
{"Ratio", "iX3M Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x25, NULL},
{"Ratio", "iX3M Pro Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x32, NULL},
{"Ratio", "iX3M Pro Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x34, NULL},
{"Ratio", "iX3M Pro Tech+",DC_FAMILY_DIVESYSTEM_IDIVE, 0x35, NULL},
{"Ratio", "iDive Free", DC_FAMILY_DIVESYSTEM_IDIVE, 0x40, NULL},
{"Ratio", "iDive Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x42, NULL},
{"Ratio", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x44, NULL},
{"Ratio", "iDive Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x45, NULL},
{"Seac", "Jack", DC_FAMILY_DIVESYSTEM_IDIVE, 0x1000, NULL},
/* Cochran Commander */
{"Cochran", "Commander TM", DC_FAMILY_COCHRAN_COMMANDER, 0},
{"Cochran", "Commander I", DC_FAMILY_COCHRAN_COMMANDER, 1},
{"Cochran", "Commander II", DC_FAMILY_COCHRAN_COMMANDER, 2},
{"Cochran", "EMC-14", DC_FAMILY_COCHRAN_COMMANDER, 3},
{"Cochran", "EMC-16", DC_FAMILY_COCHRAN_COMMANDER, 4},
{"Cochran", "EMC-20H", DC_FAMILY_COCHRAN_COMMANDER, 5},
{"Cochran", "Commander TM", DC_FAMILY_COCHRAN_COMMANDER, 0, NULL},
{"Cochran", "Commander I", DC_FAMILY_COCHRAN_COMMANDER, 1, NULL},
{"Cochran", "Commander II", DC_FAMILY_COCHRAN_COMMANDER, 2, NULL},
{"Cochran", "EMC-14", DC_FAMILY_COCHRAN_COMMANDER, 3, NULL},
{"Cochran", "EMC-16", DC_FAMILY_COCHRAN_COMMANDER, 4, NULL},
{"Cochran", "EMC-20H", DC_FAMILY_COCHRAN_COMMANDER, 5, NULL},
};
dc_status_t
@ -443,3 +443,12 @@ dc_descriptor_get_transport (dc_descriptor_t *descriptor)
else
return DC_TRANSPORT_SERIAL;
}
dc_filter_t
dc_descriptor_get_filter (dc_descriptor_t *descriptor)
{
if (descriptor == NULL)
return NULL;
return descriptor->filter;
}

View File

@ -48,6 +48,7 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
#include "descriptor-private.h"
#include "array.h"
#include "platform.h"
@ -211,6 +212,8 @@ dc_irda_iterator_new (dc_iterator_t **out, dc_context_t *context, dc_descriptor_
S_CLOSE (fd);
dc_socket_exit (context);
dc_filter_t filter = dc_descriptor_get_filter (descriptor);
unsigned int count = 0;
#ifdef _WIN32
for (size_t i = 0; i < list->numDevice; ++i) {
@ -230,6 +233,10 @@ 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 (filter && !filter (DC_TRANSPORT_IRDA, name)) {
continue;
}
strncpy(iterator->items[count].name, name, sizeof(iterator->items[count].name) - 1);
iterator->items[count].name[sizeof(iterator->items[count].name) - 1] = '\0';
iterator->items[count].address = address;

View File

@ -59,6 +59,7 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
#include "descriptor-private.h"
#define DIRNAME "/dev"
@ -87,6 +88,7 @@ struct dc_serial_device_t {
typedef struct dc_serial_iterator_t {
dc_iterator_t base;
dc_filter_t filter;
DIR *dp;
} dc_serial_iterator_t;
@ -190,6 +192,8 @@ dc_serial_iterator_new (dc_iterator_t **out, dc_context_t *context, dc_descripto
goto error_free;
}
iterator->filter = dc_descriptor_get_filter (descriptor);
*out = (dc_iterator_t *) iterator;
return DC_STATUS_SUCCESS;
@ -229,6 +233,10 @@ dc_serial_iterator_next (dc_iterator_t *abstract, void *out)
return DC_STATUS_NOMEMORY;
}
if (iterator->filter && !iterator->filter (DC_TRANSPORT_SERIAL, filename)) {
continue;
}
device = (dc_serial_device_t *) malloc (sizeof(dc_serial_device_t));
if (device == NULL) {
SYSERROR (abstract->context, ENOMEM);

View File

@ -30,6 +30,7 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
#include "descriptor-private.h"
static dc_status_t dc_serial_iterator_next (dc_iterator_t *iterator, void *item);
static dc_status_t dc_serial_iterator_free (dc_iterator_t *iterator);
@ -56,6 +57,7 @@ struct dc_serial_device_t {
typedef struct dc_serial_iterator_t {
dc_iterator_t base;
dc_filter_t filter;
HKEY hKey;
DWORD count;
DWORD current;
@ -177,6 +179,7 @@ dc_serial_iterator_new (dc_iterator_t **out, dc_context_t *context, dc_descripto
}
}
iterator->filter = dc_descriptor_get_filter (descriptor);
iterator->hKey = hKey;
iterator->count = count;
iterator->current = 0;
@ -222,6 +225,10 @@ dc_serial_iterator_next (dc_iterator_t *abstract, void *out)
// Null terminate the string.
data[data_len] = 0;
if (iterator->filter && !iterator->filter (DC_TRANSPORT_SERIAL, data)) {
continue;
}
device = (dc_serial_device_t *) malloc (sizeof(dc_serial_device_t));
if (device == NULL) {
SYSERROR (abstract->context, ERROR_OUTOFMEMORY);

View File

@ -54,6 +54,7 @@
#include "common-private.h"
#include "context-private.h"
#include "iostream-private.h"
#include "descriptor-private.h"
#include "iterator-private.h"
#include "platform.h"
@ -82,6 +83,7 @@ static dc_status_t dc_usbhid_close (dc_iostream_t *iostream);
typedef struct dc_usbhid_iterator_t {
dc_iterator_t base;
dc_filter_t filter;
#if defined(USE_LIBUSB)
struct libusb_device **devices;
size_t count;
@ -306,6 +308,7 @@ dc_usbhid_iterator_new (dc_iterator_t **out, dc_context_t *context, dc_descripto
iterator->devices = devices;
iterator->current = devices;
#endif
iterator->filter = dc_descriptor_get_filter (descriptor);
*out = (dc_iterator_t *) iterator;
@ -341,6 +344,11 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out)
return syserror (rc);
}
dc_usb_desc_t usb = {dev.idVendor, dev.idProduct};
if (iterator->filter && !iterator->filter (DC_TRANSPORT_USBHID, &usb)) {
continue;
}
// Get the active configuration descriptor.
struct libusb_config_descriptor *config = NULL;
rc = libusb_get_active_config_descriptor (current, &config);
@ -414,6 +422,11 @@ 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 (iterator->filter && !iterator->filter (DC_TRANSPORT_USBHID, &usb)) {
continue;
}
device = (dc_usbhid_device_t *) malloc (sizeof(dc_usbhid_device_t));
if (device == NULL) {
ERROR (abstract->context, "Failed to allocate memory.");