summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kondrashov <spbnick@gmail.com>2010-07-22 13:19:44 +0000
committerNikolai Kondrashov <spbnick@gmail.com>2010-07-22 13:19:44 +0000
commit16d793f5bae71e72a3edcdb24431ad06a1995cc3 (patch)
treecb5fb0ec99e0e947a3dbb422794e6e407094e4ed
parent94328c20c37b8789c19205e877123499b18d49bb (diff)
downloadusbhid-dump-16d793f5bae71e72a3edcdb24431ad06a1995cc3.tar.gz
Added (somewhat dummy) Set_Protocol and Set_Idle requests to stream dumping setup.
-rw-r--r--include/hid_dump/iface.h30
-rw-r--r--lib/iface.c60
-rw-r--r--src/hid-dump.c10
3 files changed, 100 insertions, 0 deletions
diff --git a/include/hid_dump/iface.h b/include/hid_dump/iface.h
index 5348681..e5e0e73 100644
--- a/include/hid_dump/iface.h
+++ b/include/hid_dump/iface.h
@@ -128,6 +128,36 @@ extern enum libusb_error hid_dump_iface_list_attach(hid_dump_iface *list);
extern enum libusb_error hid_dump_iface_list_claim(hid_dump_iface *list);
/**
+ * Set idle duration on all interfaces in a list; ignore errors indicating
+ * missing support.
+ *
+ * @param list The list of interfaces to set idle duration on.
+ * @param duration The duration in 4 ms steps starting from 4 ms.
+ * @param timeout The request timeout, ms.
+ *
+ * @return Libusb error code.
+ */
+extern enum libusb_error hid_dump_iface_list_set_idle(
+ const hid_dump_iface *list,
+ uint8_t duration,
+ unsigned int timeout);
+
+/**
+ * Set HID protocol on all interfaces in a list; ignore errors indicating
+ * missing support.
+ *
+ * @param list The list of interfaces to set idle duration on.
+ * @param report True for "report" protocol, false for "boot" protocol.
+ * @param timeout The request timeout, ms.
+ *
+ * @return Libusb error code.
+ */
+extern enum libusb_error hid_dump_iface_list_set_protocol(
+ const hid_dump_iface *list,
+ bool report,
+ unsigned int timeout);
+
+/**
* Clear halt condition on input interrupt endpoints of all interfaces.
*
* @param list The list of interfaces to clear halt condition on.
diff --git a/lib/iface.c b/lib/iface.c
index f78fef5..0b173a9 100644
--- a/lib/iface.c
+++ b/lib/iface.c
@@ -302,6 +302,66 @@ hid_dump_iface_list_clear_halt(hid_dump_iface *list)
enum libusb_error
+hid_dump_iface_list_set_idle(const hid_dump_iface *list,
+ uint8_t duration,
+ unsigned int timeout)
+{
+ int rc;
+
+ assert(hid_dump_iface_list_valid(list));
+
+ for (; list != NULL; list = list->next)
+ {
+ rc = libusb_control_transfer(list->handle,
+ /* host->device, class, interface */
+ 0x21,
+ /* Set_Idle */
+ 0x0A,
+ /* duration for all report IDs */
+ duration << 8,
+ /* interface */
+ list->number,
+ NULL, 0,
+ timeout);
+ if (rc < 0)
+ return rc;
+ }
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
+hid_dump_iface_list_set_protocol(const hid_dump_iface *list,
+ bool report,
+ unsigned int timeout)
+{
+ int rc;
+
+ assert(hid_dump_iface_list_valid(list));
+
+ for (; list != NULL; list = list->next)
+ {
+ rc = libusb_control_transfer(list->handle,
+ /* host->device, class, interface */
+ 0x21,
+ /* Set_Protocol */
+ 0x0B,
+ /* 0 - boot, 1 - report */
+ report ? 1 : 0,
+ /* interface */
+ list->number,
+ NULL, 0,
+ timeout);
+ if (rc < 0)
+ return rc;
+ }
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
hid_dump_iface_list_release(hid_dump_iface *list)
{
enum libusb_error err;
diff --git a/src/hid-dump.c b/src/hid-dump.c
index 6d80a7f..3aca8c3 100644
--- a/src/hid-dump.c
+++ b/src/hid-dump.c
@@ -248,6 +248,16 @@ dump_iface_list_stream(libusb_context *ctx, const hid_dump_iface *list)
struct libusb_transfer **ptransfer;
const hid_dump_iface *iface;
+ /* Set report protocol on all interfaces */
+ err = hid_dump_iface_list_set_protocol(list, true, TIMEOUT);
+ if (err != LIBUSB_SUCCESS)
+ LIBUSB_ERROR_CLEANUP("set report protocol");
+
+ /* Set infinite idle duration on all interfaces */
+ err = hid_dump_iface_list_set_idle(list, 0, TIMEOUT);
+ if (err != LIBUSB_SUCCESS)
+ LIBUSB_ERROR_CLEANUP("set infinite idle duration");
+
/* Calculate number of interfaces and thus transfers */
transfer_num = hid_dump_iface_list_len(list);