diff --git a/src/atomics_cobalt.c b/src/atomics_cobalt.c index e907b77..a67ef82 100644 --- a/src/atomics_cobalt.c +++ b/src/atomics_cobalt.c @@ -19,19 +19,10 @@ * MA 02110-1301 USA */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include // memcmp, memcpy #include // malloc, free -#ifdef HAVE_LIBUSB -#ifdef _WIN32 -#define NOGDI -#endif -#include -#endif +#include #include "atomics_cobalt.h" #include "context-private.h" @@ -41,8 +32,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &atomics_cobalt_device_vtable) -#define EXITCODE(rc) (rc == LIBUSB_ERROR_TIMEOUT ? DC_STATUS_TIMEOUT : DC_STATUS_IO) - #define COBALT1 0 #define COBALT2 2 @@ -58,10 +47,7 @@ typedef struct atomics_cobalt_device_t { dc_device_t base; -#ifdef HAVE_LIBUSB - libusb_context *context; - libusb_device_handle *handle; -#endif + dc_iostream_t *iostream; unsigned int simulation; unsigned char fingerprint[6]; unsigned char version[SZ_VERSION]; @@ -69,7 +55,6 @@ typedef struct atomics_cobalt_device_t { static dc_status_t atomics_cobalt_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size); static dc_status_t atomics_cobalt_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata); -static dc_status_t atomics_cobalt_device_close (dc_device_t *abstract); static const dc_device_vtable_t atomics_cobalt_device_vtable = { sizeof(atomics_cobalt_device_t), @@ -80,22 +65,19 @@ static const dc_device_vtable_t atomics_cobalt_device_vtable = { NULL, /* dump */ atomics_cobalt_device_foreach, /* foreach */ NULL, /* timesync */ - atomics_cobalt_device_close /* close */ + NULL /* close */ }; dc_status_t -atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context) +atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t *iostream) { -#ifdef HAVE_LIBUSB dc_status_t status = DC_STATUS_SUCCESS; atomics_cobalt_device_t *device = NULL; -#endif if (out == NULL) return DC_STATUS_INVALIDARGS; -#ifdef HAVE_LIBUSB // Allocate memory. device = (atomics_cobalt_device_t *) dc_device_allocate (context, &atomics_cobalt_device_vtable); if (device == NULL) { @@ -104,67 +86,30 @@ atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context) } // Set the default values. - device->context = NULL; - device->handle = NULL; + device->iostream = iostream; device->simulation = 0; memset (device->fingerprint, 0, sizeof (device->fingerprint)); - int rc = libusb_init (&device->context); - if (rc < 0) { - ERROR (context, "Failed to initialize usb support."); - status = DC_STATUS_IO; + // Set the timeout for receiving data (2000 ms). + status = dc_iostream_set_timeout (device->iostream, TIMEOUT); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the timeout."); goto error_free; } - device->handle = libusb_open_device_with_vid_pid (device->context, VID, PID); - if (device->handle == NULL) { - ERROR (context, "Failed to open the usb device."); - status = DC_STATUS_IO; - goto error_usb_exit; - } - - rc = libusb_claim_interface (device->handle, 0); - if (rc < 0) { - ERROR (context, "Failed to claim the usb interface."); - status = DC_STATUS_IO; - goto error_usb_close; - } - status = atomics_cobalt_device_version ((dc_device_t *) device, device->version, sizeof (device->version)); if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to identify the dive computer."); - goto error_usb_close; + goto error_free; } *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; -error_usb_close: - libusb_close (device->handle); -error_usb_exit: - libusb_exit (device->context); error_free: dc_device_deallocate ((dc_device_t *) device); return status; -#else - return DC_STATUS_UNSUPPORTED; -#endif -} - - -static dc_status_t -atomics_cobalt_device_close (dc_device_t *abstract) -{ - atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) abstract; - -#ifdef HAVE_LIBUSB - libusb_release_interface(device->handle, 0); - libusb_close (device->handle); - libusb_exit (device->context); -#endif - - return DC_STATUS_SUCCESS; } @@ -202,6 +147,7 @@ atomics_cobalt_device_set_simulation (dc_device_t *abstract, unsigned int simula dc_status_t atomics_cobalt_device_version (dc_device_t *abstract, unsigned char data[], unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) abstract; if (!ISINSTANCE (abstract)) @@ -210,31 +156,31 @@ atomics_cobalt_device_version (dc_device_t *abstract, unsigned char data[], unsi if (size < SZ_VERSION) return DC_STATUS_INVALIDARGS; -#ifdef HAVE_LIBUSB // Send the command to the dive computer. - uint8_t bRequest = 0x01; - int rc = libusb_control_transfer (device->handle, - LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, - bRequest, 0, 0, NULL, 0, TIMEOUT); - if (rc != LIBUSB_SUCCESS) { - ERROR (abstract->context, "Failed to send the command."); - return EXITCODE(rc); - } + unsigned char bRequest = 0x01; + dc_usb_control_t control = { + DC_USB_REQUEST_VENDOR | DC_USB_RECIPIENT_DEVICE | DC_USB_ENDPOINT_OUT, /* bmRequestType */ + bRequest, /* bRequest */ + 0, /* wValue */ + 0, /* wIndex */ + 0, /* wLength */ + }; - HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Write", &bRequest, 1); + status = dc_iostream_ioctl (device->iostream, DC_IOCTL_USB_CONTROL_WRITE, &control, sizeof(control)); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to send the command."); + return status; + } // Receive the answer from the dive computer. - int length = 0; + size_t length = 0; unsigned char packet[SZ_VERSION + 2] = {0}; - rc = libusb_bulk_transfer (device->handle, 0x82, - packet, sizeof (packet), &length, TIMEOUT); - if (rc != LIBUSB_SUCCESS || length != sizeof (packet)) { + status = dc_iostream_read (device->iostream, packet, sizeof(packet), &length); + if (status != DC_STATUS_SUCCESS || length != sizeof (packet)) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE(rc); + return status; } - HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Read", packet, length); - // Verify the checksum of the packet. unsigned short crc = array_uint16_le (packet + SZ_VERSION); unsigned short ccrc = checksum_add_uint16 (packet, SZ_VERSION, 0x0); @@ -246,16 +192,13 @@ atomics_cobalt_device_version (dc_device_t *abstract, unsigned char data[], unsi memcpy (data, packet, SZ_VERSION); return DC_STATUS_SUCCESS; -#else - return DC_STATUS_UNSUPPORTED; -#endif } static dc_status_t atomics_cobalt_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc_event_progress_t *progress) { -#ifdef HAVE_LIBUSB + dc_status_t status = DC_STATUS_SUCCESS; atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) abstract; if (device_is_cancelled (abstract)) @@ -268,35 +211,37 @@ atomics_cobalt_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, } // Send the command to the dive computer. - uint8_t bRequest = 0; + unsigned char bRequest = 0; if (device->simulation) bRequest = init ? 0x02 : 0x03; else bRequest = init ? 0x09 : 0x0A; - int rc = libusb_control_transfer (device->handle, - LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, - bRequest, 0, 0, NULL, 0, TIMEOUT); - if (rc != LIBUSB_SUCCESS) { - ERROR (abstract->context, "Failed to send the command."); - return EXITCODE(rc); - } - HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Write", &bRequest, 1); + dc_usb_control_t control = { + DC_USB_REQUEST_VENDOR | DC_USB_RECIPIENT_DEVICE | DC_USB_ENDPOINT_OUT, /* bmRequestType */ + bRequest, /* bRequest */ + 0, /* wValue */ + 0, /* wIndex */ + 0, /* wLength */ + }; + + status = dc_iostream_ioctl (device->iostream, DC_IOCTL_USB_CONTROL_WRITE, &control, sizeof(control)); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to send the command."); + return status; + } unsigned int nbytes = 0; while (1) { // Receive the answer from the dive computer. - int length = 0; + size_t length = 0; unsigned char packet[8 * 1024] = {0}; - rc = libusb_bulk_transfer (device->handle, 0x82, - packet, sizeof (packet), &length, TIMEOUT); - if (rc != LIBUSB_SUCCESS && rc != LIBUSB_ERROR_TIMEOUT) { + status = dc_iostream_read (device->iostream, packet, sizeof(packet), &length); + if (status != DC_STATUS_SUCCESS && status != DC_STATUS_TIMEOUT) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE(rc); + return status; } - HEXDUMP (abstract->context, DC_LOGLEVEL_INFO, "Read", packet, length); - // Update and emit a progress event. if (progress) { progress->current += length; @@ -343,9 +288,6 @@ atomics_cobalt_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc_buffer_slice (buffer, 0, nbytes - 2); return DC_STATUS_SUCCESS; -#else - return DC_STATUS_UNSUPPORTED; -#endif } diff --git a/src/atomics_cobalt.h b/src/atomics_cobalt.h index 0308350..09f0226 100644 --- a/src/atomics_cobalt.h +++ b/src/atomics_cobalt.h @@ -23,6 +23,7 @@ #define ATOMICS_COBALT_H #include +#include #include #include #include @@ -32,7 +33,7 @@ extern "C" { #endif /* __cplusplus */ dc_status_t -atomics_cobalt_device_open (dc_device_t **device, dc_context_t *context); +atomics_cobalt_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream); dc_status_t atomics_cobalt_parser_create (dc_parser_t **parser, dc_context_t *context); diff --git a/src/descriptor.c b/src/descriptor.c index 5acab3f..cc8bb9a 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -61,6 +61,7 @@ static int dc_filter_mares (dc_transport_t transport, const void *userdata, void 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 dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item); @@ -326,8 +327,8 @@ static const dc_descriptor_t g_descriptors[] = { {"Dive Rite", "NiTek Trio", DC_FAMILY_ZEAGLE_N2ITION3, 0, DC_TRANSPORT_SERIAL, NULL}, {"Scubapro", "XTender 5", DC_FAMILY_ZEAGLE_N2ITION3, 0, DC_TRANSPORT_SERIAL, NULL}, /* Atomic Aquatics Cobalt */ - {"Atomic Aquatics", "Cobalt", DC_FAMILY_ATOMICS_COBALT, 0, DC_TRANSPORT_USB, NULL}, - {"Atomic Aquatics", "Cobalt 2", DC_FAMILY_ATOMICS_COBALT, 2, DC_TRANSPORT_USB, NULL}, + {"Atomic Aquatics", "Cobalt", DC_FAMILY_ATOMICS_COBALT, 0, DC_TRANSPORT_USB, dc_filter_atomic}, + {"Atomic Aquatics", "Cobalt 2", DC_FAMILY_ATOMICS_COBALT, 2, DC_TRANSPORT_USB, dc_filter_atomic}, /* Shearwater Predator */ {"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_shearwater}, /* Shearwater Petrel */ @@ -669,6 +670,23 @@ 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 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 1; +} + dc_status_t dc_descriptor_iterator (dc_iterator_t **out) { diff --git a/src/device.c b/src/device.c index 271c2f4..62914dc 100644 --- a/src/device.c +++ b/src/device.c @@ -190,7 +190,7 @@ dc_device_open (dc_device_t **out, dc_context_t *context, dc_descriptor_t *descr rc = zeagle_n2ition3_device_open (&device, context, iostream); break; case DC_FAMILY_ATOMICS_COBALT: - rc = atomics_cobalt_device_open (&device, context); + rc = atomics_cobalt_device_open (&device, context, iostream); break; case DC_FAMILY_SHEARWATER_PREDATOR: rc = shearwater_predator_device_open (&device, context, iostream);