Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
I am writing USB device emulator using Microsoft Usb Device Emulation framework.
So far I have implemented support for interrupt and bulk transfers, but isochronous transfers just do not work.
Driver sets up dynamic endpoints (UdecxUsbDeviceInitSetEndpointsType is called with UdecxEndpointTypeDynamic). So when virtual USB device is plugged (UdecxUsbDevicePlugIn), UDE framework calls callback for endpoint creation. There I create and associate queue with endpoint:
Here is a part of the code:
...
WDF_IO_QUEUE_CONFIG queueConfig;
WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchSequential);
queueConfig.EvtIoInternalDeviceControl = OnTestIoInternalControl;
queueConfig.EvtIoCanceledOnQueue = OnTestCancelled;
queueConfig.EvtIoDefault = OnTestDefault;
queueConfig.EvtIoDeviceControl = OnTestIoControl;
queueConfig.EvtIoRead = OnTestRead;
queueConfig.EvtIoResume = OnTestResume;
queueConfig.EvtIoStop = OnTestStop;
queueConfig.EvtIoWrite = OnTestWrite;
WdfIoQueueCreate(hubDevice, &queueConfig, &queueAttributes, &queue);
...
UdecxUsbEndpointCreate(&endpointInit, &endpointAttributes, &udecxEndpoint);
UdecxUsbEndpointSetWdfIoQueue(udecxEndpoint, queue);
Note: I have just extracted part of the code, to make this post as short as possible
For bulk and interrupt endpoints it works fine, but for isochronous endpoint no "Test" callbacks are called. From log I can see that UDE has created endpoint and queue. USBVIEW shows opened pipe for isochronous endpoint, but when I try to play some music (tested virtual USB is audio device) it just does not trigger any callbacks that I could use to transfer data.
Does anybody know is isochronous transfers supported at all by Microsoft UDE?
If so, is there any additional setup required to make this work?
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Kernel Debugging | 30 January 2023 | Live, Online |
Developing Minifilters | 20 March 2023 | Live, Online |
Internals & Software Drivers | 17 April 2023 | Live, Online |
Writing WDF Drivers | 22 May 2023 | Live, Online |
Comments
Yes, UDE supports isochronous transfers but you need to be careful of certain pitfalls with the descriptors. Can you post your Configuration Descriptor here?
(Sorry for double or triple posting, somehow my post was deleted when I tried to edit)
I have a similar issue with an emulated audio device. Communication with default control endpoint is OK, but the ISO endpoint's callback is only called once, then never again. Looks like something is blocking the queue, but I have no idea what.
Here is the configuration descriptor I use. This should be a simple stereo USB speaker with 16bit / 48 kHz plus volume and mute controls.
How are you testing this? In battle, using a live audio app?
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
Thanks @Andreas_Graefe , I will try with hardcoded descriptor - just to see what happens.
Have you used static or dynamic endpoints?
For my project: I am doing USB forwarding. So I get configuration descriptor of remote device - I have double check - it is correct configuration. Basically when I "forward" device with bulk and interrupt endpoints, everything works fine. Just device with isochronous endpoints does not trigger any callbacks (to perform USB transfers). So I thought I am missing something for isochronous transfers.
Are you using
UsbFullSpeed
orUsbHighSpeed
? If usingUsbFullSpeed
, try switching toUsbHighSpeed
instead and retry.@Benjamin_Höglinger I am using UdecxUsbHighSpeed, but I will try another values just to see will it make any difference.
@Tim_Roberts: I'm testing it "in battle" (nice term btw).
I also looked into manually creating URBs and sending it to the device via the WinUSB API (following this guide but I wasn't able to open the device from my test application. As far as I understand, this is because the device is already "in use" by Windows' class audio driver, but I didn't find a way to work around this.
@bojan_janjic, @Benjamin_Höglinger
Regarding the speed: I tried both UsbFullSpeed and UsbHighSpeed, made no difference.
Regarding static and dynamic endpoints: I started with this UDE sample, which uses static endpoints and modified it to use the descriptor posted above, then I switched to dynamic endpoints.
I did that because I learned that the EvtUsbDeviceEndpointsConfigure callback (which handles the altsettings requests for an audio interface) is only called when dynamic endpoints are used.
Now I see the EvtUsbDeviceEndpointsConfigure callback called with setting my audio interfaces' altsetting to 0 (which means audio playback is stopped), but it never seems to be set to 1 when I try to play something.
@Andreas_Graefe for WinUSB:
Yes Windows blocks lot of devices: has own services that use device. So to access device you will need to do it from kernel - I did write a filter driver to make it work.
For EvtUsbDeviceEndpointsConfigure:
I have noticed that it does not trigger correctly alternate setting change - even found a Github project where somebody else had similar issue and was making a workaround. So I will make a workaround for my project to deal with alternate setting change.
However I do receive EvtUsbDeviceEndpointsConfigure when alternate setting is changed (to choose setting that activates endpoint). I see that endpoint is created and usbview displays that endpoint's pipe is opened. But UDE does not fire any of events for data transmission.
Yes, I can confirm that behaviour. The altsetting is either incorrect (set to 0 when it should be set to 1) or it's just not called.
I believe that something needs to be done in EvtUsbDeviceEndpointsConfigure, but I don't know what.
Can you please post the link to the mentioned github project? Would like to take a look myself at this workaround.
https://github.com/cezanne/usbip-win
Ah yes, I also looked into that before. I also tried it out, but it also wasn't able to forward an audio device properly (at least I didn't manage to get it running).
Indeed,
EvtUsbDeviceEndpointsConfigure
is called withUdecxEndpointsConfigureTypeInterfaceSettingChange
, butParams->InterfaceNumber
andParams->NewInterfaceSetting
are wrong.I'm asking myself what needs to be done in the
EvtUsbDeviceEndpointsConfigure
callback to notify the framework that the interface setting request was sucessful. I'm just doing(because I only want to simulate an audio device), but this is seems to be not enough. Perhaps the endpoint has to be started / restarted somehow, but I was assuming that this is already done by the framework in the
EvtUsbDeviceEndpointAdd
callback.I have logged today what values are received in EvtUsbDeviceEndpointsConfigure, and it is for sure wrong.
Device has interface 1 for speaker with 2 alternate settings:
0 - no endpoints
1 - two isochronous endpoints
When I try to test speaker, USB analyzer tool shows that alternate setting 1 of interface 1 is selected, however in EvtUsbDeviceEndpointsConfigure callback I receive:
InterfaceNumber = 1
NewInterfaceSetting = 0
Like streaming is off (alternate setting has not endpoints), but that is not the case. UDE driver actually created 2 endpoints and device has opened pipes.
I have tried to "fix" value for NewInterfaceSetting, but again I do not receive any data.
Seems like problem is not with isochronous endpoints, but with interfaces that have alternate settings.
Took a couple months of excruciating research, trial and error but we finally cracked it!
UDE doesn't implement
QueryBusTime
inUSB_BUS_INTERFACE_USBDI_V1
whichUSBAUDIO.SYS
depends on to compare frame times. I've reported this to Microsoft and in the meantime have written a filter driver to mitigate this problem and now audio works with UDE! I'll update my post once I got a writeup published.Cheers