Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xbox Series X|S controller HIDP input latency problem #156

Closed
kakra opened this issue Jun 17, 2021 · 8 comments
Closed

Xbox Series X|S controller HIDP input latency problem #156

kakra opened this issue Jun 17, 2021 · 8 comments

Comments

@kakra
Copy link

kakra commented Jun 17, 2021

The new model of the Xbox Series X|S controller is a BLE device, it thus uses virtual/uhid to create a HID device in user space inside the bluez daemon and exposes it to kernel drivers this way. The xpadneo project is a driver for such a HID device.

While testing the device, I found a high latency of input. It is somewhat difficult to describe, it's not exactly high latency but a strange effect. I'm not sure if that may be an issue of the device firmware itself, or if there is some HID report throttling inside bluez:

  1. Pressing a button will generate a report immediately
  2. Releasing the button again, and repeating the first two steps in a quick succession generates reports at 10 Hz
  3. HID reports will have their key bits updated immediately with the next 10 Hz cycle
  4. After stopping pressing buttons, HID reports still come in at 10 Hz, key bits are 0
  5. The incoming reports stop after some seconds, seems to depend on the amount of events generated before
  6. The problem is reproducible for axis movement

This introduces a lag of 100ms for events because reports may come in up to 100ms late. Also, each report reflects the input state of the controller at that point in time (the live state), it's not like the events are just buffered and replayed from a queue. This means, we may miss input events like button presses: If I manage to press a button multiple times per 100ms, it will register just one button press/release.

According to btmon there was no other Bluetooth activity from other devices at the same time, so it's probably not an air-time issue. As far as I can tell, the Xbox controllers should update at 100 Hz in Bluetooth mode, so we would see a latency of at most 10ms, and event reporting should stop immediately (except the first Xbox Bluetooth controller model which continues to send data for at least 20 packets after the last event).

Bluetooth monitor ver 5.58
= Note: Linux version 5.10.43-gentoo-r1 (x86_64)
= Note: Bluetooth subsystem version 2.22
= New Index: 00:1A:7D:DA:71:15 (Primary,USB,hci0)
= Open Index: 00:1A:7D:DA:71:15
= Index Info: 00:1A:7D:DA:71:15 (Cambridge Silicon Radio)
@ MGMT Open: bluetoothd (privileged) version 1.18
@Vudentz
Copy link
Contributor

Vudentz commented Jun 17, 2021

@kakra Does the delay also appears over btmon? It perhaps worth attaching the logs here so we can check the interval we received them, if it is already lagging over the air then it is likely a device problem otherwise we will need to investigate if there any buffering that could cause the processing to be this late. This could also be the connection interval is not properly set, though the defaults are 30-50ms (they used to be 50-70ms a while ago (2017)).

@kakra
Copy link
Author

kakra commented Jun 18, 2021

Actually, I took the interval from btmon. So according to your description, this means, the delay is introduced by the device itself. My main concern was about understanding that btmon is actually showing what's happening over the air - thanks for confirming that.

So yes, it's already lagging over the air. Can I set said intervals myself? For a gamepad, I think it would be important to have a maximum input delay of 10-20ms (60 fps = 16.6 ms intervals).

@kakra
Copy link
Author

kakra commented Jun 20, 2021

@Vudentz Setting the latency settings on the LE connection manually fixes the problem:

# hcitool con
Connections:
        < LE 44:16:22:BD:48:69 handle 75 state 1 lm MASTER AUTH ENCRYPT
                                      ^^
# hcitool lecup --handle 75 --latency 0 --min 7 --max 9
                         ^^

Is there a list of hard-coded devices that should get such parameters automatically set? If yes, do you need more info to add a patch to bluez?

Are these sensible settings? Since the firmware uses 100 Hz intervals internally, and the values are multiples of 1.25ms, it probably makes sense to use min=7, max=9 (8.75..11.25ms).

@Vudentz
Copy link
Contributor

Vudentz commented Jun 23, 2021

@kakra Usually connection parameters is set by the peripheral and is the saved by bluetoothd, so either the device doesn't set this properly or it is using something like the Peripheral Preferred Connection Parameters, alternatively you can set the defaults value via main.conf but that would apply to any peripheral so things might not work as expected.

@kakra
Copy link
Author

kakra commented Jun 23, 2021

@Vudentz Alternatively, is there a way I could easily set the values via udev rules? I already looked at the sysfs tree but it doesn't look like there a definitive relative path I could take from one of the device nodes to some bluetooth device parameters. I'm not even sure if there is such a sysfs interface...

kakra added a commit to atar-axis/xpadneo that referenced this issue Jun 25, 2021
It looks like the new Xbox Series X|S controller doesn't set its BLE
connection parameters properly. The problem is currently evaluated in
the bluez project. Until it's officially resolved, let's document a
work-around.

See-also: bluez/bluez#156
Fixes: #297
Maybe-fixes: #290
Signed-off-by: Kai Krakow <kai@kaishome.de>
@Vudentz Vudentz closed this as completed Sep 1, 2021
@kakra
Copy link
Author

kakra commented Sep 1, 2021

@Vudentz What does this "close" mean? Was it fixed? Closed due to inactivity? Duplicate? Or no interest in implementing some solution?

@bitbegin
Copy link

I had a similar problem.

Compare the bluedroid process. After the pairing is complete, bluedroid sets 7.5 ms connection parameters for service discovery. After service discovery is complete, the protocol stack can set the connection parameters with the device's.

In the real world, many devices do not comply with the specifications, causing many compatibility problems. It is hoped that the BlueZ protocol stack can take this situation into consideration.

@kakra
Copy link
Author

kakra commented Sep 28, 2021

After the pairing is complete, bluedroid sets 7.5 ms connection parameters for service discovery

This is even lower to what I suggested. So, with bluedroid, the latency remains at 7.5 ms because the device actually doesn't request to set any other. Then bluez should probably go with the same defaults because we probably can't expect device manufacturers to change their devices and firmwares, especially not in after-market situations. And we probably cannot expect device manufacturers to test their devices against Linux default installations anytime soon - they will test against Android with bluedroid/fluoride - and that's all about "Linux testing".

kakra added a commit to kakra/xpadneo that referenced this issue Nov 17, 2021
It looks like the new Xbox Series X|S controller doesn't set its BLE
connection parameters properly. The problem is currently evaluated in
the bluez project. Until it's officially resolved, let's document a
work-around.

See-also: bluez/bluez#156
Fixes: atar-axis#297
Maybe-fixes: atar-axis#290
Signed-off-by: Kai Krakow <kai@kaishome.de>
kakra added a commit to atar-axis/xpadneo that referenced this issue May 26, 2022
It looks like the new Xbox Series X|S controller doesn't set its BLE
connection parameters properly. The problem is currently evaluated in
the bluez project. Until it's officially resolved, let's document a
work-around.

See-also: bluez/bluez#156
Fixes: #297
Maybe-fixes: #290
Signed-off-by: Kai Krakow <kai@kaishome.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants