Vid pid устройства linux

how to get usb’s urb info in linux

Also, be careful with strncpy , if the string you copy is longer or equal to the length, then it won’t add the terminating ‘\0’ .

A third point, you close the file even if the open call fails. Put the call to close inside the else .

when use ioctl above.. result = ioctl(fd, USBDEVFS_REAPURB, receive); it failed. and I’m sure the length of that path is short~ 🙂 thank you @JoachimPileborg

2 Answers 2

I ended up with a similar problem — so here are my notes. Besides the problems pointed out so far in comments, I think the main issues with the OP code are:

  1. You cannot just «reap» a URB; you first have to «submit» a (read or write) URB, then you «reap» it
  2. You cannot just open a file string that you got as path from command line arguments ( argv[1] ), and obtain a file descriptor valid for URB ioctl

Also, once I have filled this structure am I right in thinking I need to call the following:
int retSubmit = ioctl( fd, USBDEVFS_SUBMITURB, &usbRequest );
and then once submitted I can wait for the request to complete using
USBDEVFS_REAPURBNDELAY

The routine, and the call to it, whidch I use to submit the URB are as follows:
.
Submitting the URB works fine. This is how I try to reap it:
.

Yes, you submit a BULK type usbdevfs_urb to the interrupt endpoint. It gets one packet of data. You can submit multiple ones that will queue up. and I’m guessing ‘reap’ is REAd Pointer, not like the grim reaper (although maybe it is. )

I think (but I’m not sure 100%) that «submit» and «reap» are equivalent to «submit» and «completion» as noted in Virtual USB Analyzer — Tutorial.

As far as the 2. goes — it depends on the kind of the device. For instance, if you connect an Arduino Duemillanove, which has an FT232 USB serial chip, to a Linux PC — that will automatically load the ftdi_sio kernel driver, which in turn loads usbserial driver, which then creates the file (device node) /dev/ttyUSB0 . Thus, Linux would see this file, at best, as a plain serial port — not something necessarily related to a URB request (I guess something similar goes for USB flash thumbdrives); and I was getting the same error as OP, when trying to call the OP code with an argument of /dev/ttyUSB0 .

Obtaining this file descriptor is somewhat difficult, as it’s kinda hard to track down examples:

On Fri, May 05, 2006 at 04:45:30PM -0400, Danny Budik wrote:
> How do I use the «raw» usbfs? I tried reading from the /dev/bus/usb file
> and got a bind — address already in use error.

Look at how libusb is implemented for a good example of how to do this.
The source code to ‘lsusb’ will also help you out here.

NOTE: The filesystem has been renamed from «usbdevfs» to
«usbfs», to reduce confusion with «devfs». You may
still see references to the older «usbdevfs» name.

I basically started from the code in [Discuss-gnuradio] New implementation for fusb_linux without allocs/frees, and tried to modify the OP code so it works with an Arduino Duemillanove. The problem is that it uses the older libusb-0.1 code, which has some different names of headers and functions; e.g. libusb-0.1 has libusb/usbi.h, while the newer libusb-1.0 has libusb/libusbi.h. In essence, libusb functions can be used to obtain the proper file descriptor.

Читайте также:  Linux deploy and install

The modified OP code is below, let’s say we call it testu.c . I’ve tested it on Ubuntu Natty — first, connect the Arduino Duemillanove, which hooks the ftdi_sio driver (this can be checked in terminal with tail -f /var/log/syslog ). So, to begin with, remove the auto-hooked driver ( libusb doesn’t need it to talk to the device, and it’s possible it could interfere; note after removal, /dev/ttyUSB0 file doesn’t exist anymore):

sudo modprobe -r ftdi_sio # this also removes usbserial lsmod | grep ftdi # make sure ftdi_sio isn't listed by lsmod 

Then, we will use the USB vendor/product ID to connect to the device via libusb ; to find it, use lsusb :

$ lsusb | grep FT Bus 002 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC 

The VID:PID 0403:6001 is hardcoded in testu.c ; then we can build and run it. Note that the testu program has to be ran as root (via sudo ) — else libusb won’t be able to communicate with the device:

$ gcc -o testu -Wall -g testu.c `pkg-config --libs --cflags libusb-1.0` testu.c:23:1: warning: ‘fd_from_usb_dev_handle’ defined but not used $ sudo ./testu First Second 0x8B4B4F0 Open successed: Device: 0403:6001 6 polling. The 1 th time ok. polling. The 2 th time ok. polling. The 3 th time ok. polling. The 4 th time ok. polling. The 5 th time ok. polling. The 6 th time ok. polling. The 7 th time ok. polling. The 8 th time ok. polling. The 9 th time ok. polling. The 10 th time ok. 

The code submits a write request (on endpoint 0x02), then reaps it — and I can see the RX led blink on the Arduino — meaning some data does get to it, as expected. However, not much more than that happens — so I’m not sure if the code answers the «get usb’s urb info» part 🙂 However, it does show how the file descriptor can be obtained, so the raw ioctl s can work — albeit via libusb (you’d probably have to dig deeper through the libusb source, in order to do the same without libusb).

Here is testu.c (note, install the libusb-dev package so it can compile):

#include #include #include #include #include #include #include #include /* #include */ /* #include */ #include /* #include */ /* #include */ //~ #define USBDEVFS_REAPURB _IOW('U', 12, void *) #include struct libusb_device_handle *d_udh = NULL; // [http://www.mail-archive.com/discuss-gnuradio@gnu.org/msg17549.html [Discuss-gnuradio] New implementation for fusb_linux without allocs/frees] static int fd_from_usb_dev_handle (libusb_device_handle *udh) //(usb_dev_handle *udh) < return *((int *) udh); >//~ ./libusb/os/linux_usbfs.c struct linux_device_handle_priv < int fd; >; //~ ./libusb/libusbi.h #define usbi_mutex_t pthread_mutex_t struct list_head < struct list_head *prev, *next; >; struct libusb_device_handle < /* lock protects claimed_interfaces */ usbi_mutex_t lock; unsigned long claimed_interfaces; struct list_head list; struct libusb_device *dev; unsigned char os_priv[0]; >; //~ ./libusb/os/linux_usbfs.c struct linux_device_handle_priv* _device_handle_priv( struct libusb_device_handle *handle) < struct linux_device_handle_priv* out; out = (struct linux_device_handle_priv *) handle->os_priv; return out; >; int main(int argc, char *argv[]) < int fd; int result; int i; struct usbdevfs_urb * receive; struct usbdevfs_urb * send; struct linux_device_handle_priv *hpriv; send = malloc(sizeof (struct usbdevfs_urb)); memset(send, 0, sizeof (*send)); send->buffer_length = 10; send->buffer = malloc(sizeof(unsigned char)*10); send->type = USBDEVFS_URB_TYPE_BULK; send->endpoint = 0x02; send->signr = 0; receive = malloc(sizeof (struct usbdevfs_urb)); bzero(receive, sizeof (struct usbdevfs_urb)); char file[30]; if (argv[1]) strncpy (file, argv[1], 30); printf ("First\n"); result = libusb_init(NULL); if (result < 0) < printf("failed to initialise libusb:\n"); >d_udh = libusb_open_device_with_vid_pid(NULL, 0x0403, 0x6001); hpriv = _device_handle_priv(d_udh); printf ("Second 0x%X\n", (unsigned int)d_udh); result = d_udh ? 0 : -EIO; //~ if ((fd = open(file, O_RDWR)) < 0) if (result < 0) < printf("failed to open device: %s, \n error: %s \n", "0403:6001", strerror(errno)); //file >else < //~ fd = fd_from_usb_dev_handle(d_udh); // doesn't work fd = _device_handle_priv(d_udh)->fd; printf ("Open successed: Device: %s %d\n", "0403:6001", fd ); // file); for (i = 0; i < 10; ++i) < result = ioctl (fd, USBDEVFS_SUBMITURB, send); if (result < 0) < printf ("Error! USBDEVFS_SUBMITURB : ioctl returned : %d\n errno =%s\n", result, strerror(errno)); break; >printf ("polling. \n"); result = ioctl(fd, USBDEVFS_REAPURB, receive); if (result < 0) < printf ("Error! USBDEVFS_REAPURB : ioctl returned : %d\n errno =%s\n", result, strerror(errno)); break; >printf ("The %d th time ok.\n", i + 1); usleep(2000); > > close(fd); return 0; > 

Well, hope this helps someone,
Cheers!

Читайте также:  Burp suite linux install

Источник

How to get USB vendor and product info programmatically on Linux?

Now I want to get the full strings that are associated with the vendor and product ids. I found that the file /usr/share/misc/usb.ids contains the information that I’m looking for:

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 

However, it’s not clear to me how I should retrieve this data in my application. Is there an API available or should I just parse the file? If I choose to parse it, then is /usr/share/misc/usb.ids always going to be the correct location?

Here’s the most recent version: linux-usb.org/usb.ids and the interface for submitting them: linux-usb.org/usb-ids.html

On Android, my C program uses libusbhost which provides callbacks for device insertion/removal. All device descriptors are made available by the lib.

5 Answers 5

lsusb command queries information about currently plugged USB devices. You can use its -d option to query a certain vendor/product (but it seems to work only for currently plugged devices):

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

You can show information for all devices:

$ 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 

You can also make it be verbose ( lsusb -v ) and printing a lot of stuff.

Читайте также:  Mount ntfs oracle linux

Note that when accessing information about the system in Linux OS, it’s much preferred to do it via shell commands (such as lsusb ) than to directly parse the system files these commands access.

@Stacked, yes (for C), but that depends on a language you develop in. But either way you’ll be reading something from a stream, and calling lsusb -d . via popen seems to require less keystrokes than parsing the whole file with descriptions.

Haven’t tried this myself, but libudev’s udev_device_get_property_value should be it; it is used in pulseaudio’s udev-util.c as udev_device_get_property_value(card, «ID_VENDOR_FROM_DATABASE»)) .

Here is a small example I just put together, based on udev-util.c — note that I’ve used an Arduino Duemillanove with FTDI FT232 chip, whose udev path I find using udevadm (see comments in code below), and then I hardcoded it in the below program, udevl.c :

// sudo apt-get install libudev-dev // build with: gcc -o udevl -ludev -Wall -g udevl.c #include #include 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; > 

This program (with the Arduino attached) outputs:

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

. and «FT232 USB-Serial (UART) IC» is the right entry for VID:PID 0403:6001 in usb.ids.

Источник

Оцените статью
Adblock
detector