[Spice-devel] [PATCH spice-gtk 3/3] usbutil: Add support for getting strings from usb.ids

Marc-André Lureau mlureau at redhat.com
Thu Feb 9 05:53:29 PST 2012


Hi

----- Mensaje original -----
> Unfortunately not all device makers go to the "trouble" of adding
> device
> identification strings to a device's descriptors. This patch makes
> spice-gtk
> translate vid/pid into strings if the device lacks the strings.

Wouldn't it make more sense to have this utility functions in a usb library? if not libusb, libgusb?


> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  configure.ac    |   21 ++++++++
>  gtk/Makefile.am |    1 +
>  gtk/usbutil.c   |  150
>  +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 172 insertions(+), 0 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 470f714..0d84e5c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -426,6 +426,27 @@ AC_ARG_WITH([usb-acl-helper-dir],
>    [ACL_HELPER_DIR="${bindir}/"])
>  AC_SUBST([ACL_HELPER_DIR])
>  
> +AC_ARG_WITH([usb-ids-path],
> +  AC_HELP_STRING([--with-usb-ids-path],
> +                 [Specify the path to usb.ids
> @<:@default=auto@:>@]),
> +  [USB_IDS="$with_usb_ids_path"],
> +  [USB_IDS="auto"])
> +AC_MSG_CHECKING([for usb.ids])
> +if test "x$USB_IDS" = "xauto"; then
> +  if test -n "$PKG_CONFIG"; then
> +    USB_IDS=$($PKG_CONFIG --variable=usbids usbutils)
> +  else
> +    USB_IDS=
> +  fi
> +fi
> +if test -n "$USB_IDS"; then
> +  AC_MSG_RESULT([$USB_IDS])
> +  AC_SUBST(USB_IDS)
> +  AC_DEFINE(WITH_USBIDS, [1], [Define if compiling with usb.ids
> support])
> +else
> +  AC_MSG_RESULT([not found])
> +fi
> +
>  AC_ARG_WITH([coroutine],
>    AS_HELP_STRING([--with-coroutine=@<:@ucontext/gthread/winfiber/auto@:>@],
>                   [use ucontext or GThread for coroutines
>                   @<:@default=auto@:>@]),
> diff --git a/gtk/Makefile.am b/gtk/Makefile.am
> index e0cc6fb..2b13168 100644
> --- a/gtk/Makefile.am
> +++ b/gtk/Makefile.am
> @@ -60,6 +60,7 @@ SPICE_COMMON_CPPFLAGS = \
>  	-DSW_CANVAS_CACHE		\
>  	-DSPICE_GTK_LOCALEDIR=\"${SPICE_GTK_LOCALEDIR}\" \
>  	-DPNP_IDS=\""$(PNP_IDS)"\"\
> +	-DUSB_IDS=\""$(USB_IDS)"\"\
>  	\
>  	-I$(COMMON_DIR)			\
>  	-I$(CLIENT_DIR)			\
> diff --git a/gtk/usbutil.c b/gtk/usbutil.c
> index 025b85f..cc7f21e 100644
> --- a/gtk/usbutil.c
> +++ b/gtk/usbutil.c
> @@ -23,6 +23,8 @@
>  
>  #include <glib-object.h>
>  #include <glib/gi18n.h>
> +#include <ctype.h>
> +#include <stdlib.h>
>  
>  #include "glib-compat.h"
>  
> @@ -35,6 +37,27 @@
>  #endif
>  #include "usbutil.h"
>  
> +#ifdef WITH_USBIDS
> +#define VENDOR_NAME_LEN (122 - sizeof(void *))
> +#define PRODUCT_NAME_LEN 126
> +
> +typedef struct _usb_product_info {
> +    guint16 product_id;
> +    char name[PRODUCT_NAME_LEN];
> +} usb_product_info;
> +
> +typedef struct _usb_vendor_info {
> +    usb_product_info *product_info;
> +    int product_count;
> +    guint16 vendor_id;
> +    char name[VENDOR_NAME_LEN];
> +} usb_vendor_info;
> +
> +GStaticMutex usbids_parse_mutex = G_STATIC_MUTEX_INIT;
> +int usbids_vendor_count;
> +usb_vendor_info *usbids_vendor_info;
> +#endif
> +
>  const char *spice_usbutil_libusb_strerror(enum libusb_error
>  error_code)
>  {
>      switch (error_code) {
> @@ -96,10 +119,111 @@ gchar *spice_usbutil_get_sysfs_attribute(int
> bus, int address, const char *attri
>  }
>  #endif
>  
> +#ifdef WITH_USBIDS
> +static void spice_usbutil_parse_usbids(void)
> +{
> +    gchar *contents, *line, **lines;
> +    usb_product_info *product_info;
> +    int i, j, id, product_count = 0;
> +
> +    g_static_mutex_lock(&usbids_parse_mutex);
> +    if (usbids_vendor_count)
> +        goto leave;
> +
> +    if (!g_file_get_contents(USB_IDS, &contents, NULL, NULL)) {
> +        usbids_vendor_count = -1;
> +        goto leave;
> +    }
> +    lines = g_strsplit(contents, "\n", -1);
> +
> +    for (i = 0; lines[i]; i++) {
> +        if (!isxdigit(lines[i][0]) || !isxdigit(lines[i][1]))
> +            continue;
> +
> +        for (j = 1; lines[i + j] &&
> +                   (lines[i + j][0] == '\t' ||
> +                    lines[i + j][0] == '#'  ||
> +                    lines[i + j][0] == '\0'); j++) {
> +            if (lines[i + j][0] == '\t' && isxdigit(lines[i +
> j][1]))
> +                product_count++;
> +        }
> +        i += j - 1;
> +
> +        usbids_vendor_count++;
> +    }
> +
> +    usbids_vendor_info = g_new(usb_vendor_info,
> usbids_vendor_count);
> +    product_info = g_new(usb_product_info, product_count);
> +
> +    usbids_vendor_count = 0;
> +    for (i = 0; lines[i]; i++) {
> +        line = lines[i];
> +
> +        if (!isxdigit(line[0]) || !isxdigit(line[1]))
> +            continue;
> +
> +        id = strtoul(line, &line, 16);
> +        while(isspace(line[0]))
> +            line++;
> +        usbids_vendor_info[usbids_vendor_count].vendor_id = id;
> +        snprintf(usbids_vendor_info[usbids_vendor_count].name,
> +                 VENDOR_NAME_LEN, "%s", line);
> +
> +        product_count = 0;
> +        for (j = 1; lines[i + j] &&
> +                   (lines[i + j][0] == '\t' ||
> +                    lines[i + j][0] == '#'  ||
> +                    lines[i + j][0] == '\0'); j++) {
> +            line = lines[i + j];
> +
> +            if (line[0] != '\t' || !isxdigit(line[1]))
> +                continue;
> +
> +            id = strtoul(line + 1, &line, 16);
> +            while(isspace(line[0]))
> +                line++;
> +            product_info[product_count].product_id = id;
> +            snprintf(product_info[product_count].name,
> +                     PRODUCT_NAME_LEN, "%s", line);
> +
> +            product_count++;
> +        }
> +        i += j - 1;
> +
> +        usbids_vendor_info[usbids_vendor_count].product_count =
> product_count;
> +        usbids_vendor_info[usbids_vendor_count].product_info  =
> product_info;
> +        product_info += product_count;
> +        usbids_vendor_count++;
> +    }
> +
> +    g_strfreev(lines);
> +    g_free(contents);
> +
> +#if 0 /* Testing only */
> +    for (i = 0; i < usbids_vendor_count; i++) {
> +        printf("%04x  %s\n", usbids_vendor_info[i].vendor_id,
> +               usbids_vendor_info[i].name);
> +        product_info = usbids_vendor_info[i].product_info;
> +        for (j = 0; j < usbids_vendor_info[i].product_count; j++) {
> +            printf("\t%04x  %s\n", product_info[j].product_id,
> +                   product_info[j].name);
> +        }
> +    }
> +#endif
> +leave:
> +    g_static_mutex_unlock(&usbids_parse_mutex);
> +}
> +#endif
> +
>  void spice_usb_util_get_device_strings(int bus, int address,
>                                         int vendor_id, int
>                                         product_id,
>                                         gchar **manufacturer, gchar
>                                         **product)
>  {
> +#ifdef WITH_USBIDS
> +    usb_product_info *product_info;
> +    int i, j;
> +#endif
> +
>      *manufacturer = NULL;
>      *product = NULL;
>  
> @@ -107,6 +231,32 @@ void spice_usb_util_get_device_strings(int bus,
> int address,
>      *manufacturer = spice_usbutil_get_sysfs_attribute(bus, address,
>      "manufacturer");
>      *product = spice_usbutil_get_sysfs_attribute(bus, address,
>      "product");
>  #endif
> +
> +#ifdef WITH_USBIDS
> +    if (!*manufacturer || !*product) {
> +        spice_usbutil_parse_usbids();
> +
> +        for (i = 0; i < usbids_vendor_count; i++) {
> +            if ((int)usbids_vendor_info[i].vendor_id != vendor_id)
> +                continue;
> +
> +            if (!*manufacturer && usbids_vendor_info[i].name[0])
> +                *manufacturer =
> g_strdup(usbids_vendor_info[i].name);
> +
> +            product_info = usbids_vendor_info[i].product_info;
> +            for (j = 0; j < usbids_vendor_info[i].product_count;
> j++) {
> +                if ((int)product_info[j].product_id != product_id)
> +                    continue;
> +
> +                if (!*product && product_info[j].name[0])
> +                    *product = g_strdup(product_info[j].name);
> +
> +                break;
> +            }
> +            break;
> +        }
> +    }
> +#endif
>      if (!*manufacturer)
>          *manufacturer = g_strdup(_("USB"));
>      if (!*product)
> --
> 1.7.7.6
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
> 


More information about the Spice-devel mailing list