summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kondrashov <spbnick@gmail.com>2010-11-15 22:18:49 +0300
committerNikolai Kondrashov <spbnick@gmail.com>2010-11-15 22:18:49 +0300
commitd0ad24c4c9ef12b1b4e1425867b7753e11f9d432 (patch)
tree002fc38c18490bd653009391eaf6edc86fd5dfe3
parent6a72205d8ac5689af81488538d0069a590d61ab8 (diff)
downloadusbhid-dump-d0ad24c4c9ef12b1b4e1425867b7753e11f9d432.tar.gz
Break iface list functions into iface functions
Break interface list functions into interface functions and use list iteration macro instead.
-rw-r--r--include/uhd/iface.h158
-rw-r--r--lib/iface.c317
-rw-r--r--src/usbhid-dump.c74
3 files changed, 275 insertions, 274 deletions
diff --git a/include/uhd/iface.h b/include/uhd/iface.h
index 72c5ca7..cc25361 100644
--- a/include/uhd/iface.h
+++ b/include/uhd/iface.h
@@ -72,8 +72,8 @@ extern bool uhd_iface_valid(const uhd_iface *iface);
/**
* Create a new interface.
*
- * @param handle Device handle.
- * @param number Interface number.
+ * @param handle Device handle.
+ * @param number Interface number.
* @param int_in_ep_addr Interrupt in endpoint address.
* @param int_in_ep_maxp Interrupt in endpoint maximum packet size.
*
@@ -92,143 +92,151 @@ extern uhd_iface *uhd_iface_new(libusb_device_handle *handle,
extern void uhd_iface_free(uhd_iface *iface);
/**
- * Check if an interface list is valid.
+ * Detach an interface from its kernel driver (if any).
*
- * @param list Interface list to check.
+ * @param iface The interface to detach.
*
- * @return True if the interface list is valid, false otherwise.
+ * @return Libusb error code.
*/
-extern bool uhd_iface_list_valid(const uhd_iface *list);
+extern enum libusb_error uhd_iface_detach(uhd_iface *iface);
/**
- * Check if an interface list is empty.
+ * Attach an interface to its kernel driver (if detached before).
*
- * @param list Interface list to check.
+ * @param iface The interface to attach.
*
- * @return True if the interface list is empty, false otherwise.
+ * @return Libusb error code.
*/
-static inline bool
-uhd_iface_list_empty(const uhd_iface *list)
-{
- return list == NULL;
-}
+extern enum libusb_error uhd_iface_attach(uhd_iface *iface);
/**
- * Calculate length of an interface list.
+ * Claim an interface.
*
- * @param list The list to calculate length of.
+ * @param iface The interface to claim.
*
- * @return The list length.
+ * @return Libusb error code.
*/
-extern size_t uhd_iface_list_len(const uhd_iface *list);
+extern enum libusb_error uhd_iface_claim(uhd_iface *iface);
/**
- * Free an interface list.
+ * Set idle duration on an interface; ignore errors indicating missing
+ * support.
*
- * @param list The interface list to free.
+ * @param iface The interface 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 void uhd_iface_list_free(uhd_iface *list);
-
+extern enum libusb_error uhd_iface_set_idle(
+ const uhd_iface *iface,
+ uint8_t duration,
+ unsigned int timeout);
/**
- * Fetch a list of HID interfaces from a device.
+ * Set HID protocol on an interface; ignore errors indicating missing
+ * support.
*
- * @param handle The device handle to fetch interface list from.
- * @param plist Location for the resulting list head; could be NULL.
+ * @param iface The interface 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.
*/
-enum libusb_error
-uhd_iface_list_new_from_dev(libusb_device_handle *handle,
- uhd_iface **plist);
+extern enum libusb_error uhd_iface_set_protocol(
+ const uhd_iface *iface,
+ bool report,
+ unsigned int timeout);
/**
- * Filter an interface list by an optional interface number, resulting
- * either in an empty, a single-interface, or an unmodified list.
+ * Clear halt condition on the input interrupt endpoint of an interface.
*
- * @param plist The original list head.
- * @param number The interface number to match against, or a negative
- * integer meaning there is no restriction.
+ * @param iface The interface to clear halt condition on.
*
- * @return The resulting list head
+ * @return Libusb error code.
*/
-extern uhd_iface *uhd_iface_list_fltr_by_num(uhd_iface *list,
- int number);
+extern enum libusb_error uhd_iface_clear_halt(uhd_iface *iface);
/**
- * Detach all interfaces in a list from their kernel drivers (if any).
+ * Release an interface (if claimed before).
*
- * @param list The list of interfaces to detach.
+ * @param iface The interface to release.
*
* @return Libusb error code.
*/
-extern enum libusb_error uhd_iface_list_detach(uhd_iface *list);
+extern enum libusb_error uhd_iface_release(uhd_iface *iface);
/**
- * Attach all interfaces in a list to their kernel drivers (if were detached
- * before).
+ * Check if an interface list is valid.
*
- * @param list The list of interfaces to attach.
+ * @param list Interface list to check.
*
- * @return Libusb error code.
+ * @return True if the interface list is valid, false otherwise.
*/
-extern enum libusb_error uhd_iface_list_attach(uhd_iface *list);
+extern bool uhd_iface_list_valid(const uhd_iface *list);
/**
- * Claim all interfaces in a list.
+ * Check if an interface list is empty.
*
- * @param list The list of interfaces to claim.
+ * @param list Interface list to check.
*
- * @return Libusb error code.
+ * @return True if the interface list is empty, false otherwise.
*/
-extern enum libusb_error uhd_iface_list_claim(uhd_iface *list);
+static inline bool
+uhd_iface_list_empty(const uhd_iface *list)
+{
+ return list == NULL;
+}
/**
- * Set idle duration on all interfaces in a list; ignore errors indicating
- * missing support.
+ * Calculate length of an interface list.
*
- * @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.
+ * @param list The list to calculate length of.
*
- * @return Libusb error code.
+ * @return The list length.
*/
-extern enum libusb_error uhd_iface_list_set_idle(
- const uhd_iface *list,
- uint8_t duration,
- unsigned int timeout);
+extern size_t uhd_iface_list_len(const uhd_iface *list);
/**
- * Set HID protocol on all interfaces in a list; ignore errors indicating
- * missing support.
+ * Free an interface list.
*
- * @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.
+ * @param list The interface list to free.
+ */
+extern void uhd_iface_list_free(uhd_iface *list);
+
+/**
+ * Iterate over an interface list.
*
- * @return Libusb error code.
+ * @param _iface Loop interface variable.
+ * @param _list Interface list to iterate over.
*/
-extern enum libusb_error uhd_iface_list_set_protocol(
- const uhd_iface *list,
- bool report,
- unsigned int timeout);
+#define UHD_IFACE_LIST_FOR_EACH(_iface, _list) \
+ for (_iface = _list; _iface != NULL; _iface = _iface->next)
/**
- * Clear halt condition on input interrupt endpoints of all interfaces.
+ * Fetch a list of HID interfaces from a device.
*
- * @param list The list of interfaces to clear halt condition on.
+ * @param handle The device handle to fetch interface list from.
+ * @param plist Location for the resulting list head; could be NULL.
*
* @return Libusb error code.
*/
-extern enum libusb_error uhd_iface_list_clear_halt(uhd_iface *list);
+enum libusb_error
+uhd_iface_list_new_from_dev(libusb_device_handle *handle,
+ uhd_iface **plist);
+
/**
- * Release all interfaces in a list (if were claimed before).
+ * Filter an interface list by an optional interface number, resulting
+ * either in an empty, a single-interface, or an unmodified list.
*
- * @param list The list of interfaces to release.
+ * @param plist The original list head.
+ * @param number The interface number to match against, or a negative
+ * integer meaning there is no restriction.
*
- * @return Libusb error code.
+ * @return The resulting list head
*/
-extern enum libusb_error uhd_iface_list_release(uhd_iface *list);
+extern uhd_iface *uhd_iface_list_fltr_by_num(uhd_iface *list,
+ int number);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/lib/iface.c b/lib/iface.c
index 3c8cb80..85dfcd8 100644
--- a/lib/iface.c
+++ b/lib/iface.c
@@ -74,6 +74,155 @@ uhd_iface_free(uhd_iface *iface)
}
+enum libusb_error
+uhd_iface_detach(uhd_iface *iface)
+{
+ enum libusb_error err;
+
+ assert(uhd_iface_valid(iface));
+
+ err = libusb_detach_kernel_driver(iface->handle, iface->number);
+ if (err == LIBUSB_SUCCESS)
+ iface->detached = true;
+ else if (err != LIBUSB_ERROR_NOT_FOUND)
+ return err;
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
+uhd_iface_attach(uhd_iface *iface)
+{
+ enum libusb_error err;
+
+ assert(uhd_iface_valid(iface));
+
+ if (iface->detached)
+ {
+ err = libusb_attach_kernel_driver(iface->handle, iface->number);
+ if (err != LIBUSB_SUCCESS)
+ return err;
+ iface->detached = false;
+ }
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
+uhd_iface_claim(uhd_iface *iface)
+{
+ enum libusb_error err;
+
+ assert(uhd_iface_valid(iface));
+
+ err = libusb_claim_interface(iface->handle, iface->number);
+ if (err != LIBUSB_SUCCESS)
+ return err;
+
+ iface->claimed = true;
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
+uhd_iface_release(uhd_iface *iface)
+{
+ enum libusb_error err;
+
+ assert(uhd_iface_valid(iface));
+
+ err = libusb_release_interface(iface->handle, iface->number);
+ if (err != LIBUSB_SUCCESS)
+ return err;
+
+ iface->claimed = false;
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
+uhd_iface_clear_halt(uhd_iface *iface)
+{
+ enum libusb_error err;
+
+ assert(uhd_iface_valid(iface));
+
+ err = libusb_clear_halt(iface->handle, iface->int_in_ep_addr);
+ if (err != LIBUSB_SUCCESS)
+ return err;
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
+uhd_iface_set_idle(const uhd_iface *iface,
+ uint8_t duration,
+ unsigned int timeout)
+{
+ int rc;
+
+ assert(uhd_iface_valid(iface));
+
+ rc = libusb_control_transfer(iface->handle,
+ /* host->device, class, interface */
+ 0x21,
+ /* Set_Idle */
+ 0x0A,
+ /* duration for all report IDs */
+ duration << 8,
+ /* interface */
+ iface->number,
+ NULL, 0,
+ timeout);
+ /*
+ * Ignoring EPIPE, which means a STALL handshake, which is OK on
+ * control pipes and indicates request is not supported.
+ * See USB 2.0 spec, 8.4.5 Handshake Packets
+ */
+ if (rc < 0 && rc != LIBUSB_ERROR_PIPE)
+ return rc;
+
+ return LIBUSB_SUCCESS;
+}
+
+
+enum libusb_error
+uhd_iface_set_protocol(const uhd_iface *iface,
+ bool report,
+ unsigned int timeout)
+{
+ int rc;
+
+ assert(uhd_iface_valid(iface));
+
+ rc = libusb_control_transfer(iface->handle,
+ /* host->device, class, interface */
+ 0x21,
+ /* Set_Protocol */
+ 0x0B,
+ /* 0 - boot, 1 - report */
+ report ? 1 : 0,
+ /* interface */
+ iface->number,
+ NULL, 0,
+ timeout);
+ /*
+ * Ignoring EPIPE, which means a STALL handshake, which is OK on
+ * control pipes and indicates request is not supported.
+ * See USB 2.0 spec, 8.4.5 Handshake Packets
+ */
+ if (rc < 0 && rc != LIBUSB_ERROR_PIPE)
+ return rc;
+
+ return LIBUSB_SUCCESS;
+}
+
+
bool
uhd_iface_list_valid(const uhd_iface *list)
{
@@ -224,171 +373,3 @@ uhd_iface_list_fltr_by_num(uhd_iface *list,
}
-enum libusb_error
-uhd_iface_list_detach(uhd_iface *list)
-{
- enum libusb_error err;
-
- assert(uhd_iface_list_valid(list));
-
- for (; list != NULL; list = list->next)
- {
- err = libusb_detach_kernel_driver(list->handle, list->number);
- if (err == LIBUSB_SUCCESS)
- list->detached = true;
- else if (err != LIBUSB_ERROR_NOT_FOUND)
- return err;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-
-enum libusb_error
-uhd_iface_list_attach(uhd_iface *list)
-{
- enum libusb_error err;
-
- assert(uhd_iface_list_valid(list));
-
- for (; list != NULL; list = list->next)
- if (list->detached)
- {
- err = libusb_attach_kernel_driver(list->handle, list->number);
- if (err != LIBUSB_SUCCESS)
- return err;
- list->detached = false;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-
-enum libusb_error
-uhd_iface_list_claim(uhd_iface *list)
-{
- enum libusb_error err;
-
- assert(uhd_iface_list_valid(list));
-
- for (; list != NULL; list = list->next)
- {
- err = libusb_claim_interface(list->handle, list->number);
- if (err != LIBUSB_SUCCESS)
- return err;
-
- list->claimed = true;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-
-enum libusb_error
-uhd_iface_list_clear_halt(uhd_iface *list)
-{
- enum libusb_error err;
-
- assert(uhd_iface_list_valid(list));
-
- for (; list != NULL; list = list->next)
- {
- err = libusb_clear_halt(list->handle, list->int_in_ep_addr);
- if (err != LIBUSB_SUCCESS)
- return err;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-
-enum libusb_error
-uhd_iface_list_set_idle(const uhd_iface *list,
- uint8_t duration,
- unsigned int timeout)
-{
- int rc;
-
- assert(uhd_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);
- /*
- * Ignoring EPIPE, which means a STALL handshake, which is OK on
- * control pipes and indicates request is not supported.
- * See USB 2.0 spec, 8.4.5 Handshake Packets
- */
- if (rc < 0 && rc != LIBUSB_ERROR_PIPE)
- return rc;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-
-enum libusb_error
-uhd_iface_list_set_protocol(const uhd_iface *list,
- bool report,
- unsigned int timeout)
-{
- int rc;
-
- assert(uhd_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);
- /*
- * Ignoring EPIPE, which means a STALL handshake, which is OK on
- * control pipes and indicates request is not supported.
- * See USB 2.0 spec, 8.4.5 Handshake Packets
- */
- if (rc < 0 && rc != LIBUSB_ERROR_PIPE)
- return rc;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-
-enum libusb_error
-uhd_iface_list_release(uhd_iface *list)
-{
- enum libusb_error err;
-
- assert(uhd_iface_list_valid(list));
-
- for (; list != NULL; list = list->next)
- if (list->claimed)
- {
- err = libusb_release_interface(list->handle, list->number);
- if (err != LIBUSB_SUCCESS)
- return err;
- list->claimed = false;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-
diff --git a/src/usbhid-dump.c b/src/usbhid-dump.c
index 1f16bb2..999d406 100644
--- a/src/usbhid-dump.c
+++ b/src/usbhid-dump.c
@@ -69,15 +69,29 @@
goto cleanup; \
} while (0)
-#define LIBUSB_ERROR_CLEANUP(_fmt, _args...) \
- ERROR_CLEANUP(_fmt ": %s", ##_args, libusb_strerror(err))
-
#define FAILURE_CLEANUP(_fmt, _args...) \
ERROR_CLEANUP("Failed to " _fmt, ##_args)
+#define LIBUSB_ERROR_CLEANUP(_fmt, _args...) \
+ ERROR_CLEANUP(_fmt ": %s", ##_args, libusb_strerror(err))
+
#define LIBUSB_FAILURE_CLEANUP(_fmt, _args...) \
LIBUSB_ERROR_CLEANUP("Failed to " _fmt, ##_args)
+#define LIBUSB_WATCH(_expr, _fmt, _args...) \
+ do { \
+ err = _expr; \
+ if (err != LIBUSB_SUCCESS) \
+ LIBUSB_FAILURE(_fmt, ##_args); \
+ } while (0)
+
+#define LIBUSB_GUARD(_expr, _fmt, _args...) \
+ do { \
+ err = _expr; \
+ if (err != LIBUSB_SUCCESS) \
+ LIBUSB_FAILURE_CLEANUP(_fmt, ##_args); \
+ } while (0)
+
/**< Number of the signal causing the exit */
static volatile sig_atomic_t exit_signum = 0;
@@ -285,15 +299,15 @@ dump_iface_list_stream(libusb_context *ctx, uhd_iface *list)
uhd_iface *iface;
bool submitted = false;
- /* Set report protocol on all interfaces */
- err = uhd_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 = uhd_iface_list_set_idle(list, 0, TIMEOUT);
- if (err != LIBUSB_SUCCESS)
- LIBUSB_ERROR_CLEANUP("set infinite idle duration");
+ UHD_IFACE_LIST_FOR_EACH(iface, list)
+ {
+ /* Set report protocol */
+ LIBUSB_GUARD(uhd_iface_set_protocol(list, true, TIMEOUT),
+ "set report protocol on an interface");
+ /* Set infinite idle duration */
+ LIBUSB_GUARD(uhd_iface_set_idle(list, 0, TIMEOUT),
+ "set infinite idle duration on an interface");
+ }
/* Calculate number of interfaces and thus transfers */
transfer_num = uhd_iface_list_len(list);
@@ -485,6 +499,7 @@ run(bool dump_descriptor,
libusb_context *ctx = NULL;
libusb_device_handle *handle = NULL;
uhd_iface *iface_list = NULL;
+ uhd_iface *iface;
/* Initialize libusb context */
err = libusb_init(&ctx);
@@ -509,16 +524,14 @@ run(bool dump_descriptor,
if (uhd_iface_list_empty(iface_list))
ERROR_CLEANUP("No matching HID interfaces");
- /* Detach interfaces */
- err = uhd_iface_list_detach(iface_list);
- if (err != LIBUSB_SUCCESS)
- LIBUSB_FAILURE_CLEANUP("detach the interface(s) from "
- "the kernel drivers");
-
- /* Claim interfaces */
- err = uhd_iface_list_claim(iface_list);
- if (err != LIBUSB_SUCCESS)
- LIBUSB_FAILURE_CLEANUP("claim the interface(s)");
+ /* Detach and claim the interfaces */
+ UHD_IFACE_LIST_FOR_EACH(iface, iface_list)
+ {
+ LIBUSB_GUARD(uhd_iface_detach(iface),
+ "detach an interface from the kernel driver");
+ LIBUSB_GUARD(uhd_iface_claim(iface),
+ "claim an interface");
+ }
/* Run with the prepared interface list */
result = (!dump_descriptor || dump_iface_list_descriptor(iface_list)) &&
@@ -528,15 +541,14 @@ run(bool dump_descriptor,
cleanup:
- /* Release the interfaces back */
- err = uhd_iface_list_release(iface_list);
- if (err != LIBUSB_SUCCESS)
- LIBUSB_FAILURE("release the interface(s)");
-
- /* Attach interfaces back */
- err = uhd_iface_list_attach(iface_list);
- if (err != LIBUSB_SUCCESS)
- LIBUSB_FAILURE("attach the interface(s) to the kernel drivers");
+ /* Release and attach the interfaces back */
+ UHD_IFACE_LIST_FOR_EACH(iface, iface_list)
+ {
+ LIBUSB_GUARD(uhd_iface_release(iface),
+ "release an interface");
+ LIBUSB_GUARD(uhd_iface_attach(iface),
+ "attach an interface to the kernel driver");
+ }
/* Free the interface list */
uhd_iface_list_free(iface_list);