From 0256f04338517a2a5ed33954133044b5526f25e3 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Thu, 19 Nov 2015 17:45:18 +0000 Subject: [PATCH] libdfu: Improve the output of 'dfu-util list' Being semi-compatible with dfu-util isn't important anymore. --- libdfu/Makefile.am | 2 + libdfu/dfu-device.c | 9 ++++ libdfu/dfu-error.h | 2 + libdfu/dfu-tool.c | 105 ++++++++++++++++++++++++++++++++------------ 4 files changed, 90 insertions(+), 28 deletions(-) diff --git a/libdfu/Makefile.am b/libdfu/Makefile.am index cc7d6839e..e202f4760 100644 --- a/libdfu/Makefile.am +++ b/libdfu/Makefile.am @@ -1,4 +1,5 @@ AM_CPPFLAGS = \ + $(APPSTREAM_GLIB_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUSB_CFLAGS) \ -I$(top_srcdir)/libdfu \ @@ -59,6 +60,7 @@ dfu_tool_SOURCES = \ dfu_tool_LDADD = \ $(privlib_LTLIBRARIES) \ + $(APPSTREAM_GLIB_LIBS) \ $(GLIB_LIBS) \ $(GUSB_LIBS) diff --git a/libdfu/dfu-device.c b/libdfu/dfu-device.c index 6b3e11698..164a1dcd2 100644 --- a/libdfu/dfu-device.c +++ b/libdfu/dfu-device.c @@ -403,6 +403,15 @@ dfu_device_open (DfuDevice *device, GError **error) /* open */ if (!g_usb_device_open (priv->dev, &error_local)) { + if (g_error_matches (error_local, + G_USB_DEVICE_ERROR, + G_USB_DEVICE_ERROR_PERMISSION_DENIED)) { + g_set_error (error, + DFU_ERROR, + DFU_ERROR_PERMISSION_DENIED, + "%s", error_local->message); + return FALSE; + } g_set_error (error, DFU_ERROR, DFU_ERROR_INVALID_DEVICE, diff --git a/libdfu/dfu-error.h b/libdfu/dfu-error.h index 73dcba013..b1ef2ea7c 100644 --- a/libdfu/dfu-error.h +++ b/libdfu/dfu-error.h @@ -34,6 +34,7 @@ * @DFU_ERROR_INVALID_DEVICE: Invalid device type * @DFU_ERROR_NOT_FOUND: Resource not found * @DFU_ERROR_NOT_SUPPORTED: Action was not supported + * @DFU_ERROR_PERMISSION_DENIED: Failed due to access permissions * * The error code. **/ @@ -44,6 +45,7 @@ typedef enum { DFU_ERROR_INVALID_DEVICE, /* Since: 0.5.4 */ DFU_ERROR_NOT_FOUND, /* Since: 0.5.4 */ DFU_ERROR_NOT_SUPPORTED, /* Since: 0.5.4 */ + DFU_ERROR_PERMISSION_DENIED, /* Since: 0.5.4 */ /*< private >*/ DFU_ERROR_LAST } DfuError; diff --git a/libdfu/dfu-tool.c b/libdfu/dfu-tool.c index bb0b59de1..c3a1c01a0 100644 --- a/libdfu/dfu-tool.c +++ b/libdfu/dfu-tool.c @@ -26,6 +26,7 @@ #include #include #include +#include typedef struct { GPtrArray *cmd_array; @@ -1157,6 +1158,68 @@ dfu_tool_download (DfuToolPrivate *priv, gchar **values, GError **error) return TRUE; } +/** + * dfu_tool_print_indent: + **/ +static void +dfu_tool_print_indent (const gchar *title, const gchar *message, guint indent) +{ + guint i; + for (i = 0; i < indent; i++) + g_print (" "); + g_print ("%s:", title); + for (i = strlen (title) + indent; i < 15; i++) + g_print (" "); + g_print ("%s\n", message); +} + +/** + * dfu_tool_list_target: + **/ +static void +dfu_tool_list_target (DfuTarget *target) +{ + const gchar *tmp; + gboolean ret; + g_autofree gchar *alt_id = NULL; + g_autoptr(GError) error_local = NULL; + + /* TRANSLATORS: the identifier name please */ + alt_id = g_strdup_printf ("%i", dfu_target_get_interface_alt_setting (target)); + dfu_tool_print_indent (_("ID"), alt_id, 1); + + /* TRANSLATORS: device mode, e.g. runtime or DFU */ + dfu_tool_print_indent (_("Mode"), dfu_mode_to_string (dfu_target_get_mode (target)), 2); + tmp = dfu_target_get_interface_alt_name (target); + if (tmp != NULL) { + /* TRANSLATORS: interface name, e.g. "Flash" */ + dfu_tool_print_indent (_("Name"), tmp, 2); + } + ret = dfu_target_open (target, + DFU_TARGET_OPEN_FLAG_NONE, + NULL, &error_local); + if (ret) { + tmp = dfu_status_to_string (dfu_target_get_status (target)); + /* TRANSLATORS: device status, e.g. "OK" */ + dfu_tool_print_indent (_("Status"), tmp, 2); + + tmp = dfu_state_to_string (dfu_target_get_state (target)); + /* TRANSLATORS: device state, i.e. appIDLE */ + dfu_tool_print_indent (_("State"), tmp, 2); + } else { + if (g_error_matches (error_local, + DFU_ERROR, + DFU_ERROR_PERMISSION_DENIED)) { + /* TRANSLATORS: probably not run as root... */ + dfu_tool_print_indent (_("Status"), _("Unknown: permission denied"), 2); + } else { + /* TRANSLATORS: device has failed to report status */ + dfu_tool_print_indent (_("Status"), error_local->message, 2); + } + } + dfu_target_close (target, NULL); +} + /** * dfu_tool_list: **/ @@ -1164,7 +1227,6 @@ static gboolean dfu_tool_list (DfuToolPrivate *priv, gchar **values, GError **error) { GUsbDevice *usb_device; - gboolean ret; guint i; g_autoptr(GPtrArray) devices = NULL; g_autoptr(GUsbContext) usb_ctx = NULL; @@ -1178,6 +1240,7 @@ dfu_tool_list (DfuToolPrivate *priv, gchar **values, GError **error) GPtrArray *dfu_targets; DfuTarget *target; guint j; + g_autofree gchar *version = NULL; usb_device = g_ptr_array_index (devices, i); g_debug ("PROBING [%04x:%04x]", @@ -1186,36 +1249,22 @@ dfu_tool_list (DfuToolPrivate *priv, gchar **values, GError **error) device = dfu_device_new (usb_device); if (device == NULL) continue; + + /* device specific */ + version = as_utils_version_from_uint16 (g_usb_device_get_release (usb_device), + AS_VERSION_PARSE_FLAG_NONE); + g_print ("%s %04x:%04x [v%s]:\n", + /* TRANSLATORS: detected a DFU device */ + _("Found"), + g_usb_device_get_vid (usb_device), + g_usb_device_get_pid (usb_device), + version); + + /* list targets */ dfu_targets = dfu_device_get_targets (device); for (j = 0; j < dfu_targets->len; j++) { - g_autoptr(GError) error_local = NULL; target = g_ptr_array_index (dfu_targets, j); - - if (priv->transfer_size > 0) - dfu_target_set_transfer_size (target, priv->transfer_size); - ret = dfu_target_open (target, - DFU_TARGET_OPEN_FLAG_NONE, - NULL, &error_local); - g_print ("Found %s: [%04x:%04x] ver=%04x, devnum=%i, " - "cfg=%i, intf=%i, ts=%i, alt=%i, name=%s", - dfu_mode_to_string (dfu_target_get_mode (target)), - g_usb_device_get_vid (usb_device), - g_usb_device_get_pid (usb_device), - g_usb_device_get_release (usb_device), - g_usb_device_get_address (usb_device), - g_usb_device_get_configuration (usb_device, NULL), - dfu_target_get_interface_number (target), - dfu_target_get_transfer_size (target), - dfu_target_get_interface_alt_setting (target), - dfu_target_get_interface_alt_name (target)); - if (ret) { - g_print (", status=%s, state=%s\n", - dfu_status_to_string (dfu_target_get_status (target)), - dfu_state_to_string (dfu_target_get_state (target))); - } else { - g_print (": %s\n", error_local->message); - } - dfu_target_close (target, NULL); + dfu_tool_list_target (target); } } return TRUE;