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>
This commit is contained in:
Alan Ott
2012-05-01 13:39:39 -04:00
parent c30dfd8c97
commit 74440e2dbb
10 changed files with 212 additions and 27 deletions
+15 -6
View File
@@ -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,7 +112,10 @@ 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.
@@ -118,6 +123,8 @@ 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
+4
View File
@@ -0,0 +1,4 @@
*.o
*.so
hidtest
hidtest-libusb
+18
View File
@@ -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)
+46
View File
@@ -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
+49
View File
@@ -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
+37 -7
View File
@@ -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,19 +367,23 @@ 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;
@@ -361,7 +391,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
*((wchar_t*)outptr) = 0x00000000;
/* Allocate and copy the string. */
str = wcsdup(wbuf+1);
str = wcsdup(wbuf);
err:
iconv_close(ic);
+5 -13
View File
@@ -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,14 +18,12 @@ 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`
@@ -33,13 +31,7 @@ INCLUDES ?= -I../hidapi `pkg-config libusb-1.0 --cflags`
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
+4
View File
@@ -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.)
+33
View File
@@ -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
+1 -1
View File
@@ -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`