Use the hidapi library on Mac OS X.
On Mac OS X, libusb doesn't work for USB HID devices. We can use the hidapi library instead. Although the hidapi library supports Linux and Windows too, we keep using libusb there to avoid the extra dependency.
This commit is contained in:
parent
bae6cb856e
commit
ed2a7c91fe
19
configure.ac
19
configure.ac
@ -73,6 +73,8 @@ esac
|
||||
AC_MSG_RESULT([$os_win32])
|
||||
AM_CONDITIONAL([OS_WIN32], [test "$os_win32" = "yes"])
|
||||
|
||||
DEPENDENCIES=""
|
||||
|
||||
# Checks for USB support.
|
||||
AC_ARG_WITH([libusb],
|
||||
[AS_HELP_STRING([--without-libusb],
|
||||
@ -82,10 +84,25 @@ AS_IF([test "x$with_libusb" != "xno"], [
|
||||
PKG_CHECK_MODULES([LIBUSB], [libusb-1.0], [have_libusb=yes], [have_libusb=no])
|
||||
AS_IF([test "x$have_libusb" = "xyes"], [
|
||||
AC_DEFINE([HAVE_LIBUSB], [1], [libusb library])
|
||||
AC_SUBST([DEPENDENCIES], [libusb-1.0])
|
||||
DEPENDENCIES="$DEPENDENCIES libusb-1.0"
|
||||
])
|
||||
])
|
||||
|
||||
# Checks for HIDAPI support.
|
||||
AC_ARG_WITH([hidapi],
|
||||
[AS_HELP_STRING([--without-hidapi],
|
||||
[Build without the hidapi library])],
|
||||
[], [with_hidapi=auto])
|
||||
AS_IF([test "x$with_hidapi" != "xno"], [
|
||||
PKG_CHECK_MODULES([HIDAPI], [hidapi], [have_hidapi=yes], [have_hidapi=no])
|
||||
AS_IF([test "x$have_hidapi" = "xyes"], [
|
||||
AC_DEFINE([HAVE_HIDAPI], [1], [hidapi library])
|
||||
DEPENDENCIES="$DEPENDENCIES hidapi"
|
||||
])
|
||||
])
|
||||
|
||||
AC_SUBST([DEPENDENCIES])
|
||||
|
||||
# Checks for IrDA support.
|
||||
AC_CHECK_HEADERS([winsock2.h af_irda.h], [irda_win32=yes], [irda_win32=no], [
|
||||
#if HAVE_WINSOCK2_H
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
AM_CFLAGS = $(LIBUSB_CFLAGS) -DENABLE_DEPRECATED
|
||||
AM_CFLAGS = $(LIBUSB_CFLAGS) $(HIDAPI_CFLAGS) -DENABLE_DEPRECATED
|
||||
|
||||
lib_LTLIBRARIES = libdivecomputer.la
|
||||
|
||||
libdivecomputer_la_LIBADD = $(LIBUSB_LIBS) -lm
|
||||
libdivecomputer_la_LIBADD = $(LIBUSB_LIBS) $(HIDAPI_LIBS) -lm
|
||||
libdivecomputer_la_LDFLAGS = \
|
||||
-version-info $(DC_VERSION_LIBTOOL) \
|
||||
-no-undefined \
|
||||
|
||||
69
src/usbhid.c
69
src/usbhid.c
@ -25,11 +25,13 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
#ifdef _WIN32
|
||||
#define NOGDI
|
||||
#endif
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
#include <hidapi/hidapi.h>
|
||||
#endif
|
||||
|
||||
#include "usbhid.h"
|
||||
@ -40,17 +42,20 @@ struct dc_usbhid_t {
|
||||
/* Library context. */
|
||||
dc_context_t *context;
|
||||
/* Internal state. */
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
libusb_context *ctx;
|
||||
libusb_device_handle *handle;
|
||||
int interface;
|
||||
unsigned char endpoint_in;
|
||||
unsigned char endpoint_out;
|
||||
unsigned int timeout;
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
hid_device *handle;
|
||||
int timeout;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
static dc_status_t
|
||||
syserror(int errcode)
|
||||
{
|
||||
@ -95,7 +100,7 @@ dc_usbhid_open (dc_usbhid_t **out, dc_context_t *context, unsigned int vid, unsi
|
||||
// Library context.
|
||||
usbhid->context = context;
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
struct libusb_device **devices = NULL;
|
||||
struct libusb_config_descriptor *config = NULL;
|
||||
|
||||
@ -226,13 +231,33 @@ dc_usbhid_open (dc_usbhid_t **out, dc_context_t *context, unsigned int vid, unsi
|
||||
|
||||
libusb_free_config_descriptor (config);
|
||||
libusb_free_device_list (devices, 1);
|
||||
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
|
||||
// Initialize the hidapi library.
|
||||
rc = hid_init();
|
||||
if (rc < 0) {
|
||||
ERROR (context, "Failed to initialize usb support.");
|
||||
status = DC_STATUS_IO;
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
// Open the USB device.
|
||||
usbhid->handle = hid_open (vid, pid, NULL);
|
||||
if (usbhid->handle == NULL) {
|
||||
ERROR (context, "Failed to open the usb device.");
|
||||
status = DC_STATUS_IO;
|
||||
goto error_hid_exit;
|
||||
}
|
||||
|
||||
usbhid->timeout = -1;
|
||||
#endif
|
||||
|
||||
*out = usbhid;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
error_usb_close:
|
||||
libusb_close (usbhid->handle);
|
||||
error_usb_free_config:
|
||||
@ -241,6 +266,9 @@ error_usb_free_list:
|
||||
libusb_free_device_list (devices, 1);
|
||||
error_usb_exit:
|
||||
libusb_exit (usbhid->ctx);
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
error_hid_exit:
|
||||
hid_exit ();
|
||||
#endif
|
||||
error_free:
|
||||
free (usbhid);
|
||||
@ -255,10 +283,13 @@ dc_usbhid_close (dc_usbhid_t *usbhid)
|
||||
if (usbhid == NULL)
|
||||
return DC_STATUS_SUCCESS;
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
libusb_release_interface (usbhid->handle, usbhid->interface);
|
||||
libusb_close (usbhid->handle);
|
||||
libusb_exit (usbhid->ctx);
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
hid_close(usbhid->handle);
|
||||
hid_exit();
|
||||
#endif
|
||||
free (usbhid);
|
||||
|
||||
@ -273,7 +304,7 @@ dc_usbhid_set_timeout (dc_usbhid_t *usbhid, int timeout)
|
||||
|
||||
INFO (usbhid->context, "Timeout: value=%i", timeout);
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
if (timeout < 0) {
|
||||
usbhid->timeout = 0;
|
||||
} else if (timeout == 0) {
|
||||
@ -281,6 +312,12 @@ dc_usbhid_set_timeout (dc_usbhid_t *usbhid, int timeout)
|
||||
} else {
|
||||
usbhid->timeout = timeout;
|
||||
}
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
if (timeout < 0) {
|
||||
usbhid->timeout = -1;
|
||||
} else {
|
||||
usbhid->timeout = timeout;
|
||||
}
|
||||
#endif
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -297,7 +334,7 @@ dc_usbhid_read (dc_usbhid_t *usbhid, void *data, size_t size, size_t *actual)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
int rc = libusb_interrupt_transfer (usbhid->handle, usbhid->endpoint_in, data, size, &nbytes, usbhid->timeout);
|
||||
if (rc != LIBUSB_SUCCESS) {
|
||||
ERROR (usbhid->context, "Usb read interrupt transfer failed (%s).",
|
||||
@ -305,6 +342,13 @@ dc_usbhid_read (dc_usbhid_t *usbhid, void *data, size_t size, size_t *actual)
|
||||
status = syserror (rc);
|
||||
goto out;
|
||||
}
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
nbytes = hid_read_timeout(usbhid->handle, data, size, usbhid->timeout);
|
||||
if (nbytes < 0) {
|
||||
ERROR (usbhid->context, "Usb read interrupt transfer failed.");
|
||||
status = DC_STATUS_IO;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
out:
|
||||
@ -327,7 +371,7 @@ dc_usbhid_write (dc_usbhid_t *usbhid, const void *data, size_t size, size_t *act
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
int rc = libusb_interrupt_transfer (usbhid->handle, usbhid->endpoint_out, (void *) data, size, &nbytes, 0);
|
||||
if (rc != LIBUSB_SUCCESS) {
|
||||
ERROR (usbhid->context, "Usb write interrupt transfer failed (%s).",
|
||||
@ -335,6 +379,13 @@ dc_usbhid_write (dc_usbhid_t *usbhid, const void *data, size_t size, size_t *act
|
||||
status = syserror (rc);
|
||||
goto out;
|
||||
}
|
||||
#elif defined(HAVE_HIDAPI)
|
||||
nbytes = hid_write(usbhid->handle, data, size);
|
||||
if (nbytes < 0) {
|
||||
ERROR (usbhid->context, "Usb write interrupt transfer failed.");
|
||||
status = DC_STATUS_IO;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
out:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user