2010-07-19 12 views
14

Usando udev he sido capaz de obtener esta información para un determinado dispositivo USB:¿Cómo obtener el proveedor de USB y la información del producto mediante programación en Linux?

idVendor: 13b1 
idProduct: 0018 
manufacturer: 
product: USB 2.0 Network Adapter ver.2 
serial: 00FFFF 

ahora quiero obtener las cadenas completos que están asociados con los identificadores de proveedor y producto. He encontrado que el archivo /usr/share/misc/usb.ids contiene la información que estoy buscando:

13b1 Linksys 
     000b WUSB11 v4.0 802.11b Adapter 
     000d WUSB54G Wireless Adapter 
     0011 WUSB54GP v4.0 802.11g Adapter 
     0018 USB200M 10/100 Ethernet Adapter 
     001a HU200TS Wireless Adapter 
     001e WUSBF54G 802.11bg 
     0020 WUSB54GC 802.11g Adapter [ralink rt73] 
     0023 WUSB54GR 
     0024 WUSBF54G v1.1 802.11bg 

Sin embargo, no me queda claro cómo debería recuperar estos datos en mi aplicación. ¿Hay una API disponible o debería simplemente analizar el archivo? Si elijo analizarlo, entonces ¿/usr/share/misc/usb.ids siempre será la ubicación correcta?

+1

En mi sistema es '/ usr/share/usb.ids'. No se puede encontrar ningún estándar que rija el lugar para este archivo. –

+2

Aquí está la versión más reciente: http://www.linux-usb.org/usb.ids y la interfaz para enviarlos: http://www.linux-usb.org/usb-ids.html – endolith

+0

En Android, mi programa C usa * libusbhost * que proporciona devoluciones de llamada para la inserción/eliminación de dispositivos. Todos los descriptores de dispositivo están disponibles por lib. –

Respuesta

17

lsusb consulta de comandos información acerca de los dispositivos USB conectados actualmente. Puede utilizar la opción -d para consultar un proveedor determinado/producto (pero parece que funciona sólo para los dispositivos actualmente conectados):

$ lsusb -d 0e21:0750 
Bus 001 Device 005: ID 0e21:0750 Cowon Systems, Inc. 

le puede mostrar la información para todos los dispositivos:

$ lsusb 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 
Bus 001 Device 004: ID 0421:01c7 Nokia Mobile Phones 
Bus 001 Device 003: ID 0bda:8187 Realtek Semiconductor Corp. RTL8187 Wireless Adapter 
Bus 001 Device 005: ID 0e21:0750 Cowon Systems, Inc. 
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
Bus 006 Device 002: ID 046d:c01b Logitech, Inc. MX310 Optical Mouse 
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 

Puede también hacer que sea verboso (lsusb -v) e imprimir mucho de cosas.

Tenga en cuenta que al acceder a información sobre el sistema en el sistema operativo Linux, es preferible hacerlo a través de comandos del shell (como lsusb) que analizar directamente los archivos del sistema a los que acceden estos comandos.

+0

Entonces, ¿necesito llamar a lsusb usando popen? – StackedCrooked

+1

@Stacked, sí (para C), pero eso depende del idioma en el que se desarrolle. Pero en cualquier caso, leerá algo de un flujo, y parece que llamar 'lsusb -d ...' a través de 'popen' parece requerir menos teclas que analizar el archivo completo con descripciones. –

1

Su dispositivo USB no necesita hacer coincidir los identificadores del producto y del proveedor con los nombres correctos reales.

Sería más seguro obtener esta información del dispositivo en sí con algo como libusb o lsusb.

3

En mi sistema Ubuntu, la página de manual lsusb(1) dice que /var/lib/usbutils/usb.ids es la ubicación del archivo id; de hecho, hay dos enlaces simbólicos, uno de los cuales es su /usr/share/misc/usb.ids. Me fío de la ubicación real antes de confiar en los enlaces simbólicos:

$ ls -l /usr/share/misc/usb.ids /var/lib/misc/usb.ids /var/lib/usbutils/usb.ids 
lrwxrwxrwx 1 root root  25 2010-04-29 18:08 /usr/share/misc/usb.ids -> /var/lib/usbutils/usb.ids 
lrwxrwxrwx 1 root root  19 2010-04-29 18:08 /var/lib/misc/usb.ids -> ../usbutils/usb.ids 
-rw-r--r-- 1 root root 368377 2009-11-06 09:26 /var/lib/usbutils/usb.ids 
3

no han probado este mismo, pero libudev's udev_device_get_property_value debería serlo; se usa en pulseaudio's udev-util.c como udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")).

Aquí hay un pequeño ejemplo que acabo de poner juntos, basado en udev-util.c - en cuenta que yo he utilizado un Duemillanove Arduino con chip FTDI FT232, cuyo camino udev Encuentro usando udevadm (ver comentarios en código de abajo), y luego hardcoded que en el siguiente programa, udevl.c:

// sudo apt-get install libudev-dev 
// build with: gcc -o udevl -ludev -Wall -g udevl.c 

#include <stdio.h> 

#include <libudev.h> 

int main(int argc, char **argv) 
{ 
    const char *v; 
    char t[256]; 
    struct udev *udev; 
    struct udev_device *card = NULL; 

    if (!(udev = udev_new())) { 
     fprintf(stderr, "Failed to allocate udev context.\n"); 
     return -1; 
    } 

    // $ lsusb | grep FT232 
    // Bus 002 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC  
    // $ udevadm info --name=/dev/ttyUSB0 --attribute-walk | grep "looking at device" 
    // looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0' 
    // (that one is under /sys) 
    // hardcode that path below: 

    // udev_get_sys_path(udev) for me: '/sys' 
    sprintf(t, "%s/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0", udev_get_sys_path(udev)); 
    fprintf(stdout, " path: %s\n", t); 

    card = udev_device_new_from_syspath(udev, t); 
    fprintf(stdout, " udev_device: 0x%08X\n", (unsigned int)card); 

    if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE"))) 
    fprintf(stdout, "got ID_MODEL_FROM_DATABASE: %s\n", v); 
    else 
    fprintf(stdout, "failed getting ID_MODEL_FROM_DATABASE: %s\n", v); 

    fprintf(stdout, "Done.\n"); 

    if (card) 
    udev_device_unref(card); 

    if (udev) 
    udev_unref(udev); 

    return 0; 
} 

Este programa (con el Arduino adjunta) salidas:

$ ./udevl 
path: /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0 
udev_device: 0x09FBF080 
got ID_MODEL_FROM_DATABASE: FT232 USB-Serial (UART) IC 
Done. 

... y "FT232 USB-serie (UART) IC "es la entrada correcta para VID: PID 0403: 6001 en usb.ids.

Espero que esto ayude,
¡Salud!

+0

cómo inicializar struct udev * udev ;? struct udev * udev = NULL? Debido a que mi código de verificación está dando error para esto. Gracias. – sree

Cuestiones relacionadas