libudev und USB-Sticks



  • Guten Morgen zusammen,

    ich versuche zurzeit alle USB-Geräte mit Seriennummer, Hersteller, Type und Verweis auf das Devicefile auszulesen. Hersteller und Type bekomme ich dabei aus der "/var/lib/usbutils/usb.ids" Datei. Im speziellen möchte ich mich auf USB-Sticks konzentrieren.

    Mit libusb hab ich auch die ersten drei Punkte geschafft, allerdings habe ich keine Möglichkeit gefunden das Devicefile herauszubekommen. Also wurde gegoogelt und habe die Library "libudev" gefunden.

    Habe mich dann eingelesen und ein kleines Beispiel geschrieben:

    #include <libudev.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <locale.h>
    #include <unistd.h>
    
    int main (void)
    {
    	struct udev *udev;
    	struct udev_enumerate *enumerate;
    	struct udev_list_entry *devices, *dev_list_entry;
    	struct udev_device *dev;
    
    	udev = udev_new();
    	if (!udev) {
    		printf("Can't create udev\n");
    		exit(1);
    	}
    
    	enumerate = udev_enumerate_new(udev);
    	udev_enumerate_add_match_subsystem(enumerate, "block");
    	udev_enumerate_scan_devices(enumerate);
    	devices = udev_enumerate_get_list_entry(enumerate);
    	udev_list_entry_foreach(dev_list_entry, devices) {
    		const char *path;
    
    		path = udev_list_entry_get_name(dev_list_entry);
    		dev = udev_device_new_from_syspath(udev, path);
    
    		printf("Device Node Path: %s\n", udev_device_get_devnode(dev));
    
    		dev = udev_device_get_parent_with_subsystem_devtype(
    		       dev,
    		       "usb",
    		       "usb_device");
    		if (!dev) {
    			printf("Unable to find parent usb device.\n");
    			exit(1);
    		}
    
    		printf("  VID/PID: %s %s\n",
    		        udev_device_get_sysattr_value(dev,"idVendor"),
    		        udev_device_get_sysattr_value(dev, "idProduct"));
    		printf("  %s\n  %s\n",
    		        udev_device_get_sysattr_value(dev,"manufacturer"),
    		        udev_device_get_sysattr_value(dev,"product"));
    		printf("  serial: %s\n",
    		         udev_device_get_sysattr_value(dev, "serial"));
    		udev_device_unref(dev);
    	}
    	udev_enumerate_unref(enumerate);
    
    	udev_unref(udev);
    
    	return 0;       
    }
    

    Allerdings bekomme ich den Fehler:

    Device Node Path: /dev/sda
    Unable to find parent usb device

    Jetzt zur eigentlichen Frage: Was ist ein "parent usb device"? Ist es im Grunde der BUS/Hub an dem das jeweilige Gerät hängt oder ist es etwas ganz anderes?

    Und vorallem: Wie kann ich das Problem lösen?



  • Die Geräte /Devices werden normalerweise in einer verketteten liste verwaltet.

    USB-Stick anstecken. (unter Linux)
    der usb treiber wird geladen
    Subsystem USB Type usb_device
    Subsystem USB Type usb_interface
    ....
    Subsystem Block Type DISK
    Subsystem BLock Type Partition.

    Nun kann man normalerweise die Liste vor/zurück suchen.

    Auf einen ARM funktioniert das ebi mir ohne Probleme.
    Nur auf einem X86 kommt er nicht auf das Usb_device. Die Kette ist irgendwie unterbrochen.



  • Dein enumerate iteriert über devices vom typ "block":

    udev_enumerate_add_match_subsystem(enumerate, "block");
    

    Jetzt willst du eins von diesen devices aber als usb_device behandlen:

    dev = udev_device_get_parent_with_subsystem_devtype(
                   dev,
                   "usb",
                   "usb_device");
    

    Das geht nicht für alle devices, weil ja nicht alle vom typ usb_device sind. Deswegen ist dev dann 0.

    Lass die Schleife einfach weiterlaufen und überspring die restlichen operationen falls dev == 0.


Log in to reply