Attached is a super rough (did it in 20 minutes at the airport) patch to move
concordance to libhid, which is required to make things work in Mac, and may
also make windows support more consistent. Maybe.

Anyway, as of this point, it compiles, but I'm on a laptop in an airport and
have no idea if it actually works... someone wanna try this (in Linux, it's
not yet ready for Mac), and lemme know how it goes?


-- 
Phil Dibowitz                             p...@ipom.com
Open Source software and tech docs        Insanity Palace of Metallica
http://www.phildev.net/                   http://www.ipom.com/

"Be who you are and say what you feel, because those who mind don't matter
 and those who matter don't mind."
 - Dr. Seuss

commit dcd161927271087d6649c14f215f8236603576c0
Author: Phil Dibowitz <p...@ipom.com>
Date:   Mon May 6 18:22:18 2013 -0700

    first run at libhid

diff --git a/libconcord/Makefile.am b/libconcord/Makefile.am
index 3293967..7d07dce 100644
--- a/libconcord/Makefile.am
+++ b/libconcord/Makefile.am
@@ -2,11 +2,11 @@
 ACLOCAL_AMFLAGS= -I m4
 lib_LTLIBRARIES = libconcord.la
 libconcord_la_SOURCES = remote.cpp remote_z.cpp libconcord.cpp binaryfile.cpp \
-	web.cpp libusb/libusbhid.cpp usblan.cpp binaryfile.h hid.h protocol_z.h \
+	web.cpp libusb/libhid.cpp usblan.cpp binaryfile.h hid.h protocol_z.h \
 	 remote_info.h web.h protocol.h remote.h usblan.h xml_headers.h \
 	 operationfile.cpp remote_mh.cpp
 include_HEADERS = libconcord.h
-libconcord_la_LDFLAGS = -version-info 3:0:0 -lusb -lzzip
+libconcord_la_LDFLAGS = -version-info 3:0:0 -lhidapi-hidraw -lzzip
 UDEVROOT ?= /
 UDEVLIBDIR ?= $(UDEVROOT)/lib
 
diff --git a/libconcord/configure.ac b/libconcord/configure.ac
index 094e93f..5db5168 100644
--- a/libconcord/configure.ac
+++ b/libconcord/configure.ac
@@ -4,11 +4,11 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_PROG_LIBTOOL
 AC_PROG_CXX
 a=1
-AC_CHECK_HEADER(usb.h, [], [a=0])
-AC_CHECK_LIB(usb, usb_init, [], [a=0])
+AC_CHECK_HEADER(hidapi/hidapi.h, [], [a=0])
+#AC_CHECK_LIB(usb, usb_init, [], [a=0])
 if test $a == 0
 then
-	AC_MSG_ERROR([Error, libusb is missing!])
+	AC_MSG_ERROR([Error, hidapi is missing!])
 fi
 AC_CHECK_HEADER(zzip/lib.h, [], [a=0])
 AC_CHECK_LIB(zzip, zzip_dir_open, [], [a=0])
diff --git a/libconcord/libusb/libhid.cpp b/libconcord/libusb/libhid.cpp
new file mode 100644
index 0000000..7a60f34
--- /dev/null
+++ b/libconcord/libusb/libhid.cpp
@@ -0,0 +1,251 @@
+/*
+ * vi: formatoptions+=tc textwidth=80 tabstop=8 shiftwidth=8 noexpandtab:
+ *
+ * $Id$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright Kevin Timmerman 2007
+ * (C) Copyright Phil Dibowitz 2007
+ */
+
+#include "../lc_internal.h"
+#include "../libconcord.h"
+
+#ifdef LIBUSB
+
+#include "../hid.h"
+#ifdef WIN32
+#include "win/usb.h"
+#else
+#include <hidapi/hidapi.h>
+#endif
+#include <errno.h>
+#include <string.h>
+
+/*
+ * Harmonies either fall under logitech's VendorID (0x046d), and logitech's
+ * productID range for Harmonies (0xc110 - 0xc14f)...
+ *
+ * OR, they fall under 0x400/0xc359 (older 7-series, all 6-series).
+ */
+#define LOGITECH_VID 0x046D
+#define LOGITECH_MIN_PID 0xc110
+#define LOGITECH_MAX_PID 0xc14f
+#define NATIONAL_VID 0x0400
+#define NATIONAL_PID 0xc359
+
+hid_device *h_dev;
+/*
+static unsigned int irl;
+static unsigned int orl;
+static int ep_read = -1;
+static int ep_write = -1;
+*/
+
+int InitUSB()
+{
+//	usb_init();
+	return 0;
+}
+
+void ShutdownUSB()
+{
+//	if (h_hid) {
+//		usb_release_interface(h_hid,0);
+//	}
+}
+
+#if 0
+void check_ep(usb_endpoint_descriptor &ued)
+{
+	debug("address %02X attrib %02X max_length %i",
+		ued.bEndpointAddress, ued.bmAttributes,
+		ued.wMaxPacketSize);
+
+	if ((ued.bmAttributes & USB_ENDPOINT_TYPE_MASK) ==
+	    USB_ENDPOINT_TYPE_INTERRUPT) {
+		if (ued.bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+			if (ep_read == -1) {
+				ep_read = ued.bEndpointAddress;
+				// hack! todo: get from HID report descriptor
+				irl = ued.wMaxPacketSize;
+			}
+		} else {
+			if (ep_write == -1) {
+				ep_write = ued.bEndpointAddress;
+				// hack! todo: get from HID report descriptor
+				orl = ued.wMaxPacketSize;
+			}
+		}
+	}
+}
+#endif
+
+bool is_harmony(struct hid_device_info *dev)
+{
+	/* IF vendor == logitech AND product is in range of harmony
+	 *   OR vendor == National Semiconductor and product is harmony
+	 */
+	if ((dev->vendor_id == LOGITECH_VID
+	      && (dev->product_id >= LOGITECH_MIN_PID
+	          && dev->product_id <= LOGITECH_MAX_PID))
+	    || (dev->vendor_id == NATIONAL_VID
+	          && dev->product_id == NATIONAL_PID)) {
+		return true;
+	}
+	return false;
+}
+
+/*
+ * Find a HID device with VendorID == 0x046D ||
+ *    (VendorID == 0x0400 && ProductID == 0xC359)
+ */
+int FindRemote(THIDINFO &hid_info)
+{
+	struct hid_device_info *devs, *cur_dev;
+	bool found = false;
+	devs = hid_enumerate(0x0, 0x0);
+	cur_dev = devs; 
+	while (cur_dev) {
+		if (is_harmony(cur_dev)) {
+			h_dev = hid_open(cur_dev->vendor_id,
+					cur_dev->product_id,
+					NULL);
+			found = true;
+			break;
+		}
+		cur_dev = cur_dev->next;
+	}
+	hid_free_enumeration(devs);
+	if (!h_dev) {
+		debug("Failed to establish communication with remote: %s",
+			usb_strerror());
+		return LC_ERROR_CONNECT;
+	}
+
+#ifdef linux
+	/*
+	 * Before we attempt to claim the interface, lets go ahead and get
+	 * the kernel off of it, in case it claimed it already.
+	 *
+	 * This is ONLY available when on Linux. We don't check for an error
+	 * because it will error if no kernel driver is attached to it.
+	 *
+	 * Don't attempt to do this if this is a usbnet remote as it will
+	 * unload the zaurus driver, which is not desired.
+	 */
+#if 0
+	if (!(h_dev && (h_dev->descriptor.idProduct == 0xC11F))) {
+		usb_detach_kernel_driver_np(h_hid, 0);
+	}
+#endif
+#endif
+
+	/*
+	int err;
+	if ((err = usb_set_configuration(h_hid, 1))) {
+		debug("Failed to set device configuration: %d (%s)", err,
+			usb_strerror());
+		return err;
+	}
+
+	if ((err=usb_claim_interface(h_hid, 0))) {
+		debug("Failed to claim interface: %d (%s)", err,
+			usb_strerror());
+		return err;
+	}
+
+	unsigned char maxconf = h_dev->descriptor.bNumConfigurations;
+	for (unsigned char j = 0; j < maxconf; ++j) {
+		usb_config_descriptor &uc = h_dev->config[j];
+		unsigned char maxint = uc.bNumInterfaces;
+		for (unsigned char k = 0; k < maxint; ++k) {
+			usb_interface &ui = uc.interface[k];
+			unsigned char maxalt = ui.num_altsetting;
+			for (unsigned char l = 0; l < maxalt; ++l) {
+				usb_interface_descriptor &uid =
+					ui.altsetting[l];
+
+					debug("bNumEndpoints %i",
+						uid.bNumEndpoints);
+				unsigned char maxep = uid.bNumEndpoints;
+				for (unsigned char n = 0; n < maxep; ++n) {
+					check_ep(uid.endpoint[n]);
+				}
+			}
+		}
+	}
+
+	if (ep_read == -1 || ep_write == -1) return 1;
+	*/
+
+	// Fill in hid_info
+
+	char s[128];
+	hid_get_manufacturer_string(h_dev, (wchar_t *)s, sizeof(s));
+	hid_info.mfg = s;
+	hid_get_product_string(h_dev, (wchar_t *)s, sizeof(s));
+	hid_info.prod = s;
+
+	/*
+	hid_info.vid = h_dev->descriptor.idVendor;
+	hid_info.pid = h_dev->descriptor.idProduct;
+	hid_info.ver = h_dev->descriptor.bcdDevice;
+	*/
+	hid_info.vid = 0x0;
+	hid_info.pid = 0x0;
+	hid_info.ver = 0x0;
+
+	hid_info.irl = 0x0;
+	hid_info.orl = 0x0;
+	hid_info.frl = 0;/// ???
+
+	return 0;
+}
+
+int HID_WriteReport(const uint8_t *data)
+{
+	/*
+	 * In Windows you send an preceeding 0x00 byte with
+	 * every command, and the codebase used to do that, and we'd
+	 * skip the first byte here. Now, we do not assume this, we send
+	 * wholesale here, and add the 0 in the windows code.
+	 */
+	int err = hid_send_feature_report(h_dev, data, sizeof(data));
+	if (err < 0) {
+		debug("Failed to write to device: %d (%s)", err,
+			strerror(-err));
+		return err;
+	}
+
+	return 0;
+}
+
+int HID_ReadReport(uint8_t *data, unsigned int timeout)
+{
+	/* Note default timeout is set to 500 in hid.h */
+	int err = hid_get_feature_report(h_dev, data, sizeof(data));
+
+	if (err < 0) {
+		debug("Failed to read from device: %d (%s)", err,
+			usb_strerror());
+		return err;
+	}
+
+	return 0;
+}
+
+#endif

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and 
their applications. This 200-page book is written by three acclaimed 
leaders in the field. The early access version is available now. 
Download your free book today! http://p.sf.net/sfu/neotech_d2d_may
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to