atar-axis / xpadneo

Advanced Linux Driver for Xbox One Wireless Controller (shipped with Xbox One S)
https://atar-axis.github.io/xpadneo/
GNU General Public License v3.0
1.92k stars 111 forks source link

Incorrect buttons mapping on XBox Series X controller #291

Closed anton-gorbikov closed 3 years ago

anton-gorbikov commented 3 years ago

Version of xpadneo

0.9

Severity / Impact

Medium

Describe the bug

Some buttons have incorrect mappings, some don't work at all (probably unmapped):

Steps to Reproduce

  1. Connect the wireless XBox Series X controller to Raspberry Pi 4.
  2. Run Steam Link
  3. Run any game or controller test

Expected behavior

Buttons should be mapped properly

System information

# uname -a
Linux raspberrypi 5.10.17-v7l+ #1414 SMP Fri Apr 30 13:20:47 BST 2021 armv7l GNU/Linux
# xxd -c20 -g1 /sys/module/hid_xpadneo/drivers/hid:xpadneo/0005:045E:*/report_descriptor | tee >(cksum)
00000000: 05 01 09 05 a1 01 85 01 09 01 a1 00 09 30 09 31 15 00 27 ff  .............0.1..'.
00000014: ff 00 00 95 02 75 10 81 02 c0 09 01 a1 00 09 33 09 34 15 00  .....u.........3.4..
00000028: 27 ff ff 00 00 95 02 75 10 81 02 c0 05 01 09 32 15 00 26 ff  '......u.......2..&.
0000003c: 03 95 01 75 0a 81 02 15 00 25 00 75 06 95 01 81 03 05 01 09  ...u.....%.u........
00000050: 35 15 00 26 ff 03 95 01 75 0a 81 02 15 00 25 00 75 06 95 01  5..&....u.....%.u...
00000064: 81 03 05 01 09 39 15 01 25 08 35 00 46 3b 01 66 14 00 75 04  .....9..%.5.F;.f..u.
00000078: 95 01 81 42 75 04 95 01 15 00 25 00 35 00 45 00 65 00 81 03  ...Bu.....%.5.E.e...
0000008c: 05 09 19 01 29 0c 15 00 25 01 75 01 95 0c 81 02 15 00 25 00  ....)...%.u.......%.
000000a0: 75 01 95 04 81 03 05 0c 0a b2 00 15 00 25 01 95 01 75 01 81  u............%...u..
000000b4: 02 15 00 25 00 75 07 95 01 81 03 05 0f 09 21 85 03 a1 02 09  ...%.u........!.....
000000c8: 97 15 00 25 01 75 04 95 01 91 02 15 00 25 00 75 04 95 01 91  ...%.u.......%.u....
000000dc: 03 09 70 15 00 25 64 75 08 95 04 91 02 09 50 66 01 10 55 0e  ..p..%du......Pf..U.
000000f0: 15 00 26 ff 00 75 08 95 01 91 02 09 a7 15 00 26 ff 00 75 08  ..&..u.........&..u.
00000104: 95 01 91 02 65 00 55 00 09 7c 15 00 26 ff 00 75 08 95 01 91  ....e.U..|..&..u....
00000118: 02 c0 c0                                                     ...
2986910699 1363

Controller and Bluetooth information

xpadneo-btmon.txt xpadneo-dmesg.txt I don't use dongle, hence no xpadneo-lsusb.txt attachment.

Additional context

I've tried to use quirks mode from the discussion in the related issue: https://github.com/atar-axis/xpadneo/issues/273 but it didn't help.

AlexandreLaborde commented 3 years ago

I have the exact same issue. The button mapping is correct over USB but I have the same incorrect mapping via Bluetooth.

kakra commented 3 years ago

I'm working on a solution already that may solve it, however this is the second time this is reported with Steam Link involved so I believe it is doing something unexpected.

Your dmesg lists:

[   28.066124] xpadneo 0005:045E:0B13.0001: input,hidraw0: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller] on DC:A6:32:D6:A6:67

Could you check the permissions of /dev/hidraw0 (or whatever hidraw number it showed after connection)? Do you know which user Steam Link does run under? Does it have read and/or write access to this hidraw device?

AlexandreLaborde commented 3 years ago

output of dmesg

[   19.250803] hid_xpadneo: loading out-of-tree module taints kernel.
[   19.251459] hid_xpadneo: unknown parameter 'disable_ff' ignored
[   19.251650] loaded hid-xpadneo v0.9-63-gf17a4e2
[   19.251739] xpadneo 0005:045E:0B13.0001: pretending XB1S Windows wireless mode (changed PID from 0x0B13 to 0x02E0)
[   19.251752] xpadneo 0005:045E:0B13.0001: working around wrong SDL2 mappings (changed version from 0x00000505 to 0x00000903)
[   19.251766] xpadneo 0005:045E:0B13.0001: report descriptor size: 283 bytes
[   19.251777] xpadneo 0005:045E:0B13.0001: fixing up Rx axis
[   19.251787] xpadneo 0005:045E:0B13.0001: fixing up Ry axis
[   19.251797] xpadneo 0005:045E:0B13.0001: fixing up Z axis
[   19.251806] xpadneo 0005:045E:0B13.0001: fixing up Rz axis
[   19.251816] xpadneo 0005:045E:0B13.0001: fixing up button mapping
[   19.252962] xpadneo 0005:045E:0B13.0001: gamepad detected
[   19.252974] xpadneo 0005:045E:0B13.0001: enabling compliance with Linux Gamepad Specification
[   19.254472] xpadneo 0005:045E:0B13.0001: input,hidraw0: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[   19.254493] xpadneo 0005:045E:0B13.0001: controller quirks: 0x00000050
[   19.254505] xpadneo xpadneo_welcome_rumble start
[   20.244828] xpadneo xpadneo_welcome_rumble took 990ms
[   20.244870] xpadneo 0005:045E:0B13.0001: Xbox Wireless Controller 4416226D773F [44:16:22:6d:77:3f] connected
[   20.905328] xpadneo 0005:045E:0B13.0002: pretending XB1S Windows wireless mode (changed PID from 0x0B13 to 0x02E0)
[   20.905344] xpadneo 0005:045E:0B13.0002: working around wrong SDL2 mappings (changed version from 0x00000505 to 0x00000903)
[   20.905359] xpadneo 0005:045E:0B13.0002: report descriptor size: 283 bytes
[   20.905371] xpadneo 0005:045E:0B13.0002: fixing up Rx axis
[   20.905382] xpadneo 0005:045E:0B13.0002: fixing up Ry axis
[   20.905393] xpadneo 0005:045E:0B13.0002: fixing up Z axis
[   20.905403] xpadneo 0005:045E:0B13.0002: fixing up Rz axis
[   20.905414] xpadneo 0005:045E:0B13.0002: fixing up button mapping
[   20.906647] xpadneo 0005:045E:0B13.0002: gamepad detected
[   20.906659] xpadneo 0005:045E:0B13.0002: enabling compliance with Linux Gamepad Specification
[   20.908709] xpadneo 0005:045E:0B13.0002: input,hidraw0: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[   20.908730] xpadneo 0005:045E:0B13.0002: controller quirks: 0x00000050
[   20.908743] xpadneo xpadneo_welcome_rumble start
[   21.899463] xpadneo xpadneo_welcome_rumble took 990ms
[   21.899616] xpadneo 0005:045E:0B13.0002: Xbox Wireless Controller 4416226D773F [44:16:22:6d:77:3f] connected
[   21.975728] xpadneo 0005:045E:0B13.0002: consumer controls not detected
[  921.798999] xpadneo 0005:045E:0B13.0003: pretending XB1S Windows wireless mode (changed PID from 0x0B13 to 0x02E0)
[  921.799009] xpadneo 0005:045E:0B13.0003: working around wrong SDL2 mappings (changed version from 0x00000505 to 0x00000903)
[  921.799018] xpadneo 0005:045E:0B13.0003: report descriptor size: 283 bytes
[  921.799025] xpadneo 0005:045E:0B13.0003: fixing up Rx axis
[  921.799032] xpadneo 0005:045E:0B13.0003: fixing up Ry axis
[  921.799039] xpadneo 0005:045E:0B13.0003: fixing up Z axis
[  921.799045] xpadneo 0005:045E:0B13.0003: fixing up Rz axis
[  921.799052] xpadneo 0005:045E:0B13.0003: fixing up button mapping
[  921.799811] xpadneo 0005:045E:0B13.0003: gamepad detected
[  921.799818] xpadneo 0005:045E:0B13.0003: enabling compliance with Linux Gamepad Specification
[  921.800289] xpadneo 0005:045E:0B13.0003: input,hidraw0: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[  921.800301] xpadneo 0005:045E:0B13.0003: controller quirks: 0x00000050
[  921.800309] xpadneo xpadneo_welcome_rumble start
[  922.790439] xpadneo xpadneo_welcome_rumble took 990ms
[  922.790459] xpadneo 0005:045E:0B13.0003: Xbox Wireless Controller 4416226D773F [44:16:22:6d:77:3f] connected
[ 7348.485168] xpadneo 0005:045E:0B13.0007: pretending XB1S Windows wireless mode (changed PID from 0x0B13 to 0x02E0)
[ 7348.485191] xpadneo 0005:045E:0B13.0007: working around wrong SDL2 mappings (changed version from 0x00000505 to 0x00000903)
[ 7348.485212] xpadneo 0005:045E:0B13.0007: report descriptor size: 283 bytes
[ 7348.485229] xpadneo 0005:045E:0B13.0007: fixing up Rx axis
[ 7348.485246] xpadneo 0005:045E:0B13.0007: fixing up Ry axis
[ 7348.485262] xpadneo 0005:045E:0B13.0007: fixing up Z axis
[ 7348.485278] xpadneo 0005:045E:0B13.0007: fixing up Rz axis
[ 7348.485294] xpadneo 0005:045E:0B13.0007: fixing up button mapping
[ 7348.487010] xpadneo 0005:045E:0B13.0007: gamepad detected
[ 7348.487028] xpadneo 0005:045E:0B13.0007: enabling compliance with Linux Gamepad Specification
[ 7348.493076] xpadneo 0005:045E:0B13.0007: input,hidraw1: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[ 7348.493106] xpadneo 0005:045E:0B13.0007: controller quirks: 0x00000050
[ 7348.493126] xpadneo xpadneo_welcome_rumble start
[ 7349.483261] xpadneo xpadneo_welcome_rumble took 990ms
[ 7349.483279] xpadneo 0005:045E:0B13.0007: Xbox Wireless Controller 4416226D773F [44:16:22:6d:77:3f] connected
[ 7349.562422] xpadneo 0005:045E:0B13.0007: consumer controls not detected

Permissions of /dev/hidraw0 : crw-rw---- 1 root input 244, 0 May 21 20:17 hidraw0

Steam Link creates several processes but they all appear to be running under the default user pi

kakra commented 3 years ago

Then try to chmod a-rwx /dev/hidraw0 after connecting the controller, if possible, restart the Steam Link process. Now check the mappings again.

AlexandreLaborde commented 3 years ago

Did that and restarted the process, the mappings still don't work. The weird part is that every button is mapped correctly on https://gamepad-tester.com/ before and after the chmod๐Ÿคทโ€โ™‚๏ธ

AlexandreLaborde commented 3 years ago

I tested the mappings using jstest /dev/input/js0 and it registers the correct controller and keys.

Driver version is 2.1.0.
Joystick (Xbox Wireless Controller 4416226D773F) has 9 axes (X, Y, Z, Rx, Ry, Rz, Hat0X, Hat0Y, (null))
and 10 buttons (BtnA, BtnB, BtnX, BtnY, BtnTL, BtnTR, BtnSelect, BtnStart, BtnThumbL, BtnThumbR).

Every button maps correctly. It must be something in Steam Link.

I also noticed that dmesg shows this [ 117.925707] input: Valve virtual keyboard as /devices/virtual/input/input3. Maybe we should check this one somehow.

kakra commented 3 years ago

Well, my request for chmod was because Steam Input (or rather SDL2 to be more specific) can read input directly from hidraw, and xpadneo exposes a mapping there that matches correctly with the VID/PID but SDL2 looks at the HID packet size instead to decide which mapping it sees. Revoking permissions from that device node prevents SDL2 to use it and fall back to evdev which has the correct mapping anyways.

As a local test, you could try evtest to see that the mappings are actually correct as seen by the input layer (but don't let it fool you with the north/east/south/west, it's still correct, Y and X seem swapped there). If Steam Link skips that or doesn't respect the evdev device as it should, it won't work.

The online gamepad tester is its own thing: It works differently in Chrome and Firefox, and at least in Chrome, it reads mappings from evdev but then statically maps jsdev positional event sources to the evdev mappings and uses jsdev - which goes wrong sometimes. So it completely ignores whatever mapping is defined - even adjusting jsdev would confuse it. OTOH, this may mean it's immune to whatever Steam Link messes up.

Steam Input creates virtual input devices so it can apply custom mappings, even from gamepad buttons to keyboard, thus there's a virtual keyboard.

This one confuses me:

[ 7349.562422] xpadneo 0005:045E:0B13.0007: consumer controls not detected

Is this the Xbox controller with the share button? It should have a consumer control device. Did you update it to latest firmware?

AlexandreLaborde commented 3 years ago

I have this controller : Xbox Wireless Controller Firmware version : 5.5.2641.0

Here's the result of the evtest:

No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event0:      Xbox Wireless Controller 4416226D773F
Select the device event number [0-0]: 0
Input driver version is 1.0.1
Input device ID: bus 0x5 vendor 0x45e product 0x2e0 version 0x903
Input device name: "Xbox Wireless Controller 4416226D773F"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 304 (BTN_SOUTH)
    Event code 305 (BTN_EAST)
    Event code 307 (BTN_NORTH)
    Event code 308 (BTN_WEST)
    Event code 310 (BTN_TL)
    Event code 311 (BTN_TR)
    Event code 314 (BTN_SELECT)
    Event code 315 (BTN_START)
    Event code 317 (BTN_THUMBL)
    Event code 318 (BTN_THUMBR)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value    747
      Min   -32768
      Max    32767
      Flat    3072
    Event code 1 (ABS_Y)
      Value   -592
      Min   -32768
      Max    32767
      Flat    3072
    Event code 2 (ABS_Z)
      Value      0
      Min        0
      Max     1023
      Fuzz       4
    Event code 3 (ABS_RX)
      Value    543
      Min   -32768
      Max    32767
      Fuzz      32
      Flat    3072
    Event code 4 (ABS_RY)
      Value    -19
      Min   -32768
      Max    32767
      Fuzz      32
      Flat    3072
    Event code 5 (ABS_RZ)
      Value      0
      Min        0
      Max     1023
      Fuzz       4
    Event code 16 (ABS_HAT0X)
      Value      0
      Min       -1
      Max        1
    Event code 17 (ABS_HAT0Y)
      Value      0
      Min       -1
      Max        1
    Event code 40 (ABS_MISC)
      Value      0
      Min    -1023
      Max     1023
      Fuzz       3
      Flat      63
  Event type 4 (EV_MSC)
    Event code 4 (MSC_SCAN)
  Event type 21 (EV_FF)
    Event code 80 (FF_RUMBLE)
    Event code 81 (FF_PERIODIC)
    Event code 88 (FF_SQUARE)
    Event code 89 (FF_TRIANGLE)
    Event code 90 (FF_SINE)
    Event code 96 (FF_GAIN)
Properties:
Testing ... (interrupt to exit)

And what the buttons on the controller map to: I named the buttons following XBox support naming https://support.xbox.com/en-US/help/hardware-network/controller/get-to-know-your-xbox-series-x-s-controller

Controller evtest
A BTN_SOUTH
B BTN_EAST
X BTN_NORTH
Y BTN_WEST
D-Pad Left ABS_HAT0X(-1)
D-Pad Right ABS_HAT0X(1)
D-Pad Up ABS_HAT0Y(-1)
D-Pad Down ABS_HAT0Y(1)
View Button BTN_SELECT
Menu Button BTN_START
Share Button NO RESPONSE
Xbox Button NO RESPONSE
Left Bumper BTN_TL
Right Bumper BTN_TR
Left Trigger ABS_Z
Right Trigger ABS_RZ
Left thumbstick Up ABS_Y(-)
Left thumbstick Down ABS_Y(+)
Left thumbstick Left ABS_X(-)
Left thumbstick Right ABS_X(+)
Right thumbstick Up ABS_RY(-)
Right thumbstick Down ABS_RY(+)
Right thumbstick Left ABS_RX(-)
Right thumbstick Right ABS_RX(+)
Left thumbstick Press BTN_THUMBL
Right thumbstick Press BTN_THUMBR

Even though X and Y are swapped, the Left Bumper does not appear to map to Y like it does inside Steam Link.

anton-gorbikov commented 3 years ago

I've tested my gamepad on the Gamepad Tester and it looks like it's working fine. Also, I've noticed that Steam Link app shows my controller as "XBox One S Controller" which is not true. On the support page, I see that "XBox Series" controllers are still missing. It looks like it's Steam Link issue, not the driver issue.

I'm not sure if anything can be done on the driver's side. If that's so, you can close the bug. Sorry for inconvinience.

AlexandreLaborde commented 3 years ago

But my gamepad works as intended when connected via USB. What about yours @anton-gorbikov ?

kakra commented 3 years ago

@AlexandreLaborde USB uses a completely different mapping protocol, and xpadneo is for Bluetooth only. So there's no point in comparing it against USB: For user space software, the controller is two completely distinct devices when connected via USB or Bluetooth.

kakra commented 3 years ago

@AlexandreLaborde X and Y is not swapped, BTN_Y and BTN_WEST are actually the same value in the Linux kernel, same for X and north. If evtest would should BTN_{A,B,X,Y} symbols instead, the mapping would look correct. Games internally use the values of the button symbols instead of the cardinal directions.

About these:

Controller evtest
View Button BTN_SELECT
Menu Button BTN_START
Share Button NO RESPONSE
Xbox Button NO RESPONSE

It looks correct but evtest should show more than one device instance of your Xbox controller: It should also show a consumer controls device, and that one would have the Share button and the Xbox button. As you can see in the initial output of evtest, it doesn't support events for the Guide or the Share button - that is expected because those are keyboard events, and cannot exist on a gaming input device (except for the Guide button but that is ordered into a wrong position by Linux and we can do nothing about it but exclude it from the button map which is okay because games have no business with this button anyways).

If testing, basically in the very first instance evtest has to work correctly. Everything else builds upon it, even jstest. If evtest isn't correct, there's no point in testing anything else. Programs that use SDL2 are a different story, depending on hidraw permissions, they may read the device even before evdev but still that's usually a thing I'm looking into last because SDL2 uses some strange detection heuristics to detect the device which can go wrong with xpadneo.

[ 7349.562422] xpadneo 0005:045E:0B13.0007: consumer controls not detected

So I probably need to bite the bullet now and add synthetic device support for your controller now. We are going to do it anyways to add keyboard and mouse mode support to the driver soon.

kakra commented 3 years ago

@anton-gorbikov @AlexandreLaborde OTOH, according to the HID descriptor, the consumer controls device should exist. Could you retry with a Steam process stopped on the system? I want to ensure that Steam virtual input doesn't interfere with anything.

AlexandreLaborde commented 3 years ago

@AlexandreLaborde USB uses a completely different mapping protocol, and xpadneo is for Bluetooth only. So there's no point in comparing it against USB: For user space software, the controller is two completely distinct devices when connected via USB or Bluetooth.

Sorry for my stupidity ๐Ÿ˜… moving on

AlexandreLaborde commented 3 years ago

@anton-gorbikov @AlexandreLaborde OTOH, according to the HID descriptor, the consumer controls device should exist. Could you retry with a Steam process stopped on the system? I want to ensure that Steam virtual input doesn't interfere with anything.

I completely removed Steam Link, rebooted the device and confirmed in htop that there is are no steam related processes running. This is the output of dmesg:

[  209.966380] input: Xbox Wireless Controller 4416226D773F as /devices/virtual/misc/uhid/0005:045E:0B13.0004/input/input8
[  209.966843] hid-generic 0005:045E:0B13.0004: input,hidraw2: BLUETOOTH HID v5.05 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[  210.132562] hid_xpadneo: loading out-of-tree module taints kernel.
[  210.133280] hid_xpadneo: unknown parameter 'disable_ff' ignored
[  210.133492] loaded hid-xpadneo v0.9-63-gf17a4e2
[  210.133598] xpadneo 0005:045E:0B13.0004: pretending XB1S Windows wireless mode (changed PID from 0x0B13 to 0x02E0)
[  210.133612] xpadneo 0005:045E:0B13.0004: working around wrong SDL2 mappings (changed version from 0x00000505 to 0x00000903)
[  210.133627] xpadneo 0005:045E:0B13.0004: report descriptor size: 283 bytes
[  210.133639] xpadneo 0005:045E:0B13.0004: fixing up Rx axis
[  210.133650] xpadneo 0005:045E:0B13.0004: fixing up Ry axis
[  210.133660] xpadneo 0005:045E:0B13.0004: fixing up Z axis
[  210.133671] xpadneo 0005:045E:0B13.0004: fixing up Rz axis
[  210.133681] xpadneo 0005:045E:0B13.0004: fixing up button mapping
[  210.135022] xpadneo 0005:045E:0B13.0004: gamepad detected
[  210.135035] xpadneo 0005:045E:0B13.0004: enabling compliance with Linux Gamepad Specification
[  210.135233] input: Xbox Wireless Controller 4416226D773F as /devices/virtual/misc/uhid/0005:045E:0B13.0004/input/input9
[  210.136155] xpadneo 0005:045E:0B13.0004: input,hidraw2: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[  210.136175] xpadneo 0005:045E:0B13.0004: controller quirks: 0x00000050
[  210.136188] xpadneo xpadneo_welcome_rumble start
[  211.126472] xpadneo xpadneo_welcome_rumble took 990ms
[  211.126523] xpadneo 0005:045E:0B13.0004: Xbox Wireless Controller 4416226D773F [44:16:22:6d:77:3f] connected
[  211.183256] xpadneo 0005:045E:0B13.0004: consumer controls not detected

Is there some level of verbose I can increase somewhere to give you more information?

Can this be related to the hacky way I described in #287 to connect my controller? @kakra do you think it is worth it for me to compile the kernel to v5.12 to have a proper pairing process or do you believe it is unrelated to that?

AlexandreLaborde commented 3 years ago

@kakra @anton-gorbikov I THINK I GOT IT!๐Ÿฅณ I uninstalled steamlink, shutdown my gamepad and rebooted the Pi. After that I connected the gamepad, did the chmod a-rwx /dev/hidraw0 and installed steamlink and it worked!

working

Played a game and every button worked as expected.

After that, I turn the gamepad off and on and this reset the permissions of /dev/hidraw0. This caused Steam Link to recognize the controller as a Xbox One S Controller.

notworking

Now the mappings are wrong as before. I terminated all Steam Link processes and ran the chmod again, started Steam Link and it recognized once again as the Xbox One Wireless Controller.

I guess you were right all along @kakra but for some reason it did not work when I tried it the first time.

kakra commented 3 years ago

Okay, let's try the following: Edit the udev rule to revoke permissions from the created hidraw device so it will persist across reconnects:

# /etc/udev/rules.d/60-xpadneo.rules
ACTION=="add", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*|0005:045E:0B05.*|0005:045E:0B13.*", SUBSYSTEM=="hid", DRIVER!="xpadneo", ATTR{driver/unbind}="%k", ATTR{[drivers/hid:xpadneo]bind}="%k"
ACTION=="add|change", DRIVERS=="xpadneo", SUBSYSTEM=="input", TAG+="uaccess"
## add this line:
ACTION=="add|change", DRIVERS=="xpadneo", KERNEL=="hidraw*", MODE:="0000"

It should work around the issue.

Easiest way to apply the new rules is rebooting the system.

kakra commented 3 years ago

Can this be related to the hacky way I described in #287 to connect my controller?

No, shouldn't make a difference.

@kakra do you think it is worth it for me to compile the kernel to v5.12 to have a proper pairing process or do you believe it is unrelated to that?

The major difference is the L2CAP patch in kernel 5.12. If you know how to patch your distributions kernel, you could simply add that single patch to your running kernel and it should be able to pair at least somewhat reliably. If there's a kernel 5.12 available, it may be worth trying that.

I terminated all Steam Link processes and ran the chmod again, started Steam Link and it recognized once again as the Xbox One Wireless Controller.

The problem is that the device node will be recreated after reconnect, so it gets the default permissions again. Also, it may appear with a new number (e.g., hidraw2). The udev rule change above should take care of that: It compares added and changed devices to match the hidraw device name and the xpadneo driver, and then assigns a final (:=) value to the permissions. Assigning an overwritable value with = instead of := could also work but later rules could then overwrite the mode value.

kakra commented 3 years ago

We still need to figure out why there is no consumer control subdevice.

AlexandreLaborde commented 3 years ago

Okay, let's try the following: Edit the udev rule to revoke permissions from the created hidraw device so it will persist across reconnects:

# /etc/udev/rules.d/60-xpadneo.rules
ACTION=="add", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*|0005:045E:0B05.*|0005:045E:0B13.*", SUBSYSTEM=="hid", DRIVER!="xpadneo", ATTR{driver/unbind}="%k", ATTR{[drivers/hid:xpadneo]bind}="%k"
ACTION=="add|change", DRIVERS=="xpadneo", SUBSYSTEM=="input", TAG+="uaccess"
## add this line:
ACTION=="add|change", DRIVERS=="xpadneo", KERNEL=="hidraw*", MODE:="0000"

It should work around the issue.

Easiest way to apply the new rules is rebooting the system.

Did this and rebooted and it still goes back to the Xbox Ones S Controller. applying the chmod still fixes this.

My /etc/udev/rules.d/60-xpadneo.rules now looks like this:

ACTION=="add", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*|0005:045E:0B05.*|0005:045E:0B13.*", SUBSYSTEM=="hid", DRIVER!="xpadneo", ATTR{driver/unbind}="%k", ATTR{[drivers/hid:xpadneo]bind}="%k"
ACTION=="add|change", DRIVERS=="xpadneo", SUBSYSTEM=="input", TAG+="uaccess"
ACTION=="add|change", DRIVERS=="xpadneo", KERNEL=="hidraw*", MODE:="0000"

Permissions before the chmod and after rebooting with your fix: crw-rw---- 1 root input 244, 0 May 22 22:31 hidraw0

AlexandreLaborde commented 3 years ago

We still need to figure out why there is no consumer control subdevice.

I am happy to help you. Just tell me what to do. I can put my Pi on a DMZ and let you test remotely if you are interested.

kakra commented 3 years ago

Could you try my PR #292 which should fix both issues?

It should add the missing consumer control subdevice so you can test the Share and Xbox button in evtest. Verify the dmesg output first, if it is detected, run evtest.

It should also fix the permissions, at least this worked for me after I changed the udev rules: The permissions were successfully set to 0000. If it doesn't work for you, we need to find out why. A proper test could be to run udevadm monitor as root, then connect the gamepad.

AlexandreLaborde commented 3 years ago

This was my first time testing someone else's PR so let me know if I did something wrong.

I uninstalled xpadneo, cloned the repo and checkout fixes/291, install from there and rebooted the device.

Installation log:

* installing module (using DKMS)

Creating symlink /var/lib/dkms/hid-xpadneo/v0.9-68-gfef8e4c/source ->
                 /usr/src/hid-xpadneo-v0.9-68-gfef8e4c

DKMS: add completed.

Kernel preparation unnecessary for this kernel.  Skipping...

Building module:
cleaning build area...
make -j4 KERNELRELEASE=5.10.17-v7l+ -C /lib/modules/5.10.17-v7l+/build M=/var/lib/dkms/hid-xpadneo/v0.9-68-gfef8e4c/build/src VERSION=v0.9-68-gfef8e4c modules....
cleaning build area...

DKMS: build completed.

hid-xpadneo.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.10.17-v7l+/kernel/drivers/hid/

Running the post_install script:
Disabling ERTM permanently (requires reboot)...
HINT: If you want to prevent this in the future, run 'ln -snf /dev/null /etc/modprobe.d/99-xpadneo-bluetooth.conf'.
Disabling ERTM instantly...
Installing modalias database...
Installing udev rules...
Reloading udev...

depmod...

Warning: Unable to find an initial ram disk that I know how to handle.
Will not try to make an initrd.

DKMS: install completed.

dmseg after plugin in the controller:

[   82.736530] input: Xbox Wireless Controller 4416226D773F as /devices/virtual/misc/uhid/0005:045E:0B13.0001/input/input0
[   82.737030] hid-generic 0005:045E:0B13.0001: input,hidraw0: BLUETOOTH HID v5.05 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[   82.920504] hid_xpadneo: loading out-of-tree module taints kernel.
[   82.921205] hid_xpadneo: unknown parameter 'disable_ff' ignored
[   82.921438] loaded hid-xpadneo v0.9-68-gfef8e4c
[   82.921528] xpadneo 0005:045E:0B13.0001: pretending XB1S Windows wireless mode (changed PID from 0x0B13 to 0x02E0)
[   82.921540] xpadneo 0005:045E:0B13.0001: working around wrong SDL2 mappings (changed version from 0x00000505 to 0x00000903)
[   82.921554] xpadneo 0005:045E:0B13.0001: report descriptor size: 283 bytes
[   82.921564] xpadneo 0005:045E:0B13.0001: fixing up Rx axis
[   82.921574] xpadneo 0005:045E:0B13.0001: fixing up Ry axis
[   82.921584] xpadneo 0005:045E:0B13.0001: fixing up Z axis
[   82.921593] xpadneo 0005:045E:0B13.0001: fixing up Rz axis
[   82.921603] xpadneo 0005:045E:0B13.0001: fixing up button mapping
[   82.922672] xpadneo 0005:045E:0B13.0001: gamepad detected
[   82.922684] xpadneo 0005:045E:0B13.0001: enabling compliance with Linux Gamepad Specification
[   82.922859] input: Xbox Wireless Controller 4416226D773F as /devices/virtual/misc/uhid/0005:045E:0B13.0001/input/input1
[   82.923167] xpadneo 0005:045E:0B13.0001: input,hidraw0: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller 4416226D773F] on dc:a6:32:e2:03:fe
[   82.923295] input: Xbox Wireless Controller 4416226D773F Consumer Control as /devices/virtual/misc/uhid/0005:045E:0B13.0001/input/input2
[   82.927856] xpadneo 0005:045E:0B13.0001: consumer control added
[   82.927877] xpadneo 0005:045E:0B13.0001: controller quirks: 0x00000050
[   82.927890] xpadneo xpadneo_welcome_rumble start
[   83.918207] xpadneo xpadneo_welcome_rumble took 990ms
[   83.918248] xpadneo 0005:045E:0B13.0001: Xbox Wireless Controller 4416226D773F [44:16:22:6d:77:3f] connected

evtest now shows two devices: /dev/input/event0: Xbox Wireless Controller 4416226D773F /dev/input/event1: Xbox Wireless Controller 4416226D773F Consumer Control

The first does the same that I have described before and does nothing when pressing the Xbox or Share buttons. The second one only responds to these those buttons: Share button -> KEY_RECORD Xbox button -> KEY_MODE

When testing on Steam Link the controller still shows up as Xbox One S Controller and the mappings are wrong. I manually changed the permissions for the hidraw and it worked correctly after that. I checked /etc/udev/rules.d/60-xpadneo.rules and I can confirm that your changes are there.

kakra commented 3 years ago

Instead of cloning, you can add my repo to the main xpadneo repo: git remote add kakra https://github.com/kakra/xpadneo. I'd recommend going that route to stick to the version tags of the main repo. Then fetch updates: git remote update, then you can checkout the branch.

It's good that you're seeing two devices now, and both send the keys they are supposed to see.

But I'm not sure how to fix the permission issue. Could you create a udev log with udevadm monitor, then connect the controller? It should shed some light on which rules are run, and which sets the permissions.

AlexandreLaborde commented 3 years ago

Instead of cloning, you can add my repo to the main xpadneo repo: git remote add kakra https://github.com/kakra/xpadneo. I'd recommend going that route to stick to the version tags of the main repo. Then fetch updates: git remote update, then you can checkout the branch.

Do I need to uninstall, fecth updates , install or can I then just run update.sh and it will pull from your remote?

udevadm monitor log:

UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL[2859.301206] add      /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:64 (bluetooth)
UDEV  [2859.311580] add      /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:64 (bluetooth)
KERNEL[2859.407757] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006 (hid)
KERNEL[2859.409158] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input14 (input)
KERNEL[2859.409503] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input14/event0 (input)
KERNEL[2859.409743] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input14/js0 (input)
KERNEL[2859.409969] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/hidraw/hidraw0 (hidraw)
KERNEL[2859.410149] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input15 (input)
UDEV  [2859.410439] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006 (hid)
UDEV  [2859.415688] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/hidraw/hidraw0 (hidraw)
KERNEL[2859.418327] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input15/event1 (input)
UDEV  [2859.430752] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input15 (input)
UDEV  [2859.435016] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input14 (input)
KERNEL[2860.408637] bind     /devices/virtual/misc/uhid/0005:045E:0B13.0006 (hid)
UDEV  [2860.511693] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input14/js0 (input)
UDEV  [2860.601785] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input15/event1 (input)
UDEV  [2860.761102] add      /devices/virtual/misc/uhid/0005:045E:0B13.0006/input/input14/event0 (input)
UDEV  [2860.762593] bind     /devices/virtual/misc/uhid/0005:045E:0B13.0006 (hid)
kakra commented 3 years ago

Oh sorry, my fault, use udevadm monitor -p instead. And maybe post it as a file attachment, it gets pretty long.

AlexandreLaborde commented 3 years ago

No problem ๐Ÿ˜‰

udevadmmonitor.txt

kakra commented 3 years ago

The hidraw device is added by uhid not by xpadneo:

UDEV  [3168.237451] add      /devices/virtual/misc/uhid/0005:045E:0B13.0007/hidraw/hidraw0 (hidraw)
ACTION=add
DEVPATH=/devices/virtual/misc/uhid/0005:045E:0B13.0007/hidraw/hidraw0
SUBSYSTEM=hidraw
DEVNAME=/dev/hidraw0
SEQNUM=1785
USEC_INITIALIZED=3168237059
MAJOR=244
MINOR=0

Steam Input adds virtual input devices via uhid, so what you're seeing is not our hidraw device. Actually, it looks like xpadneo even doesn't add a hidraw device on your system. Could you try logging again without any Steam components running?

AlexandreLaborde commented 3 years ago

Steam Link was not running before... Anyway I uninstalled it and rebooted the Pi. udevadmmonitor_nosteamlink.txt

kakra commented 3 years ago

There's still some uhid driver stealing the device from xpadneo:

UDEV  [36.876782] unbind   /devices/virtual/misc/uhid/0005:045E:0B13.0001 (hid)
ACTION=unbind
DEVPATH=/devices/virtual/misc/uhid/0005:045E:0B13.0001
SUBSYSTEM=hid
HID_ID=0005:0000045E:00000B13
HID_NAME=Xbox Wireless Controller 4416226D773F
HID_PHYS=dc:a6:32:e2:03:fe
HID_UNIQ=44:16:22:6d:77:3f
SEQNUM=1639
USEC_INITIALIZED=36876630
DRIVER=xpadneo

Do you have other user-space drivers running which can grab Bluetooth devices and expose via user input driver? It doesn't look like devices don't come directly from the kernel Bluetooth driver. Usually it would look something like this, as you can see, the path sits directly on PCI -> USB -> Bluetooth while for you it's just a virtual uhid device:

KERNEL[102031.660560] add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.7/2-1.2.7.2/2-1.2.7.2:1.0/bluetooth/hci0/hci0:72/0005:045E:02FD.0018 (hid)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.7/2-1.2.7.2/2-1.2.7.2:1.0/bluetooth/hci0/hci0:72/0005:045E:02FD.0018
SUBSYSTEM=hid
HID_ID=0005:0000045E:000002FD
HID_NAME=Xbox Wireless Controller
HID_PHYS=00:1a:7d:da:71:15
HID_UNIQ=c8:3f:26:a9:2d:6c
MODALIAS=hid:b0005g0000v0000045Ep000002FD
SEQNUM=32658

OTOH, yours is a BLE device, it may be handled differently.

kakra commented 3 years ago

OTOH, yours is a BLE device, it may be handled differently.

Ah okay here's some pointer in the right direction: https://blueprints.launchpad.net/lpc/+spec/lpc2012-ref-bluetooth-uhid

So, BLE devices work differently: The data stream is de-multiplexed in user space and then HID data is injected back into the kernel via uhid. Interesting. They may do something similar for the classic Bluetooth HID profiles in the future.

kakra commented 3 years ago

Could you try this change in the udev rule file instead:

...
#FIXME(issue-291) Work around Steamlink not properly detecting the mappings
ACTION=="add|change", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*|0005:045E:0B05.*", SUBSYSTEM=="hidraw", MODE:="0000"
AlexandreLaborde commented 3 years ago

Replaced that line in the file and rebooted the Pi. Still not working.

I am sorry I can really help troubleshooting this, I am no driver/bluetooth expert so I am a bit lost. Are you trying to have the hidraw permissions to change automatically ?

udevadmmonitor_newfix.txt

kakra commented 3 years ago

Yes, but I suppose I have to get one of those controllers first. It's my next kofi goal...

AlexandreLaborde commented 3 years ago

@kakra No problem. You helped a lot and at least I can change the permissions manually for now. ๐Ÿ™‡โ€โ™‚๏ธ

I decided to run an extra command that I thought might give you some extra insights.

udevadm info --attribute-walk /dev/hidraw0

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/virtual/misc/uhid/0005:045E:0B13.0008/hidraw/hidraw0':
    KERNEL=="hidraw0"
    SUBSYSTEM=="hidraw"
    DRIVER==""

  looking at parent device '/devices/virtual/misc/uhid/0005:045E:0B13.0008':
    KERNELS=="0005:045E:0B13.0008"
    SUBSYSTEMS=="hid"
    DRIVERS=="xpadneo"
    ATTRS{country}=="00"

  looking at parent device '/devices/virtual/misc/uhid':
    KERNELS=="uhid"
    SUBSYSTEMS=="misc"
    DRIVERS==""
AlexandreLaborde commented 3 years ago

Your kofi is on it's way ๐Ÿ˜‰ In the meantime, let me know if you want me to test more stuff. Thanks for all the help once again.

kakra commented 3 years ago

Good find!

This should be picked up by the udev rule:

  looking at device '/devices/virtual/misc/uhid/0005:045E:0B13.0008/hidraw/hidraw0':
    KERNEL=="hidraw0"
    SUBSYSTEM=="hidraw"
    DRIVER==""

Hmm, okay, maybe we should use KERNELS because KERNEL matches only this device while KERNELS also matches parent devices (and the hidraw doesn't have this kernel identifier):

#FIXME(issue-291) Work around Steamlink not properly detecting the mappings
ACTION=="add|change", KERNELS=="0005:045E:02FD.*|0005:045E:02E0.*|0005:045E:0B05.*", SUBSYSTEM=="hidraw", MODE:="0000"

Please retry. If it works, I wonder why the other variant works for me but this may be the difference between BLE and classical Bluetooth HID. We should be looking at the other input devices generated by xpadneo, too, with this command. You can get them from the dmesg output, then comparing that with /dev/input/by-path to match it up with a symlink that points to the final device.

kakra commented 3 years ago

It may even work with a simple rule using this by matching against the parent driver:

#FIXME(issue-291) Work around Steamlink not properly detecting the mappings
ACTION=="add|change", DRIVERS=="xpadneo", SUBSYSTEM=="hidraw", MODE:="0000"
kakra commented 3 years ago

BTW: After changing a rule, you can use udevadm control -R to reload the rules, this eliminates the need to reboot. Then either reconnect the controller, or run udevadm trigger /dev/HIDRAW-DEVICE.

AlexandreLaborde commented 3 years ago

We should be looking at the other input devices generated by xpadneo, too, with this command. You can get them from the dmesg output, then comparing that with /dev/input/by-path to match it up with a symlink that points to the final device.

Not exactly what to do regarding this bit...

I checked /dev/input/ and contains 3 items. event0, event1 and js0.

Results of testing ACTION=="add|change", KERNELS=="0005:045E:02FD.*|0005:045E:02E0.*|0005:045E:0B05.*", SUBSYSTEM=="hidraw", MODE:="0000" on the attachments.

This fix did not cause the permissions to change. SteamLink still recognizes the wrong controller.

js0.txt event1.txt event0.txt dmesg1.txt

kakra commented 3 years ago

Not exactly what to do regarding this bit...

NP, looks like you attached just one input device anyways, no need to find which is what. ;-)

This fix did not cause the permissions to change. SteamLink still recognizes the wrong controller.

Looks like I need to test with real hardware. If you want to debug a little more, you can add RUN+="echo debugtest" to a rule line, and it should show up in the system log or dmesg. This way you'd know if a rule matched.

AlexandreLaborde commented 3 years ago

Changing the rule to ACTION=="add|change", DRIVERS=="xpadneo", SUBSYSTEM=="hidraw", MODE:="0000" produced the same results.

Regarding the debug prints do you mean something like this ACTION=="add|change", DRIVERS=="xpadneo", SUBSYSTEM=="hidraw", MODE:="0000", RUN+="echo rule3" ?

I did that to all 3 rules present in /etc/udev/rules.d/60-xpadneo.rules and looking at the syslog they all appear to be called. Interestingly, the first rule causes some issues. ( line 88 )

syslog.txt

kakra commented 3 years ago

May 24 12:28:34 raspberrypi systemd-udevd[970]: Process 'echo rule3' failed with exit code 1.

Okay, looks like you need to pass the full path to echo. Run which echo and replace the command with the path.

May 24 12:28:33 raspberrypi systemd-udevd[972]: 0005:045E:0B13.0001: Failed to open ATTR{/sys/devices/virtual/misc/uhid/0005:045E:0B13.0001/[drivers/hid:xpadneo]bind} for writing: No such file or directory

You can safely ignore that if xpadneo gets automatically bound to the controller. It is there to re-bind the controller to xpadneo if another driver already bound to that device. It works by some systemd magic where writing to [drivers/hid:xpadneo] would look the module up in /sys/bus/hid/drivers/xpadneo and write to the bind file. It's a work-around for older kernels, current kernels seem to auto-bind to specialized HID drivers. It goes away once the module is loaded. That's because the sysfs path doesn't exist before the xpadneo is loaded. You can see that the kernel binds to hid-generic first (one line above), this rule unbinds the driver, then xpadneo gets loaded through the modalias rules, finally binding to the device.

It may be possible that MODE:= gets forced before our rule because you're using an older mechanism for input permissions (usually, group input is no longer used, input device nodes should belong to root, and the systemd session manager uses ACLs to assign permissions depending on which user has the screen). In this case, it may be worth trying RUN+="/usr/bin/chmod a-rw %k (or maybe /dev/%k, I'm not sure). But I won't be able to ship this with xpadneo because I don't know where chmod is installed.

kakra commented 3 years ago

Ordered a nice pulse red controller: https://www.amazon.de/dp/B08SRMPBRF?psc=1&smid=A3JWKAKR8XB7XF&ref_=chk_typ_imgToDp

Unfortunately, the order switched to "not currently available" after ordering it, so we may have to wait some time.

AlexandreLaborde commented 3 years ago

Changed the last rule to ACTION=="add|change", DRIVERS=="xpadneo", SUBSYSTEM=="hidraw", MODE:="0000", RUN+="/usr/bin/chmod a-rw /dev/%k" and that did the trick!!

That controller looks awesome๐ŸŽฎ! I have the boring black one, it was on sale ๐Ÿ˜… In the MSFT store is like 2โ‚ฌ more expensive but maybe they have it in stock. https://www.microsoft.com/de-de/p/xbox-wireless-controller/8XN59CRBSQGZ/18CP

kakra commented 3 years ago

Closed in favor of queued #292

Andrew-Fahmy commented 2 years ago

I am still having this same issue. The buttons are mapped wrong until I manually remove the r/w group permissions from the hidraw device. I have the udev that was merged installed (/lib/udev/rules.d/50-xpadneo-fixup-steamlink.rules) but it doesn't seem to be working when I connect my controller. (also I am on x86_64)

kakra commented 2 years ago

This is probably the same issue as #303, there are actually some bad interactions with uaccess rules of some distributions. Please follow up on that issue.