Browse files

FreeBSD: Add FreeBSD implementation.

This adds a FreeBSD implementation to HIDAPI using the libusb back-end. The
libusb/ folder now contains the libusb implementation and associated
Makefiles for Linux and FreeBSD. All libusb code has been removed from the
linux/ folder, so that the code in libusb/ can be shared by both (and
future) platforms.

This commit renames linux/hid-libusb.c to libusb/hid.c. Make sure to
use git log --follow to see full history of that file.

This code was written by:
 Alex Dupre <ale@FreeBSD.org>
 Alan Ott <alan@signal11.us>
  • Loading branch information...
1 parent c30dfd8 commit 74440e2dbbba80b4abcc4304ddae9e484231b72d @signal11 committed May 1, 2012
View
21 README.txt
@@ -1,17 +1,19 @@
-HID API for Windows, Linux, and Mac OS X
+HID API for Windows, Linux, FreeBSD and Mac OS X
About
------
HIDAPI is a multi-platform library which allows an application to interface
-with USB and Bluetooth HID-Class devices on Windows, Linux, and Mac OS X.
-On Windows, a DLL is built. On other platforms (and optionally on Windows),
-the single source file can simply be dropped into a target application.
+with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and Mac
+OS X. On Windows, a DLL is built. On other platforms (and optionally on
+Windows), the single source file can simply be dropped into a target
+application.
HIDAPI has four back-ends:
* Windows (using hid.dll)
* Linux/hidraw (using the Kernel's hidraw driver)
* Linux/libusb (using libusb-1.0)
+ * FreeBSD (using libusb-1.0)
* Mac (using IOHidManager)
On Linux, either the hidraw or the libusb back-end can be used. There are
@@ -26,7 +28,7 @@ hidraw nodes associated with them. Keyboards, mice, and some other devices
which are blacklisted from having hidraw nodes will not work. Fortunately,
for nearly all the uses of hidraw, this is not a problem.
-Linux/libusb (linux/hid-libusb.c):
+Linux/FreeBSD/libusb (libusb/hid-libusb.c):
This back-end uses libusb-1.0 to communicate directly to a USB device. This
back-end will of course not work with Bluetooth devices.
@@ -110,14 +112,19 @@ To build the console test program:
Windows:
Build the .sln file in the windows/ directory.
Linux:
- cd to the linux/ directory and run make.
+ For the hidraw implementation, cd to the linux/ directory and run make.
+ For the libusb implementation, cd to the libusb/ directory and run make.
+ FreeBSD:
+ cd to the libusb/ directory and run gmake.
Mac OS X:
cd to the mac/ directory and run make.
To build the Test GUI:
The test GUI uses Fox toolkit, available from www.fox-toolkit.org.
On Debian-based systems such as Ubuntu, install Fox using the following:
sudo apt-get install libfox-1.6-dev
+ On FreeBSD, install iconv and Fox as root:
+ pkg_add -r gmake libiconv fox16
On Mac OSX, install Fox from ports:
sudo port install fox
On Windows, download the hidapi-externals.zip file from the main download
@@ -132,6 +139,7 @@ To build the Test GUI:
Then to build:
On Windows, build the .sln file in the testgui/ directory.
On Linux and Mac, run make from the testgui/ directory.
+ On FreeBSD, run gmake from the testgui/ directory.
To build using the DDK (old method):
@@ -151,3 +159,4 @@ To build using the DDK (old method):
Signal 11 Software - 2010-04-11
2010-07-28
2011-09-10
+ 2012-05-01
View
4 libusb/.gitignore
@@ -0,0 +1,4 @@
+*.o
+*.so
+hidtest
+hidtest-libusb
View
18 libusb/Makefile
@@ -0,0 +1,18 @@
+
+
+OS=$(shell uname)
+
+ifeq ($(OS), Linux)
+ FILE=Makefile.linux
+endif
+
+ifeq ($(OS), FreeBSD)
+ FILE=Makefile.freebsd
+endif
+
+ifeq ($(FILE), )
+all:
+ $(error Your platform ${OS} is not supported by hidapi/libusb at this time.)
+endif
+
+include $(FILE)
View
46 libusb/Makefile.freebsd
@@ -0,0 +1,46 @@
+###########################################
+# Simple Makefile for HIDAPI test program
+#
+# Alan Ott
+# Signal 11 Software
+# 2010-06-01
+###########################################
+
+all: hidtest libs
+
+libs: libhidapi.so
+
+CC ?= cc
+CFLAGS ?= -Wall -g -fPIC
+
+CXX ?= c++
+CXXFLAGS ?= -Wall -g
+
+COBJS = hid.o
+CPPOBJS = ../hidtest/hidtest.o
+OBJS = $(COBJS) $(CPPOBJS)
+INCLUDES = -I../hidapi -I/usr/local/include
+LDFLAGS = -L/usr/local/lib
+LIBS = -lusb -liconv -pthread
+
+
+# Console Test Program
+hidtest: $(OBJS)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
+
+# Shared Libs
+libhidapi.so: $(COBJS)
+ $(CC) $(LDFLAGS) -shared -Wl,-soname,$@.0 $^ -o $@
+
+# Objects
+$(COBJS): %.o: %.c
+ $(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@
+
+$(CPPOBJS): %.o: %.cpp
+ $(CXX) $(CXXFLAGS) -c $(INCLUDES) $< -o $@
+
+
+clean:
+ rm -f $(OBJS) hidtest libhidapi.so ../hidtest/hidtest.o
+
+.PHONY: clean libs
View
49 libusb/Makefile.linux
@@ -0,0 +1,49 @@
+###########################################
+# Simple Makefile for HIDAPI test program
+#
+# Alan Ott
+# Signal 11 Software
+# 2010-06-01
+###########################################
+
+all: hidtest-libusb libs
+
+libs: libhidapi-libusb.so
+
+CC ?= gcc
+CFLAGS ?= -Wall -g -fpic
+
+CXX ?= g++
+CXXFLAGS ?= -Wall -g -fpic
+
+LDFLAGS ?= -Wall -g
+
+COBJS_LIBUSB = hid.o
+COBJS = $(COBJS_LIBUSB)
+CPPOBJS = ../hidtest/hidtest.o
+OBJS = $(COBJS) $(CPPOBJS)
+LIBS_USB = `pkg-config libusb-1.0 --libs` -lrt
+LIBS = $(LIBS_USB)
+INCLUDES ?= -I../hidapi `pkg-config libusb-1.0 --cflags`
+
+
+# Console Test Program
+hidtest-libusb: $(COBJS_LIBUSB) $(CPPOBJS)
+ $(CXX) $(LDFLAGS) $^ $(LIBS_USB) -o $@
+
+# Shared Libs
+libhidapi-libusb.so: $(COBJS_LIBUSB)
+ $(CC) $(LDFLAGS) $(LIBS_USB) -shared -fpic -Wl,-soname,$@.0 $^ -o $@
+
+# Objects
+$(COBJS): %.o: %.c
+ $(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@
+
+$(CPPOBJS): %.o: %.cpp
+ $(CXX) $(CXXFLAGS) -c $(INCLUDES) $< -o $@
+
+
+clean:
+ rm -f $(OBJS) hidtest-libusb libhidapi-libusb.so ../hidtest/hidtest.o
+
+.PHONY: clean libs
View
44 linux/hid-libusb.c → libusb/hid.c
@@ -8,6 +8,7 @@
8/22/2009
Linux Version - 6/2/2010
Libusb Version - 8/13/2010
+ FreeBSD Version - 11/1/2011
Copyright 2009, All Rights Reserved.
@@ -62,7 +63,7 @@ extern "C" {
/* Uncomment to enable the retrieval of Usage and Usage Page in
hid_enumerate(). Warning, this is very invasive as it requires the detach
and re-attach of the kernel driver. See comments inside hid_enumerate().
-Linux/libusb HIDAPI programs are encouraged to use the interface number
+libusb HIDAPI programs are encouraged to use the interface number
instead to differentiate between interfaces on a composite HID device. */
/*#define INVASIVE_GET_USAGE*/
@@ -146,7 +147,7 @@ static void free_hid_device(hid_device *dev)
}
#if 0
-//TODO: Implement this funciton on Linux.
+//TODO: Implement this funciton on hidapi/libusb..
static void register_error(hid_device *device, const char *op)
{
@@ -255,6 +256,27 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
}
#endif // INVASIVE_GET_USAGE
+#ifdef __FreeBSD__
+/* The FreeBSD version of libusb doesn't have this funciton. In mainline
+ libusb, it's inlined in libusb.h. This function will bear a striking
+ resemblence to that one, because there's about one way to code it.
+
+ Note that the data parameter is Unicode in UTF-16LE encoding.
+ Return value is the number of bytes in data, or LIBUSB_ERROR_*.
+ */
+static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
+ uint8_t descriptor_index, uint16_t lang_id,
+ unsigned char *data, int length)
+{
+ return libusb_control_transfer(dev,
+ LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */
+ LIBUSB_REQUEST_GET_DESCRIPTOR,
+ (LIBUSB_DT_STRING << 8) | descriptor_index,
+ lang_id, data, (uint16_t) length, 1000);
+}
+
+#endif
+
/* Get the first language the device says it reports. This comes from
USB string #0. */
@@ -317,7 +339,11 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
size_t inbytes;
size_t outbytes;
size_t res;
+#ifdef __FreeBSD__
+ const char *inptr;
+#else
char *inptr;
+#endif
char *outptr;
/* Determine which language to use. */
@@ -341,27 +367,31 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
buf[len+1] = '\0';
/* Initialize iconv. */
- ic = iconv_open("UTF-32", "UTF-16");
- if (ic == (iconv_t)-1)
+ ic = iconv_open("WCHAR_T", "UTF-16LE");
+ if (ic == (iconv_t)-1) {
+ LOG("iconv_open() failed\n");
return NULL;
+ }
- /* Convert to UTF-32 (wchar_t on glibc systems).
+ /* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
Skip the first character (2-bytes). */
inptr = buf+2;
inbytes = len-2;
outptr = (char*) wbuf;
outbytes = sizeof(wbuf);
res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
- if (res == (size_t)-1)
+ if (res == (size_t)-1) {
+ LOG("iconv() failed\n");
goto err;
+ }
/* Write the terminating NULL. */
wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
if (outbytes >= sizeof(wbuf[0]))
*((wchar_t*)outptr) = 0x00000000;
/* Allocate and copy the string. */
- str = wcsdup(wbuf+1);
+ str = wcsdup(wbuf);
err:
iconv_close(ic);
View
18 linux/Makefile
@@ -6,9 +6,9 @@
# 2010-06-01
###########################################
-all: hidtest-hidraw hidtest-libusb libs
+all: hidtest-hidraw libs
-libs: libhidapi-libusb.so libhidapi-hidraw.so
+libs: libhidapi-hidraw.so
CC ?= gcc
CFLAGS ?= -Wall -g -fpic
@@ -18,28 +18,20 @@ CXXFLAGS ?= -Wall -g -fpic
LDFLAGS ?= -Wall -g
-COBJS_LIBUSB = hid-libusb.o
+
COBJS_HIDRAW = hid.o
-COBJS = $(COBJS_LIBUSB) $(COBJS_HIDRAW)
CPPOBJS = ../hidtest/hidtest.o
OBJS = $(COBJS) $(CPPOBJS)
-LIBS_USB = `pkg-config libusb-1.0 --libs` -lrt
LIBS_UDEV = `pkg-config libudev --libs` -lrt
-LIBS = $(LIBS_USB) $(LIBS_UDEV)
+LIBS = $(LIBS_UDEV)
INCLUDES ?= -I../hidapi `pkg-config libusb-1.0 --cflags`
# Console Test Program
hidtest-hidraw: $(COBJS_HIDRAW) $(CPPOBJS)
$(CXX) $(LDFLAGS) $^ $(LIBS_UDEV) -o $@
-hidtest-libusb: $(COBJS_LIBUSB) $(CPPOBJS)
- $(CXX) $(LDFLAGS) $^ $(LIBS_USB) -o $@
-
# Shared Libs
-libhidapi-libusb.so: $(COBJS_LIBUSB)
- $(CC) $(LDFLAGS) $(LIBS_USB) -shared -fpic -Wl,-soname,$@.0 $^ -o $@
-
libhidapi-hidraw.so: $(COBJS_HIDRAW)
$(CC) $(LDFLAGS) $(LIBS_UDEV) -shared -fpic -Wl,-soname,$@.0 $^ -o $@
@@ -52,6 +44,6 @@ $(CPPOBJS): %.o: %.cpp
clean:
- rm -f $(OBJS) hidtest-libusb hidtest-hidraw libhidapi-libusb.so libhidapi-hidraw.so ../hidtest/hidtest.o
+ rm -f $(OBJS) hidtest-hidraw libhidapi-hidraw.so ../hidtest/hidtest.o
.PHONY: clean libs
View
4 testgui/Makefile
@@ -14,6 +14,10 @@ ifeq ($(OS), Linux)
FILE=Makefile.linux
endif
+ifeq ($(OS), FreeBSD)
+ FILE=Makefile.freebsd
+endif
+
ifeq ($(FILE), )
all:
$(error Your platform ${OS} is not supported at this time.)
View
33 testgui/Makefile.freebsd
@@ -0,0 +1,33 @@
+###########################################
+# Simple Makefile for HIDAPI test program
+#
+# Alan Ott
+# Signal 11 Software
+# 2010-06-01
+###########################################
+
+all: testgui
+
+CC=cc
+CXX=c++
+COBJS=../libusb/hid.o
+CPPOBJS=test.o
+OBJS=$(COBJS) $(CPPOBJS)
+CFLAGS=-I../hidapi -I/usr/local/include `fox-config --cflags` -Wall -g -c
+LDFLAGS= -L/usr/local/lib
+LIBS= -lusb -liconv `fox-config --libs` -pthread
+
+
+testgui: $(OBJS)
+ $(CXX) -Wall -g $^ $(LDFLAGS) -o $@ $(LIBS)
+
+$(COBJS): %.o: %.c
+ $(CC) $(CFLAGS) $< -o $@
+
+$(CPPOBJS): %.o: %.cpp
+ $(CXX) $(CFLAGS) $< -o $@
+
+clean:
+ rm *.o testgui
+
+.PHONY: clean
View
2 testgui/Makefile.linux
@@ -10,7 +10,7 @@ all: testgui
CC=gcc
CXX=g++
-COBJS=../linux/hid-libusb.o
+COBJS=../libusb/hid.o
CPPOBJS=test.o
OBJS=$(COBJS) $(CPPOBJS)
CFLAGS=-I../hidapi -Wall -g -c `fox-config --cflags` `pkg-config libusb-1.0 --cflags`

0 comments on commit 74440e2

Please sign in to comment.