cezanne / usbip-win

USB/IP for Windows
GNU General Public License v3.0
1.98k stars 350 forks source link

Dropped keystrokes #187

Closed RoganDawes closed 2 years ago

RoganDawes commented 4 years ago

Hi,

I am experimenting with usbip and Logitech Unifying receivers. I have an automated system sending keystrokes to the receiver, at a higher than usual rate. This works fine natively, or when being passed through to a VM using VMWare Workstation. Unfortunately, it doesn't work well using usbip, as some keystrokes go missing. I suspect that this is because the Unifying dongle doesn't have any buffer space to store the keystrokes, and, if usbip's request for any outstanding keystrokes is delayed for any reason, the next report received over the air overwrites the previous one. Having looked at the usbip protocol documentation in the Linux kernel, it appears that it is possible to pipeline multiple requests to the usbip server, and process any responses as they come. i.e. pre-seed the pipeline with 100 or more USBIP_CMD_SUBMIT messages, and whenever a USBIP_RET_SUBMIT response is received, continue to submit further USBIP_CMD_SUBMIT messages to ensure there is a buffer of messages to "smooth out" any latency issues that may occur. Does the Windows client implementation do anything along these lines? Thanks for a really neat tool!

cezanne commented 3 years ago

@RoganDawes : usbip protocol does not have flow control. It's a best effort protocol. In general, a command submitted by vhci will be eventually processed unless cancelled. However, if there's no pending interrupt transfer in a usbip server and a keyboard H/W cannot keep the strokes, keyboard event may drop. In this case, it is definitely a HW issue even though a faster vhci can relieve dropping rate.

RoganDawes commented 3 years ago

Not sure if I explained my thinking well, let me try again.

Imagine a USB host driver polling at a rate of 1 interrupt request per second rather than the more usual 125Hz or 1000Hz. If the device is a keyboard, and the user presses more than one key per second, surely keystrokes will be lost, as I would not expect the keyboard to maintain a buffer of pressed keys. Normally the host polls fast enough that this should not ever be a problem. I would not call that a hardware issue, rather a host driver problem.

From what I understand, the usbip client sends an interrupt request message to the server, and the server then sends that message to the device, gets the response, and returns it to the client. Naturally, there is network latency between the usbip client and the server, which would normally limit the ultimate polling rate to the device to (1/latency). By sending multiple interrupt request messages to the uspip server, without waiting for the responses, the usbip client can create a pipeline of request messages, largely eliminating the latency from the polling rate, ultimately depending on how many requests are pipelined.

Hypothetically, ensuring that there are always (say) 1000 unanswered requests waiting at the server should ensure that no keyboard reports go missing. I was suggesting making the number of outstanding/pipelined requests configurable, depending on the expected latency of the connection between the server and client.

cezanne commented 3 years ago

@RoganDawes :

I would not call that a hardware issue, rather a host driver problem.

I agree that a function driver may be the problem.

Hypothetically, ensuring that there are always (say) 1000 unanswered requests waiting at the server should ensure that no keyboard reports go missing. I was suggesting making the number of outstanding/pipelined requests configurable, depending on the expected latency of the connection between the server and client.

usbip(vhci) can be tweaked by sending supplementary interrupt transfers but it's not an elegant way for usbip to intervene the role of an upper function driver. More consideration is required.

cezanne commented 2 years ago

@RoganDawes : This issue will be closed. Please reopen if you need.