2010-07-19 5 views
14

En utilisant udev Je suis en mesure d'obtenir ces informations pour un périphérique USB:Comment obtenir un fournisseur USB et des informations sur les produits par programmation sous Linux?

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

Maintenant, je veux obtenir les chaînes complètes qui sont associés aux ids des fournisseurs et produits. Je trouve que le fichier /usr/share/misc/usb.ids contient les informations que je cherche:

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 

Cependant, ce n'est pas clair pour moi comment je dois récupérer ces données dans mon application. Y at-il une API disponible ou devrais-je juste analyser le fichier? Si je choisis de l'analyser, est-ce que /usr/share/misc/usb.ids sera toujours le bon emplacement?

+1

Sur mon système, c'est '/ usr/share/usb.ids'. Impossible de trouver la norme qui régit l'emplacement de ce fichier. –

+2

Voici la version la plus récente: http://www.linux-usb.org/usb.ids et l'interface pour les soumettre: http://www.linux-usb.org/usb-ids.html – endolith

+0

Sur Android, mon programme C utilise * libusbhost * qui fournit des rappels pour l'insertion/suppression de périphérique. Tous les descripteurs de périphériques sont mis à disposition par la bibliothèque lib. –

Répondre

17

lsusb La commande interroge des informations sur les périphériques USB actuellement branchés. Vous pouvez utiliser son option -d pour interroger un certain fournisseur/produit (mais il semble fonctionner que pour les appareils actuellement connectés):

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

Vous pouvez afficher des informations pour tous les appareils:

$ 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 

Vous pouvez aussi le faire être verbeux (lsusb -v) et l'impression beaucoup de choses. Notez que lors de l'accès aux informations sur le système sous Linux, il est préférable de le faire via des commandes shell (telles que lsusb) que d'analyser directement les fichiers système auxquels accèdent ces commandes.

+0

Alors j'ai besoin d'appeler lsusb en utilisant popen alors? – StackedCrooked

+1

@Stacked, oui (pour C), mais cela dépend du langage dans lequel vous développez. Mais de toute façon, vous lirez quelque chose à partir d'un flux, et l'appel 'lsusb -d ...' via 'popen' semble exiger moins de séquences de touches que l'analyse du fichier entier avec des descriptions. –

1

Votre périphérique USB n'a pas besoin de faire correspondre les identifiants des fournisseurs et des produits aux noms corrects.

Il serait plus sûr d'obtenir cette information de l'appareil lui-même avec quelque chose comme libusb ou lsusb.

3

Sur mon système Ubuntu, la page de manuel lsusb(1) indique que /var/lib/usbutils/usb.ids est l'emplacement du fichier d'identification; en fait, il y a deux liens symboliques, dont l'un est /usr/share/misc/usb.ids. Je fais confiance l'emplacement réel avant de faire confiance aux liens symboliques:

$ 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

N'a pas essayé moi-même, mais libudev's udev_device_get_property_value devrait suffire; il est utilisé dans pulseaudio's udev-util.c comme udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")).

Voici un petit exemple, je viens de mettre ensemble, sur la base udev-util.c - notez que je l'ai utilisé un Duemillanove Arduino avec puce FTDI FT232, dont le chemin udev je trouve en utilisant udevadm (voir les commentaires dans le code ci-dessous), puis je hardcoded dans le programme ci-dessous, 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; 
} 

Ce programme sorties (avec l'Arduino ci-joint):

$ ./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. 

... et « USB-série FT232 (UART) IC "est la bonne entrée pour VID: PID 0403: 6001 dans usb.ids.

Espérons que cela aide,
Cheers!

+0

comment initialiser struct udev * udev ;? struct udev * udev = NULL? Parce que mon vérificateur de code donne une erreur pour cela. Merci. – sree

Questions connexes