Open mcuee opened 9 years ago
not sure it is a real issue in all linked above in some case i suspect it is more an issue in the installation file used (.inf) i used libusb with cdc/acm type device only referencing the MI_xx i wanted and not using the IAD at all. That is working of course if multiple interface from the IAD are to be used they must all be claimed.
typicality using zadig of over inf builder wizard select one say first interface, generates driver files (chose extract do not install) then edit .inf and add Mi_xx missing , for example in a composite device with two interafce 0 and 1 to be used set
%DeviceName%=LUsbK_Device, USB\%DeviceID%&MI_01, USB\%DeviceID%&MI_00
when install is done by hand pointing to the inf file it may have to be repeated for all the multiple interface separately. The device manager will finaly appear as two separate device but it is armless.
Installing for the full device like below is also a solution (will appear only once): %DeviceName%=LUsbK_Device, USB\%DeviceID%
But that will prevent installing some standard class driver present in the composite device for instance a cdc/acm with standard serial driver along with specific device.
http://libusbx.1081486.n5.nabble.com/Libusbx-devel-Accessing-composite-devices-using-interface-association-tp1726p1737.html Nabble libusbx archive is dead.
https://www.mail-archive.com/libusbx-devel@lists.sourceforge.net/msg03070.html From Xiaofan: " I think there is a way to hack the inf-file generated by Zadig to install WinUSB driver for each interface. Interface 0 --> MI_00 Interface 1 --> MI_01 Interface 2 --> MI_02 " From Tim Roberts: "No, that won't work. When you have an IAD that wraps those three interfaces, usbccgp only creates a PDO for MI_00. You'll only get one driver, and that driver is assigned ownership of all three interfaces. There will never be an opportunity to load MI_01 and MI_02, because it won't create those PDOs. "
Parsing IADs is very trivial:
/** Endpoint descriptor. See libusb_endpoint_descriptor. */
LIBUSB_DT_ENDPOINT = 0x05,
/** Interface Association Descriptor */
LIBUSB_DT_IAD = 0x0b,
/** BOS descriptor */
LIBUSB_DT_BOS = 0x0f,
struct libusb_iad_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
}; // add to configuration
static int parse_iad(struct libusb_context *ctx,
struct libusb_iad_descriptor *iad, unsigned char *buffer,
int size, int host_endian)
{
if (size <= 8) {
usbi_err(ctx, "ias descriptor size %d expected 8", size);
return LIBUSB_ERROR_IO;
}
usbi_parse_descriptor(buffer, "bbbbbbbb", iad, host_endian);
return 8;
}
static int parse_configuration(struct libusb_context *ctx,
struct libusb_config_descriptor *config, unsigned char *buffer,
int size, int host_endian)
{
...
config->extra = NULL;
config->extra_length = 0;
memset(&config->iad, 0, sizeof(config->iad));
if (size >= DESC_HEADER_LENGTH) {
usbi_parse_descriptor(buffer, "bb", &header, 0);
if (header.bDescriptorType == LIBUSB_DT_IAD) {
parse_iad(ctx, &config->iad, buffer, size, host_endian);
buffer += header.bLength;
size -= header.bLength;
}
}
for (i = 0; i < config->bNumInterfaces; i++) {
...
}
// tricky part is that
static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle)
{
file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
}
same file handle should be used for ALL interfaces that are setup in set_composite_interface
I have a branch with three commits that I have been using to work around this problem in order to talk to an AIA U3V (USB 3.0 Vision) camera using Windows 10. Two of the commits introduce and fill the IAD structure outlined by Leo. The third commit will cause the back-end, when it encounters an IAD, to pile all of the endpoints of the grouped interfaces into the first interface of the IAD.
https://github.com/mawillia/libusb/commits/iad
The result is claiming the first interface in the IAD will pass, but claiming any of the other interfaces in the IAD will fail (as is currently the case). However, submitting requests to the end points on any of the associated interfaces appears to work as the back-end get_interface_by_endpoint() will always yield the first interface, which will have the correct underlying handle for the IO submission. I've been able to just claim the first interface of the IAD and exercise end points over a couple of the interfaces in the group this way. So far so good.
This is not a pull request or anything like that; I can't do sufficient testing to say that I haven't introduced a regression, etc. Maybe someone could take a peek and let me know if this approach has any merit or is a bad idea....
I ran into this issue (or something that looks like this) today with latest libusb release (1.0.22). I was going to try patches from @mawillia but before applying them I tried latest master (2a7372db54094a406a755f0b8548b614ba8c78ec) and it worked. I'm not sure enough that issue is solved but I'm leaving this note here in case someone else is also trying to get it working. :)
My device is STM32 Blue Pill providing composite device: CDC + WinUSB (WCID with DeviceInterfaceGUID) device. Libusb is enumerating it only once, I can open it, claim interface and perform bulk transfers.
@Novakov Could you show us the descriptors you are using? I have an identical setup but had no luck in opening the device on Windows with Libusb. (WinUsb works when called directly) Thanks
Work-around is to have WinUSB driver as the driver for the whole USB device (replacing Windows defaut USB Composite Parent driver).
I have a composite device - iface 0,1 = CDC-ACM, iface 2=WinUSB. I created a WinUSB driver as mentioned to replace the CDC driver. Unfortunately I wasn't able to claim an interface 1 when an order of claiming interfaces was 2,0,1. After changing it to 0,1,2 it seems the claiming works as expected. I just wanted to leave this note here for anybody else who is also trying to get it working.
My device is STM32 Blue Pill providing composite device: CDC + WinUSB (WCID with DeviceInterfaceGUID) device. Libusb is enumerating it only once, I can open it, claim interface and perform bulk transfers.
@Novakov Can you please share the firmware for your Blue Pill?
Well.. I can share parts of source code but it's rotten over the years and, unfortunately, I don't have binary anymore.
I have testing environment built around GD32VF on custom board and I'm planning to do some testing on it soon. If you think it would be useful I can port it to Blue Pill and share it.
I see. It would be useful for me to have a composite device with IAD for testing. But I can look into the RPi gadgetfs instead.
Give me few days, I will put something together for Blue Pill.
Thanks, but please don't put too much effort in it for my sake. I should really look at RPi gadgetfs :)
Thanks, but please don't put too much effort in it for my sake. I should really look at RPi gadgetfs :)
Yes gadgetfs or functionfs can be a good choice.
In case for STM32, you may try the following potential starting point, all with IAD. https://github.com/dijkstrw/5x5 https://github.com/openstenoproject/stenosaurus/blob/master/firmware/usb.c https://github.com/micropython/micropython/blob/master/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c
@mcuee I see that you are doing tests with RPi Pico - do you think it will be enough also for @tormodvolden purposes? My backlog of work grew a bit and if you already have something useful I will not invest building tool on STM32
Yes, I am already fine with the links from mcuee above. In particular the first was wonderful.
Now that #965 has been merged, this issue can be closed.
Let's wait for #1181 before closing this issue, as it deals with another aspect of this issue.
Related issue:
Ref: 1) http://libusbx.1081486.n5.nabble.com/Libusbx-devel-Accessing-composite-devices-using-interface-association-td1726.html https://www.mail-archive.com/libusbx-devel@lists.sourceforge.net/msg03059.html 2) http://marc.info/?t=139209996400001&r=1&w=2 3) http://sourceforge.net/p/openocd/tickets/96/
Work-around is to have WinUSB driver as the driver for the whole USB device (replacing Windows defaut USB Composite Parent driver).