Use hidapi for Suunto EON Steel on Mac

libusb on Mac doesn't support HID devices.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2015-10-17 17:41:36 -07:00
parent 138fd856bd
commit 058538e628
3 changed files with 62 additions and 3 deletions

View File

@ -80,6 +80,13 @@ if test "$have_libusb" = "yes"; then
AC_SUBST([DEPENDENCIES], [libusb-1.0])
fi
# Checks for hidapi support.
PKG_CHECK_MODULES([HIDAPI], [hidapi], [have_hidapi=yes], [have_hidapi=no])
if test "$have_hidapi" = "yes"; then
AC_DEFINE([HAVE_HIDAPI], [1], [hidapi support])
AC_SUBST([DEPENDENCIES], [hidapi])
fi
# Checks for IrDA support.
AC_CHECK_HEADERS([winsock2.h af_irda.h], [irda_win32=yes], [irda_win32=no], [
#if HAVE_WINSOCK2_H

View File

@ -1,9 +1,9 @@
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
AM_CFLAGS = $(LIBUSB_CFLAGS)
AM_CFLAGS = $(LIBUSB_CFLAGS) $(HIDAPI_CFLAGS)
lib_LTLIBRARIES = libdivecomputer.la
libdivecomputer_la_LIBADD = $(LIBUSB_LIBS)
libdivecomputer_la_LIBADD = $(LIBUSB_LIBS) $(HIDAPI_LIBS)
libdivecomputer_la_LDFLAGS = \
-version-info $(DC_VERSION_LIBTOOL) \
-no-undefined \

View File

@ -37,6 +37,9 @@
#define snprintf _snprintf
#endif
#if __APPLE__ && HAVE_HIDAPI
#include "hidapi/hidapi.h"
#endif
#ifdef HAVE_LIBUSB
#ifdef _WIN32
@ -49,7 +52,11 @@ typedef struct suunto_eonsteel_device_t {
dc_device_t base;
libusb_context *ctx;
#if __APPLE__ && HAVE_HIDAPI
hid_device *handle;
#else
libusb_device_handle *handle;
#endif
unsigned int magic;
unsigned short seq;
} suunto_eonsteel_device_t;
@ -143,7 +150,12 @@ static int receive_packet(suunto_eonsteel_device_t *eon, unsigned char *buffer,
int rc, transferred, len;
/* 5000 = 5s timeout */
#if __APPLE__ && HAVE_HIDAPI
transferred = hid_read_timeout(eon->handle, buf, PACKET_SIZE, 5000);
rc = (transferred <= 0) ? -1 : 0;
#else
rc = libusb_interrupt_transfer(eon->handle, InEndpoint, buf, PACKET_SIZE, &transferred, 5000);
#endif
if (rc) {
ERROR(eon->base.context, "read interrupt transfer failed (%s)", libusb_error_name(rc));
return -1;
@ -209,7 +221,13 @@ static int send_cmd(suunto_eonsteel_device_t *eon,
memcpy(buf+14, buffer, len);
}
#if __APPLE__ && HAVE_HIDAPI
/* there is no write with timeout */
transferred = hid_write(eon->handle, buf, PACKET_SIZE);
rc = (transferred <= 0) ? -1 : 0;
#else
rc = libusb_interrupt_transfer(eon->handle, OutEndpoint, buf, sizeof(buf), &transferred, 5000);
#endif
if (rc < 0) {
ERROR(eon->base.context, "write interrupt transfer failed");
return -1;
@ -530,7 +548,12 @@ static int initialize_eonsteel(suunto_eonsteel_device_t *eon)
for (;;) {
int transferred;
#if __APPLE__ && HAVE_HIDAPI
transferred = hid_read_timeout(eon->handle, buf, sizeof(buf), 10);
int rc = (transferred <= 0) ? -1 : 0;
#else
int rc = libusb_interrupt_transfer(eon->handle, InEndpoint, buf, sizeof(buf), &transferred, 10);
#endif
if (rc < 0)
break;
if (!transferred)
@ -572,6 +595,24 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char
// Set up the libdivecomputer interfaces
device_init(&eon->base, context, &suunto_eonsteel_device_vtable);
#if __APPLE__ && HAVE_HIDAPI
if (hid_init()) {
ERROR(context, "hid_init() failed");
free(eon);
return DC_STATUS_IO;
}
eon->handle = hid_open(0x1493, 0x0030, NULL);
if (!eon->handle) {
ERROR(context, "unable to open device");
hid_exit();
free(eon);
return DC_STATUS_IO;
}
#else
if (libusb_init(&eon->ctx)) {
ERROR(context, "libusb_init() failed");
free(eon);
@ -591,11 +632,16 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char
#endif
libusb_claim_interface(eon->handle, 0);
#endif
if (initialize_eonsteel(eon) < 0) {
ERROR(context, "unable to initialize device");
#if __APPLE__ && HAVE_HIDAPI
hid_close(eon->handle);
hid_exit();
#else
libusb_close(eon->handle);
libusb_exit(eon->ctx);
#endif
free(eon);
return DC_STATUS_IO;
}
@ -688,8 +734,14 @@ suunto_eonsteel_device_close(dc_device_t *abstract)
{
suunto_eonsteel_device_t *eon = (suunto_eonsteel_device_t *) abstract;
#if __APPLE__ && HAVE_HIDAPI
hid_close(eon->handle);
hid_exit();
#else
libusb_close(eon->handle);
libusb_exit(eon->ctx);
#endif
free(eon);
return DC_STATUS_SUCCESS;