pololu / libusbp

The Pololu USB Library (also known as libusbp) is a cross-platform C library for accessing USB devices.
Other
104 stars 32 forks source link

Extract Vendor and Product name #1

Open torfinnberset opened 5 years ago

torfinnberset commented 5 years ago

Hey, and thanks for a very useful library. I tried to follow the style used in the project, but I only have a Mac to test on, and not the reference USB device you listed either. I needed the vendor and product name, so I added them to the Device API. Hopefully someone else can contribute the Linux/Win ports.

DavidEGrayson commented 5 years ago

I'm glad you are finding the library useful and that you were able to add this feature to it! You are the first person I heard of using libusbp for something other than running Pololu software for Pololu USB products. Our software just knows the names and product IDs of all the devices it supports, so we never needed to add such a feature to libusbp before, but I'm sure this could be useful if you are trying to support a whole class of devices from different manufacturers.

I'll leave this open until someone makes adequate Windows and Linux implementations.

torfinnberset commented 5 years ago

The main reason I'm using the library is to quickly find the serial port address of a device. But I had some devices that had the same vendorId/productId, but differed on the names, hence this PR.

DavidEGrayson commented 5 years ago

I briefly looked into what it would take to do this on Windows.

Microsoft's open source USBView application demonstrates that it is possible to get those two strings from a device without opening a WinUSB handle to it, but getting those strings does cause I/O to happen to the device. So it would be bad to do it for every libusbp_device object that is created. It should only be done later, when the caller actually wants that information. (I'm not sure if your macOS implementation does extra USB I/O; that is something I would test before merging it in.)

On Windows, I suppose after those strings are requested the first time they should be cached in the libusbp_device object. That does potentially make things less thread-safe but we don't really have much of a thread-safety guarantee anyway. It does mean the functions for getting them would modify the object and therefore not be const anymore, which could be annoying I suppose.

torfinnberset commented 5 years ago

@DavidEGrayson you have a good point about the extra overhead per device. You should only pay for what you use :) However, it should be noted that the current master implementation reads out the serial number of each device, even though it's not strictly needed either (or perhaps it is for your application?).

DavidEGrayson commented 5 years ago

This library's get_string function for macOS is probably just fetching strings that were already cached by the operating system so it doesn't actually result in extra USB I/O, so it shouldn't be too bad to do that even when it's not needed. But I forget if I actually tested that.

Nightwalker-87 commented 1 year ago

@DavidEGrayson Maybe use the common libusb (https://github.com/libusb/libusb) instead?

DavidEGrayson commented 1 year ago

Which libusb function lets you retrieve the USB vendor or product string without generating traffic on the bus if possible?

Nightwalker-87 commented 1 year ago

I'd recommend to refer to the libusb API for details: https://libusb.sourceforge.io/api-1.0/group__libusb__dev.html

The question came up in a more general context, when I realised that Pololu published a custom standalone usb library. Is there any specific reason for that in favour of making use of established solutions?

DavidEGrayson commented 1 year ago

The comments in this space are for discussing adding functions to libusbp to access the USB vendor and product strings, so let's not get off topic. If you think libusb would be helpful for that task, I'd like more details. As far as I know, it can only retrieve strings after opening a handle, and retrieving those strings always requires I/O to the device, which we want to avoid when possible.

Nightwalker-87 commented 1 year ago

Well, I could not read from the original thread that this was a strong requirement in design. I found this thread regarding the specific question: https://github.com/libusb/libusb/issues/866 which appears to be a somehow similar approach for a related topic.

jporcher commented 1 year ago

@DavidEGrayson I believe I'm looking for the same feature, I'd like to access the product string: Under Windows, this is DEVPKEY_Device_BusReportedDeviceDesc Under Linux, this is "iProduct" reported by lsusb, "product" attribute of udev_device_get_sysattr_value Under MAC, dunno...

Is there a chance to get more attributes like this one (and maybe also Manufacturer) be propagated to libusbp? If not, what's the best strategy to have client be able to retrieve those?

DavidEGrayson commented 1 year ago

Yeah, I think this is the kind of feature that libusbp should support and I'd be willing to work on it at some point. We need to first understand what the capabilities of the operating systems are and think about how to make a good API that would work for any of them.

It looks like you figured out how to get the friendly name in Windows ( https://github.com/pololu/libusbp/issues/11 ). I think the friendly name is unique to Windows, right? I'm guessing it's just the name that Windows shows in the Device Manager, which comes from the USB driver most of the time, not the device. That name can be pretty bad sometimes (e.g. "USB Composite Device") but I think an advantage of it might be that it doesn't require extra I/O to the device.

We should probably have a cross-platform function that gets a real USB string, and if we want to support the Windows friendly name at all, it should only be for users who opt into it somehow (e.g. by passing a flag or calling a different function).

So, for each method of getting a USB product name (or manufacturer name), let's figure if it does extra I/O when you call it, and whether it really returns a string from the USB device or whether it returns some different name.

DavidEGrayson commented 1 year ago

Does anyone specifically want the name from the Windows Device Manager, as opposed to the product string from the actual USB device?

Nightwalker-87 commented 1 year ago

I'd be satisfied with the latter, but I am not a regular Windows user to be honestly.