Use the new USB HID backend for the Eon Steel.
This commit is contained in:
parent
6c6b144fe0
commit
417ee6e619
@ -23,6 +23,12 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||||
|
#define USBHID
|
||||||
|
#elif defined(HAVE_HIDAPI)
|
||||||
|
#define USBHID
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -80,7 +86,7 @@ static const dc_descriptor_t g_descriptors[] = {
|
|||||||
{"Suunto", "Vyper Novo", DC_FAMILY_SUUNTO_D9, 0x1D},
|
{"Suunto", "Vyper Novo", DC_FAMILY_SUUNTO_D9, 0x1D},
|
||||||
{"Suunto", "Zoop Novo", DC_FAMILY_SUUNTO_D9, 0x1E},
|
{"Suunto", "Zoop Novo", DC_FAMILY_SUUNTO_D9, 0x1E},
|
||||||
/* Suunto EON Steel */
|
/* Suunto EON Steel */
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef USBHID
|
||||||
{"Suunto", "EON Steel", DC_FAMILY_SUUNTO_EONSTEEL, 0},
|
{"Suunto", "EON Steel", DC_FAMILY_SUUNTO_EONSTEEL, 0},
|
||||||
#endif
|
#endif
|
||||||
/* Uwatec Aladin */
|
/* Uwatec Aladin */
|
||||||
|
|||||||
@ -19,10 +19,6 @@
|
|||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -32,24 +28,15 @@
|
|||||||
#include "context-private.h"
|
#include "context-private.h"
|
||||||
#include "device-private.h"
|
#include "device-private.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
#include "usbhid.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBUSB
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define NOGDI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <libusb-1.0/libusb.h>
|
|
||||||
|
|
||||||
typedef struct suunto_eonsteel_device_t {
|
typedef struct suunto_eonsteel_device_t {
|
||||||
dc_device_t base;
|
dc_device_t base;
|
||||||
|
dc_usbhid_t *usbhid;
|
||||||
libusb_context *ctx;
|
|
||||||
libusb_device_handle *handle;
|
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
unsigned short seq;
|
unsigned short seq;
|
||||||
unsigned char version[0x30];
|
unsigned char version[0x30];
|
||||||
@ -143,13 +130,13 @@ static void put_le32(unsigned int val, unsigned char *p)
|
|||||||
static int receive_packet(suunto_eonsteel_device_t *eon, unsigned char *buffer, int size)
|
static int receive_packet(suunto_eonsteel_device_t *eon, unsigned char *buffer, int size)
|
||||||
{
|
{
|
||||||
unsigned char buf[64];
|
unsigned char buf[64];
|
||||||
const int InEndpoint = 0x82;
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
int rc, transferred, len;
|
size_t transferred = 0;
|
||||||
|
int len;
|
||||||
|
|
||||||
/* 5000 = 5s timeout */
|
rc = dc_usbhid_read(eon->usbhid, buf, PACKET_SIZE, &transferred);
|
||||||
rc = libusb_interrupt_transfer(eon->handle, InEndpoint, buf, PACKET_SIZE, &transferred, 5000);
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
if (rc) {
|
ERROR(eon->base.context, "read interrupt transfer failed");
|
||||||
ERROR(eon->base.context, "read interrupt transfer failed (%s)", libusb_error_name(rc));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (transferred != PACKET_SIZE) {
|
if (transferred != PACKET_SIZE) {
|
||||||
@ -179,11 +166,11 @@ static int send_cmd(suunto_eonsteel_device_t *eon,
|
|||||||
unsigned int len,
|
unsigned int len,
|
||||||
const unsigned char *buffer)
|
const unsigned char *buffer)
|
||||||
{
|
{
|
||||||
const int OutEndpoint = 0x02;
|
|
||||||
unsigned char buf[64];
|
unsigned char buf[64];
|
||||||
int transferred, rc;
|
|
||||||
unsigned short seq = eon->seq;
|
unsigned short seq = eon->seq;
|
||||||
unsigned int magic = eon->magic;
|
unsigned int magic = eon->magic;
|
||||||
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
|
size_t transferred = 0;
|
||||||
|
|
||||||
// Two-byte packet header, followed by 12 bytes of extended header
|
// Two-byte packet header, followed by 12 bytes of extended header
|
||||||
if (len > sizeof(buf)-2-12) {
|
if (len > sizeof(buf)-2-12) {
|
||||||
@ -213,8 +200,8 @@ static int send_cmd(suunto_eonsteel_device_t *eon,
|
|||||||
memcpy(buf+14, buffer, len);
|
memcpy(buf+14, buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libusb_interrupt_transfer(eon->handle, OutEndpoint, buf, sizeof(buf), &transferred, 5000);
|
rc = dc_usbhid_write(eon->usbhid, buf, sizeof(buf), &transferred);
|
||||||
if (rc < 0) {
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
ERROR(eon->base.context, "write interrupt transfer failed");
|
ERROR(eon->base.context, "write interrupt transfer failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -525,22 +512,25 @@ static int get_file_list(suunto_eonsteel_device_t *eon, struct directory_entry *
|
|||||||
|
|
||||||
static int initialize_eonsteel(suunto_eonsteel_device_t *eon)
|
static int initialize_eonsteel(suunto_eonsteel_device_t *eon)
|
||||||
{
|
{
|
||||||
const int InEndpoint = 0x82;
|
|
||||||
const unsigned char init[] = {0x02, 0x00, 0x2a, 0x00};
|
const unsigned char init[] = {0x02, 0x00, 0x2a, 0x00};
|
||||||
unsigned char buf[64];
|
unsigned char buf[64];
|
||||||
struct eon_hdr hdr;
|
struct eon_hdr hdr;
|
||||||
|
|
||||||
|
dc_usbhid_set_timeout(eon->usbhid, 10);
|
||||||
|
|
||||||
/* Get rid of any pending stale input first */
|
/* Get rid of any pending stale input first */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int transferred;
|
size_t transferred = 0;
|
||||||
|
|
||||||
int rc = libusb_interrupt_transfer(eon->handle, InEndpoint, buf, sizeof(buf), &transferred, 10);
|
dc_status_t rc = dc_usbhid_read(eon->usbhid, buf, sizeof(buf), &transferred);
|
||||||
if (rc < 0)
|
if (rc != DC_STATUS_SUCCESS)
|
||||||
break;
|
break;
|
||||||
if (!transferred)
|
if (!transferred)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc_usbhid_set_timeout(eon->usbhid, 5000);
|
||||||
|
|
||||||
if (send_cmd(eon, INIT_CMD, sizeof(init), init)) {
|
if (send_cmd(eon, INIT_CMD, sizeof(init), init)) {
|
||||||
ERROR(eon->base.context, "Failed to send initialization command");
|
ERROR(eon->base.context, "Failed to send initialization command");
|
||||||
return -1;
|
return -1;
|
||||||
@ -576,39 +566,24 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char
|
|||||||
memset (eon->version, 0, sizeof (eon->version));
|
memset (eon->version, 0, sizeof (eon->version));
|
||||||
memset (eon->fingerprint, 0, sizeof (eon->fingerprint));
|
memset (eon->fingerprint, 0, sizeof (eon->fingerprint));
|
||||||
|
|
||||||
if (libusb_init(&eon->ctx)) {
|
status = dc_usbhid_open(&eon->usbhid, context, 0x1493, 0x0030);
|
||||||
ERROR(context, "libusb_init() failed");
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
status = DC_STATUS_IO;
|
ERROR(context, "unable to open device");
|
||||||
goto error_free;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
eon->handle = libusb_open_device_with_vid_pid(eon->ctx, 0x1493, 0x0030);
|
|
||||||
if (!eon->handle) {
|
|
||||||
ERROR(context, "unable to open device");
|
|
||||||
status = DC_STATUS_IO;
|
|
||||||
goto error_usb_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102)
|
|
||||||
libusb_set_auto_detach_kernel_driver(eon->handle, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
libusb_claim_interface(eon->handle, 0);
|
|
||||||
|
|
||||||
if (initialize_eonsteel(eon) < 0) {
|
if (initialize_eonsteel(eon) < 0) {
|
||||||
ERROR(context, "unable to initialize device");
|
ERROR(context, "unable to initialize device");
|
||||||
status = DC_STATUS_IO;
|
status = DC_STATUS_IO;
|
||||||
goto error_usb_close;
|
goto error_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = (dc_device_t *) eon;
|
*out = (dc_device_t *) eon;
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|
||||||
error_usb_close:
|
error_close:
|
||||||
libusb_close(eon->handle);
|
dc_usbhid_close(eon->usbhid);
|
||||||
error_usb_exit:
|
|
||||||
libusb_exit(eon->ctx);
|
|
||||||
error_free:
|
error_free:
|
||||||
free(eon);
|
free(eon);
|
||||||
return status;
|
return status;
|
||||||
@ -732,19 +707,7 @@ suunto_eonsteel_device_close(dc_device_t *abstract)
|
|||||||
{
|
{
|
||||||
suunto_eonsteel_device_t *eon = (suunto_eonsteel_device_t *) abstract;
|
suunto_eonsteel_device_t *eon = (suunto_eonsteel_device_t *) abstract;
|
||||||
|
|
||||||
libusb_close(eon->handle);
|
dc_usbhid_close(eon->usbhid);
|
||||||
libusb_exit(eon->ctx);
|
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // no LIBUSB support
|
|
||||||
|
|
||||||
dc_status_t
|
|
||||||
suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char *name, unsigned int model)
|
|
||||||
{
|
|
||||||
ERROR(context, "The Suunto EON Steel backend needs libusb-1.0");
|
|
||||||
return DC_STATUS_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user