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.87k stars 110 forks source link

xpadneo causes GuliKit King Kong 2 controller to vibrate constantly #391

Closed Termuellinator closed 1 year ago

Termuellinator commented 1 year ago

Version of xpadneo

xpadneo-dkms 0.9.5-2 from AUR

Controller Model

Connection mode

Installed Software

Protocol Information

Please help us identify at which layer the problem can be found if you want to report mapping errors or if the controller fails to be detected:

Please describe how it is failing below in the next sections.

Severity / Impact

Describe the Bug

I bought a new GuliKit KingKong 2 controller but was very confused when it wouldn't stop vibrating while connected via Bluetooth. Connected via USB everything was fine. Besides the vibration issue, all buttons seemed to work just fine.

After some poking around i noticed it seemed to use the hid_xpadneo module - after uninstalling xpadneo, it uses hid_microsoft and everything works as expected.

So i guess it would be a solution to prevent xpadneos udev to catch that controller? At least i would think that would be easier than figuring out why a constant vibration is sent to the controler ;)

Edit: i must correct myself - vibration seems to NOT work with bluetooth and hid_microsoft, so maybe fixing the sustained vibration would be the better way if it's doable :D

System Information

# uname -a
Linux Wunderland 6.0.5-zen1-1-zen #1 ZEN SMP PREEMPT_DYNAMIC Wed, 26 Oct 2022 15:26:02 +0000 x86_64 GNU/Linux

Controller and Bluetooth Information

➜ ~ bluetoothctl info
Device 98:B6:EA:E8:9C:CA (public) Name: GuliKit Controller XW Alias: GuliKit Controller XW Class: 0x00000508 Icon: input-gaming Paired: yes Bonded: yes Trusted: yes Blocked: no Connected: yes WakeAllowed: yes LegacyPairing: no UUID: Human Interface Device... (00001124-0000-1000-8000-00805f9b34fb) UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb) Modalias: usb:v045Ep02E0d0903

Let me know if any other outputs are relevant for this

Additional Context

kakra commented 1 year ago

Can you try loading the module with the following parameters:

rmmod hid-xpadneo
modprobe hid-xpadneo quirks=98:B6:EA:E8:9C:CA+7

Then connect the controller and see if it still rumbles continuously. Verify in dmesg that the quirks parameter was applied to your controller. If the problem isn't fixed with this, the rumble implementation isn't working exactly like the genuine firmware, and we need to deploy a fixup similar to some 8BitDo models. This seems to be a common problem with Switch-compatible controllers.

Also, let me know if this controller supports rumble in the triggers. While the problem exists, you should feel a rumble in each trigger if that is supported (do not confuse it with the full controller rumble).

If the quirks parameter does not help, try uninstalling your QMK tools and try again, so we can rule out hidraw incompatibilities.

Termuellinator commented 1 year ago

Thanks for the answer! modprobing xpadneo with the quirks argument doesn't change things - altough i can't see an indication it is applied in dmesg:

[ 6977.717365] usbcore: deregistering interface driver xpad
[ 7007.030357] loaded hid-xpadneo 0.9.5
[ 7019.392388] xpadneo 0005:045E:02E0.0021: buggy firmware detected, please upgrade to the latest version
[ 7019.392394] xpadneo 0005:045E:02E0.0021: pretending XB1S Windows wireless mode (changed PID from 0x02E0 to 0x028E)
[ 7019.392396] xpadneo 0005:045E:02E0.0021: working around wrong SDL2 mappings (changed version from 0x00000903 to 0x00001130)
[ 7019.392399] xpadneo 0005:045E:02E0.0021: report descriptor size: 307 bytes
[ 7019.392401] xpadneo 0005:045E:02E0.0021: fixing up report descriptor size
[ 7019.392554] xpadneo 0005:045E:02E0.0021: battery detected
[ 7019.392556] xpadneo 0005:045E:02E0.0021: enabling compliance with Linux Gamepad Specification
[ 7019.392602] input: GuliKit Controller XW as /devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-9/1-9:1.0/bluetooth/hci0/hci0:256/0005:045E:02E0.0021/input/input69
[ 7019.392756] xpadneo 0005:045E:02E0.0021: input,hidraw18: BLUETOOTH HID v11.30 Gamepad [GuliKit Controller XW] on fc:77:74:86:8c:aa
[ 7020.337991] input: Microsoft X-Box 360 pad 0 as /devices/virtual/input/input70
[ 7020.383468] xpadneo 0005:045E:02E0.0021: GuliKit Controller XW [98:b6:ea:e8:9c:ca] connected

Trying the MAC in both upper and lowercase yields the same result. Uninstalling VIA didn't change things, i have no QMK-software installed otherwise

I assume the 'buggy firmware' message is some check against xbox firmware? Installing the newest firmware from the website was the first thing i tried at least. I don' think it has rumble in the triggers, i didn't find any indication on the website or elsewhere, too. Disassembly-Videos also show no sign of something like that.

Edit: Ok, now it's getting weird - even after a reboot, i don't have any vibrations on my xbox controller now besides the buzz after connecting O_o Edit2: Well, it seems the quirk was applied and persisted after reboot - rmmod and modprobe xpadneo gave me back the vibration on the xbox controller :)

kakra commented 1 year ago

Thanks for the answer! modprobing xpadneo with the quirks argument doesn't change things - altough i can't see an indication it is applied in dmesg:

Yeah, it has to show a message about quirks, otherwise the flags won't be active. Not sure what's wrong. Could you double-check with modinfo hid-xpadneo that you specified the parameters correctly - and that you actually successfully unloaded the module first?

According to your dmesg, it looks like it was unloaded.

Trying the MAC in both upper and lowercase yields the same result. Uninstalling VIA didn't change things, i have no QMK-software installed otherwise

You checked the QMK checkbox, so I was recommending this. It ships some udev rules that fiddle around with hidraw permissions of all devices although I think it was fixed in newer versions.

I assume the 'buggy firmware' message is some check against xbox firmware?

Yes, as a clone, it probably identifies with an old version number (v9.03 to be exact, which is the original version that was buggy on Linux). Your report descriptor size indicates that the buggy behavior is probably not there.

Installing the newest firmware from the website was the first thing i tried at least. I don' think it has rumble in the triggers, i didn't find any indication on the website or elsewhere, too. Disassembly-Videos also show no sign of something like that.

So the quirks flag for no trigger rumble would be correct.

It should log something like this:

# modprobe hid-xpadneo quirks=44:16:22:bd:48:69+7
[176215.215491] xpadneo 0005:045E:0B13.001C: quirks added: 44:16:22:bd:48:69 flags 0x00000007
[176215.215492] xpadneo 0005:045E:0B13.001C: controller quirks: 0x00000057

Maybe the + operator isn't supported in your version - I don't remember exactly when I added it. Try : instead (it means you'd need to add the flags manually if there existed some by default). Character casing doesn't matter.

kakra commented 1 year ago

Edit2: Well, it seems the quirk was applied and persisted after reboot - rmmod and modprobe xpadneo gave me back the vibration on the xbox controller :)

No, it doesn't persist after reboot. There's probably some other random thing going on. It only persists if you put it into /etc/modprobe.d.

But if we figure out that the quirk flags will actually and reliably fix your rumble, I'll hard code your MAC OUI into the source code. I just want to know the minimum flags required for your model first.

Termuellinator commented 1 year ago

modprobe hid-xpadneo quirks=98:b6:ea:e8:9c:ca:7 worked indeed to get rid of the constant vibration! And the vibration on the xbox controller still works with that - so probably really some strange thing.

But now i notice the GuliKit controller isn't picked up in some games that work fine (besides no vibration) with hid_microsoft - both with and without the qurik. In other games it works fine besides no vibration. I can't really see a pattern though - tried some random native and proton games and both categories have working and non-working games. Awful lot of trouble for a controller that is mostly praised as working out of the box (besides switch/gyro mode)...

Edit: curiously, switch mode works properly (including vibration) if i rmmod hid_xpadneo - so it seems, despite it automatically loading hid_nintendo when connecting in switch mode, xpadneo is somehow still interfering?

➜ ~ bluetoothctl info                                                                                                                                                                                                                                             
Device 98:B6:E9:E8:9C:CA (public)
        Name: Pro Controller
        Alias: Pro Controller
        Class: 0x00002508
        Icon: input-gaming
        Paired: yes
        Bonded: yes
        Trusted: yes
        Blocked: no
        Connected: yes
        WakeAllowed: yes
        LegacyPairing: no
        UUID: Human Interface Device... (00001124-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v057Ep2009d0001

Thats in switchmode. I'm confused, i would have assumed one device would only access one module - or is that a false assumption?

The fact that beamNG drive causes the controller (in switch mode) to constantly vibrate as long as the window is in focus probably has nothing to do with this - but just in case i'm mentioning it as that doesn't happen with the xbox controller.

kakra commented 1 year ago

Thats in switchmode. I'm confused, i would have assumed one device would only access one module - or is that a false assumption?

xpadneo won't interfere, it doesn't handle device ID usb:v057Ep2009d0001.

For the games not detecting the controller, check the dmesg output after connecting the controller for the hidraw device number (changes on every connect) and run getfacl /dev/hidrawXX with XX being the number. What does it log?

modprobe hid-xpadneo quirks=98:b6:ea:e8:9c:ca:7 worked indeed to get rid of the constant vibration!

Fine, so it is just a syntax problem of the older module version. I should really push forward releasing v0.10 soonish.

Could you also try :2, :3, :5 and check how the initial vibration changes and how games behave per each setting? I think :2 returns to the buggy behavior but the other two quirks flags may change things.

And the vibration on the xbox controller still works with that - so probably really some strange thing.

If you are comparing to the original xbox controller:

  1. It doesn't match the MAC address so the quirks won't be applied.
  2. It will work correctly even with those flags applied except that trigger rumble may not work. We are just doing more work in the driver to compensate for a missing feature of clone controllers.

I can't really see a pattern though - tried some random native and proton games and both categories have working and non-working games.

The pattern may be usage of SDL. If you enable/disable Steam Input on a per game basis, SDL will be involved or won't. It also depends on the Proton version, older versions used SDL, modern versions use hidraw. Using hidraw exposes incompatible behavior on software not parsing the HID descriptor, see #286. We work around this by pretending a different device PID but this doesn't work for hidraw (the kernel crashes when I change the hidraw PID). Revoking access permissions from the hidraw device works around that for now, unfortunately software like QMK or OpenRGB unconditionally allowed world read/write for all hidraw devices, breaking our work-around. Also, when hidraw is used, xpadneo cannot prevent the firmware crash during rumble, see https://github.com/libsdl-org/SDL/issues/6435.

hid-microsoft will work because assumptions of SDL and Proton are built around the behavior of that driver. But it doesn't prevent the rumble crash of genuine Xbox controller firmware. Your model should not be affected by that. Also, if you don't need the advanced features of xpadneo, hid-microsoft is all you need.

Termuellinator commented 1 year ago

Thanks for the extensive reply!

For the games not detecting the controller, check the dmesg output after connecting the controller for the hidraw device number (changes on every connect) and run getfacl /dev/hidrawXX with XX being the number. What does it log?

getfacl: Entferne führende '/' von absoluten Pfadnamen
# file: dev/hidraw18
# owner: root
# group: root
user::---
group::---
other::---

Interestingly, switching the controller from X-Input to Android-Mode doesn't seem to cause the problem that some games don't recognize it. the getfacl-Output is the same for both, both use xpadneo, only difference i can see is in bluetoothctl info the x-Input-Mode reports Name and Alias as GuliKit Controller XW while the Android-Mode reports Xbox Wireless Controller

Could you also try :2, :3, :5 and check how the initial vibration changes and how games behave per each setting? I think :2 returns to the buggy behavior but the other two quirks flags may change things.

All 4 different quirk flags prevent the constant vibration, from short testing in carrion and antimicroX, all controls work as intended. So :2 does not return the buggy behaviour. When trying :3 the first time i had two vibrations after switching on, but i can't reproduce that anymore - so maybe that was just that it needed a second to connect to bluetooth and that was the second vibration.

The pattern may be usage of SDL.

That might be it - but as Android mode seems to work fine i'll keep that in mind if it occurs again.

hid-microsoft will work because assumptions of SDL and Proton are built around the behavior of that driver. But it doesn't prevent the rumble crash of genuine Xbox controller firmware. Your model should not be affected by that. Also, if you don't need the advanced features of xpadneo, hid-microsoft is all you need.

with hid-microsoft my xbox series gamepad doesn't work properly unfortunately.

So besides the Quirk-Workaround, the only thing that still is an issue is that both in android- and in x-input mode as well as both with hid-microsoft and hid-xpadneo, the rumble ingame doesn't work. :| For games that pick up the controller in switch-mode, rumble works fine there, so it's not a hardware issue.

Do you have any suggestion on how to troubleshoot that issue? I'm not sure if that's a driver or an implementation issue - but if it's the latter it'd probably be best to have some background info to relay to their support in order to hope for an updated firmware.

Wiedzmin89 commented 1 year ago

I have GuliKit King Kong 2 Pro and same issue modprobe hid-xpadneo quirks=98:B6:EA:48:64:25:7 also worked for me.

Termuellinator commented 1 year ago

@Wiedzmin89 Out of curiosity: do you get rumble in games with the Pro?

kakra commented 1 year ago

@Termuellinator When checking out the source code from git, there's a directory misc/examples/c_hidraw. Go to that directory and run make (you probably need to install the ncurses development package of your distribution).

This will build a program hidraw to run:

./hidraw /dev/hidrawXX

with XX being your current hidraw number.

This program will allow to run raw HID rumble commands with easy adjustments of parameters. You can check a few different settings and see how well your controller behaves. If you can use that to rumble the controllers, games should work and the issue is somewhere else but not in the driver itself.

Keys 1-4 set the bits for which rumble motors to program, q/a/ws/e/d/r/f set the individual rumble strength per motor, h/j sets sustained parameter (how long the motor should rumble), k/l sets the release time (how long the motor should pause) and u/i sets how often the motor should repeat sustain and release after the initial rumble (thus 0 = 1 loop). Pressing enter will send the command to the controller.

If your controller is Xbox compliant, a motor without the appropriate programming bit set should not rumble. If it does instead, the quirk flags are needed.

Also, if your controller does not honor the sustain/release/loop parameters, quirk flags are also needed (it will continue to rumble until you send a command with zero strenght). I've seen multiple reports for Switch-compatible controllers that don't honor these flags.

In any case: If this program does work, games should work, too, because this program does what the driver actually does at the low level. Thus, if games don't rumble, the rumble command doesn't even get through to the xpadneo driver.

There's also a race condition found in SDL which may prevent SDL detecting rumble support. A workaround is using ff_connect_notify=0 as a module parameter (just append it after the quirks parameter). It will eliminate the delay before the driver is fully initialized and may allow SDL to properly detect rumble support but the controller won't rumble on connect.

PS: You don't need to load the xpadneo driver for this program to work because it works at the lowest programming level possible.

Wiedzmin89 commented 1 year ago

@Termuellinator I get rumble only with cable connection. I'll make another issue about that.

kakra commented 1 year ago

I get rumble only with cable connection. I'll make another issue about that.

Using cable doesn't use xpadneo, so it's the same issue probably.

Wiedzmin89 commented 1 year ago

For me, It also no vibration for xbox gamepads:

I was tested with Rocket League steam proton experimental

Wiedzmin89 commented 1 year ago

@kakra I was tested ./hidraw method you send: ./hidraw /dev/hidraw10 Enabled continious strong vibro on GuliKit KingKong 2 Pro and can't stop it (LTR and RTR) ./hidraw /dev/hidraw11 Unhealty weak and short vibro on Xbox Series gamepad, it stops without send 0

kakra commented 1 year ago

LTR and RTR are the left and right triggers, please test the strong and weak main motors, too.

Wiedzmin89 commented 1 year ago

@kakra Gamepad have only two physical motors and in hidraw it's 3 (LTR) and 4 (RTR). 1 and 2 no makes anything. image

kakra commented 1 year ago

Ok wow, then the implementation of this controller is completely messed up. The values of LTR/RTR seem to be swapped with strong/weak. I think we'll need to implement a new quirk flag for that.

Thanks for the photo.

For the Xbox controller what you see as unhealthy vibration may just be due to sending a very short rumble command only.

Termuellinator commented 1 year ago

I can confirm that the strong/weak rumble motors are apparently registered as the trigger motors - that explains why there is no rumble when loading with quirks deactivating the trigger rumble. I'm just confused why this works on windows then - shouldn't there be problems with rumble too? They don't have their own windows-drivers as far as i can see.

I'd like to send a bug report to the manufacturer in hopes for a corrected firmware. But if they switch that around to have the motors assigned correctly, i would expect to have this issue on windows then - or am i missing something?

kakra commented 1 year ago

Maybe there's something in the HID descriptor which we do not read correctly yet.

Can you dump me original HID descriptor? In this case, "original" means we need the HID descriptor before xpadneo modifies it. Thus, please uninstall or disable xpadneo, then connect the controller via Bluetooth, then check dmesg for the hidraw number and then do (with XX being your hidraw number):

# cd /sys/class/hidraw/hidrawXX/device
# xxd -c20 -g1 report_descriptor

Post the output of the xxd command, and the related part of your dmesg output (about detecting the device and attaching to a kernel driver like hid-microsoft or hid-generic).

For this, please only use the controller in an operational mode that is also detected by xpadneo (which is probably Android or X-Input mode, if both are supported, share both xxd outputs).

We have descriptions of known report descriptors and report formats in the docs folder. If you like, you can prepare something in a similar format.

Hint: We are probably looking for differences in report ID 3:

0x85, 0x03,        //   Report ID (3)
0xA1, 0x02,        //   Collection (Logical)
0x09, 0x97,        //     Usage (0x97)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x04,        //     Report Size (4)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x00,        //     Logical Maximum (0)
0x75, 0x04,        //     Report Size (4)
0x95, 0x01,        //     Report Count (1)
0x91, 0x03,        //     Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x09, 0x70,        //     Usage (0x70)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x64,        //     Logical Maximum (100)
0x75, 0x08,        //     Report Size (8)
0x95, 0x04,        //     Report Count (4)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x09, 0x50,        //     Usage (0x50)
0x66, 0x01, 0x10,  //     Unit (System: SI Linear, Time: Seconds)
0x55, 0x0E,        //     Unit Exponent (-2)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x09, 0xA7,        //     Usage (0xA7)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x65, 0x00,        //     Unit (None)
0x55, 0x00,        //     Unit Exponent (0)
0x09, 0x7C,        //     Usage (0x7C)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
Termuellinator commented 1 year ago

It seems the xxd output is the same for both xinput and android mode. See gulikit_kingkong2_android.md It seems Report ID (3) is missing completely? When connected via xpadneo, the last 00 (0x00, // Unknown (bTag: 0x00, bType: 0x00)) is missing everything else stays the same.

Dmesg for xinput mode:

[ 9928.367715] microsoft 0005:045E:02E0.001F: unknown main item tag 0x0
[ 9928.367850] input: GuliKit Controller XW as /devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-9/1-9:1.0/bluetooth/hci0/hci0:512/0005:045E:02E0.001F/input/input53
[ 9928.367974] microsoft 0005:045E:02E0.001F: input,hidraw18: BLUETOOTH HID v9.03 Gamepad [GuliKit Controller XW] on fc:77:74:86:8c:aa

dmesg for android mode:

[10651.057078] microsoft 0005:045E:02E0.0024: unknown main item tag 0x0
[10651.057209] input: Xbox Wireless Controller as /devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-9/1-9:1.0/bluetooth/hci0/hci0:256/0005:045E:02E0.0024/input/input60
[10651.057344] microsoft 0005:045E:02E0.0024: input,hidraw18: BLUETOOTH HID v9.03 Gamepad [Xbox Wireless Controller] on fc:77:74:86:8c:aa
kakra commented 1 year ago

When connected via xpadneo, the last 00 (0x00, // Unknown (bTag: 0x00, bType: 0x00)) is missing everything else stays the same.

Yes, this is expected: xpadneo actively strips the bogus NULL byte from the end if it exists to prevent a warning from the Linux kernel.

It seems Report ID (3) is missing completely?

Interesting... This could explain some things... It still seems to respond to report ID 3, tho, even if doing that seemingly wrong.

kakra commented 1 year ago

Interesting... This could explain some things... It still seems to respond to report ID 3, tho, even if doing that seemingly wrong.

Okay, I think you did something wrong while removing the xxd extra columns. Decoding the report descriptor actually looks like this:

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x05,        // Usage (Game Pad)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x15, 0x00,        //     Logical Minimum (0)
0x27, 0xFF, 0xFF, 0x00, 0x00,  //     Logical Maximum (65534)
0x95, 0x02,        //     Report Count (2)
0x75, 0x10,        //     Report Size (16)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x09, 0x33,        //     Usage (Rx)
0x09, 0x34,        //     Usage (Ry)
0x15, 0x00,        //     Logical Minimum (0)
0x27, 0xFF, 0xFF, 0x00, 0x00,  //     Logical Maximum (65534)
0x95, 0x02,        //     Report Count (2)
0x75, 0x10,        //     Report Size (16)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x32,        //   Usage (Z)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x03,  //   Logical Maximum (1023)
0x95, 0x01,        //   Report Count (1)
0x75, 0x0A,        //   Report Size (10)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x00,        //   Logical Maximum (0)
0x75, 0x06,        //   Report Size (6)
0x95, 0x01,        //   Report Count (1)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x35,        //   Usage (Rz)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x03,  //   Logical Maximum (1023)
0x95, 0x01,        //   Report Count (1)
0x75, 0x0A,        //   Report Size (10)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x00,        //   Logical Maximum (0)
0x75, 0x06,        //   Report Size (6)
0x95, 0x01,        //   Report Count (1)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x39,        //   Usage (Hat switch)
0x15, 0x01,        //   Logical Minimum (1)
0x25, 0x08,        //   Logical Maximum (8)
0x35, 0x00,        //   Physical Minimum (0)
0x46, 0x3B, 0x01,  //   Physical Maximum (315)
0x66, 0x14, 0x00,  //   Unit (System: English Rotation, Length: Centimeter)
0x75, 0x04,        //   Report Size (4)
0x95, 0x01,        //   Report Count (1)
0x81, 0x42,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x75, 0x04,        //   Report Size (4)
0x95, 0x01,        //   Report Count (1)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x00,        //   Logical Maximum (0)
0x35, 0x00,        //   Physical Minimum (0)
0x45, 0x00,        //   Physical Maximum (0)
0x65, 0x00,        //   Unit (None)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x09,        //   Usage Page (Button)
0x19, 0x01,        //   Usage Minimum (0x01)
0x29, 0x0A,        //   Usage Maximum (0x0A)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x0A,        //   Report Count (10)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x00,        //   Logical Maximum (0)
0x75, 0x06,        //   Report Size (6)
0x95, 0x01,        //   Report Count (1)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x80,        //   Usage (Sys Control)
0x85, 0x02,        //   Report ID (2)
0xA1, 0x00,        //   Collection (Physical)
0x09, 0x85,        //     Usage (Sys Main Menu)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x95, 0x01,        //     Report Count (1)
0x75, 0x01,        //     Report Size (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x00,        //     Logical Maximum (0)
0x75, 0x07,        //     Report Size (7)
0x95, 0x01,        //     Report Count (1)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0x05, 0x0F,        //   Usage Page (PID Page)
0x09, 0x21,        //   Usage (0x21)
0x85, 0x03,        //   Report ID (3)
0xA1, 0x02,        //   Collection (Logical)
0x09, 0x97,        //     Usage (0x97)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x04,        //     Report Size (4)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x00,        //     Logical Maximum (0)
0x75, 0x04,        //     Report Size (4)
0x95, 0x01,        //     Report Count (1)
0x91, 0x03,        //     Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x09, 0x70,        //     Usage (0x70)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x64,        //     Logical Maximum (100)
0x75, 0x08,        //     Report Size (8)
0x95, 0x04,        //     Report Count (4)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x09, 0x50,        //     Usage (0x50)
0x66, 0x01, 0x10,  //     Unit (System: SI Linear, Time: Seconds)
0x55, 0x0E,        //     Unit Exponent (-2)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x09, 0xA7,        //     Usage (0xA7)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x65, 0x00,        //     Unit (None)
0x55, 0x00,        //     Unit Exponent (0)
0x09, 0x7C,        //     Usage (0x7C)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0x85, 0x04,        //   Report ID (4)
0x05, 0x06,        //   Usage Page (Generic Dev Ctrls)
0x09, 0x20,        //   Usage (Battery Strength)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x01,        //   Report Count (1)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection
0x00,              // Unknown (bTag: 0x00, bType: 0x00)

// 307 bytes

// best guess: USB HID Report Descriptor
Termuellinator commented 1 year ago

Okay, I think you did something wrong while removing the xxd extra columns. Decoding the report descriptor actually looks like this:

I didn't remove any columns. But maybe the website has issues with the xxd output? I couldn't find any flags for xxd that would give the pure (but still formated) hex-output like in the other examples, but as usbdescreqparser still gave an output i figured it was fine - sorry for the confusion!

kakra commented 1 year ago

It seems the xxd output is the same for both xinput and android mode. [...] Dmesg for xinput mode: [...] dmesg for android mode: [...]

I'm not sure where the difference even is then between those two modes. Does it affect how the hidraw program works? If not, I suspect this is purely switching some Bluetooth driver quirks - and Android mode would be the preferred mode for the Linux Bluetooth driver stack.

kakra commented 1 year ago

But maybe the website has issues with the xxd output?

It's actually not meant to receive xxd output directly, it can only parse the hex dump between the address column and the ascii column, so I remove that in my editor before putting it into the decoder. The Linux kernel also has a decoder if you are running a debug kernel. Because not every one does and it requires root, the bug reporting wizard doesn't depend on that.

Termuellinator commented 1 year ago

Does it affect how the hidraw program works?

Doesn't seem like it from a short test. LTR reacts to WEA and RTR reacts to STR Like i wrote earlier, android mode seems to be picked up by more/most games, so i'd agree that that would probably be the mode to target.

FormBurden commented 1 year ago

Hi all, I too use the GuiliKit King Kong 2 Controller, and I can confirm that the rmmod hid-xpadneo and modprobe hid-xpadneo quirks=98:B6:EA:xx:xx:xx:7 works correctly. And I do not get vibration when connecting to PC.

Wiedzmin89 commented 1 year ago

Have same descriptor for xinput mode:

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 0a 15 00 25 01 75 01 95 0a 81 02 15 00 25 00  ....)...%.u.......%.
000000a0: 75 06 95 01 81 03 05 01 09 80 85 02 a1 00 09 85 15 00 25 01  u.................%.
000000b4: 95 01 75 01 81 02 15 00 25 00 75 07 95 01 81 03 c0 05 0f 09  ..u.....%.u.........
000000c8: 21 85 03 a1 02 09 97 15 00 25 01 75 04 95 01 91 02 15 00 25  !........%.u.......%
000000dc: 00 75 04 95 01 91 03 09 70 15 00 25 64 75 08 95 04 91 02 09  .u......p..%du......
000000f0: 50 66 01 10 55 0e 15 00 26 ff 00 75 08 95 01 91 02 09 a7 15  Pf..U...&..u........
00000104: 00 26 ff 00 75 08 95 01 91 02 65 00 55 00 09 7c 15 00 26 ff  .&..u.....e.U..|..&.
00000118: 00 75 08 95 01 91 02 c0 85 04 05 06 09 20 15 00 26 ff 00 75  .u........... ..&..u
0000012c: 08 95 01 81 02 c0 00                                         .......
Kivarnis commented 1 year ago

I can also confirm this rmmod hid-xpadneo and modprobe hid-xpadneo quirks=98:B6:EA:xx:xx:xx:7 works correctly, though not sure if rumble works within games have to test this.

FormBurden commented 1 year ago

I can also confirm this rmmod hid-xpadneo and modprobe hid-xpadneo quirks=98:B6:EA:xx:xx:xx:7 works correctly, though not sure if rumble works within games have to test this.

It should. Even though most of the games I play do not use Rumble, I have played some games with it, and can confirm it works correctly.

Termuellinator commented 1 year ago

I have played some games with it, and can confirm it works correctly.

Are you sure that statement is really true when it's connected via bluetooth and set to either x-input or android mode? The only mode i got rumble out of it is switch-mode.

kakra commented 1 year ago

Thanks to a donation, this controller arrived today for me so I can test it out myself. I'm not sure if the donator is around here writing but send some love by liking this comment.

FormBurden commented 1 year ago

Oh my... excuse my ignorance. I thought it worked. But it's been months since I've experienced it. And what I remember was because it was wired connected to my PC. So vibration works that way. But Bluetooth, apparently not. When it's on X-windows-mode (the controller). I tested two games that I know has vibration, and yeah, it doesn't work. But my Xbox Series X controller I have does work (some games that do, apparently do not, because of the newer drivers or whatever that the Series X controllers have, so games with older controller compatibility, only the Xbox One-type of controllers work, not Series X) with vibration on Bluetooth.

kakra commented 1 year ago

Okay, this controller is special...

The programming mask bits are swapped for triggers and main motors - but at least it reacts to them unlike the 8BitDo controllers which completely ignore those bits. But like the 8BitDo controllers, it ignores the rumble envelope parameters. So we need to add another quirk handler which swaps the masking bits, and everything should work.

I've also taken a quick look into Switch Pro controller mode, and we should be able to support it via xpadneo, so we could get the gyro control working. The general appearance of the HID layout looks similar. But that's a story for a different day.

I've not messed around with the advanced settings and various buttons yet. It's a lot to find out about this controller. But yeah, we can probably get a quick fix for the rumble issue.

PS: Actually, the motor bitmask is reversed compared to genuine Xbox controllers.

FormBurden commented 1 year ago

I find it odd. Because whatever drivers/software that Steam/Valve has for their controllers, they sure need to share it with the community. Because the GuliKit King Kong 2 controller works out of the gate... at least on Steam Deck gaming mode. And even in SD Desktop Mode, things work like a normal Xbox controller. Vibration and all.

Yet, on my Arch Linux Desktop (Main PC), I need this/your software: xpadneo to get the controller to even work with Bluetooth.

kakra commented 1 year ago

Well, yes. Our driver actually makes use of the programming bits. Thus you can send a strong rumble first, and send a weak rumble later. The genuine Xbox controller will rumble those motors independently from each other. SDL and Steam Input do this completely in software, so they simply set all motor masking bits to "ON" which hides the flaw of this controller.

I now also fixed the rumble testing on connect which caused infinite rumble due to a logical flaw in our driver if the controller doesn't support rumble envelope parameters - which the GuliKit actually doesn't.

I also found that this controller has a very flat attack envelope curve for the strong rumble motor: It starts spinning very slowly, both motors seem to be very weak. The result is that very short strong rumbles feel very flat and dull. We cannot change that. This makes the weak motor actually comparably strong for short rumbles. For the GuliKit, we could rather describe the motors as heavy and light but both weak.

So, as you see: This is rather an exercise of how well the implementation is, and not a compatibility thing. Applications using fully software emulated rumble do not care about this, this includes SDL and Steam Input. Software that uses hidraw could leverage those features but will fail for the reversed motor bitmask unless we could intercept sent HID reports (by a quick glance, it looks like we can only intercept received HID reports which we already do to mimic the original Xbox 360 controllers for older games).

Whatever this is useful for, it serves as a documentation for people implementing support in SDL or Steam Input: They can look at our code to learn about the quirks.

kakra commented 1 year ago

they sure need to share it with the community

The Steam deck doesn't depend on kernel drivers for controller support. It just uses hidraw with SDL, adding support for controller models right in Steam Input and Proton's wine fork. So there's nothing to share.

If you use Steam Input, your controller should work just like on Steam Deck if you (a) add hidraw permissions and (b) don't use xpadneo (because we modify the HID reports which Steam Input doesn't expect due to not looking at the HID descriptor).

IOW, Steam Deck uses user-space drivers implemented right their software stack.

kakra commented 1 year ago

@Termuellinator Is it okay if I add a co-authored-by tag to the commit since you put some effort in creating the HID descriptor? It'll show your name and email like in your public repositories here on Github.

Termuellinator commented 1 year ago

Of course, i'd be honored ;) Really interesting how these things interact and how small differences can yield such vastly different results.

kakra commented 1 year ago

@Termuellinator Please test https://github.com/atar-axis/xpadneo/pull/393

FormBurden commented 1 year ago

they sure need to share it with the community

The Steam deck doesn't depend on kernel drivers for controller support. It just uses hidraw with SDL, adding support for controller models right in Steam Input and Proton's wine fork. So there's nothing to share.

If you use Steam Input, your controller should work just like on Steam Deck if you (a) add hidraw permissions and (b) don't use xpadneo (because we modify the HID reports which Steam Input doesn't expect due to not looking at the HID descriptor).

IOW, Steam Deck uses user-space drivers implemented right their software stack.

OH I see. Very interesting. Thanks for all this info. Things I didn't know about.

LucasSymons commented 1 year ago

It starts spinning very slowly, both motors seem to be very weak. The result is that very short strong rumbles feel very flat and dull

I wonder if this is related to their adjustable rumble feature. IIRC You can change the intensity in the controller settings all the way down to basically off.

kakra commented 1 year ago

I wonder if this is related to their adjustable rumble feature

Doesn't look like: I tried all intensities, and the heavy motor always spins up very lazily. The motors are just too weak for the heavy weight. Maybe that's a design decision due to the relatively small battery: I didn't compare the numbers but from the photo above, it looks like the battery is smaller than in the genuine Xbox controllers. The controller design of the main body is also more slim, so a bigger battery won't fit.

I didn't try it with games yet. Only played a round of Cyberpunk with it to see how it feels: While the stick are extremely precise around the center, the sensitivity curve really needs some learning: It's a lot more aggressive than the Xbox controllers. Not sure if I like it. I didn't try the sensitivity settings yet. Also, the aim assist really works like garbage, cannot be compared to the Steam controller. But if we manage to support the controller in Switch mode, we should be able to pass the gyro as separate axes so Steam can make use of it.

Termuellinator commented 1 year ago

@Termuellinator Please test #393

i might just be overlooking something obvious or being completely dumb - but i can't for the love of god get rid of the error

sed: lib/../VERSION kann nicht gelesen werden: Datei oder Verzeichnis nicht gefunden
ERROR: If you install from a git repository, you may need to run
ERROR: sudo git config --global --add safe.directory $PWD
ERROR: to trust this git checkout for the root user.
ERROR: See https://github.com/atar-axis/xpadneo/issues/346

When i look into this or your repo, there is no file VERSION in the /lib folder - so i'm not sure if that's the issue?

kakra commented 1 year ago

Read the line prefixed with ERROR:. It should solve the problem. The version file is created on demand, and exactly that fails.

Termuellinator commented 1 year ago

Of course i did add the (base)directory to safe.directory. Still no luck unfortunately. For the main repo, it works fine - but it fails on your repo/branch.

kakra commented 1 year ago

Ahhh. Please don't clone my repository, instead use git remote add kakra https://github.com/kakra/xpadneo.git to add my repo to the base repo, then run git remote update, then checkout my branch.

My fork doesn't have version tags, and thus no version file can be created.

Termuellinator commented 1 year ago

Ah, gotcha. That works indeed - first time checking out a branch from a PR, so didn't know about remote add - you never stop learning ^^ Unfortunately, the testing is only partially successful.

kakra commented 1 year ago

when testing in the hidraw tool, it's still the case that LTR reacts to WEA and RTR reacts to STR

This is expected: hidraw bypasses the driver. I'm just swapping the bits when software goes through the driver.

in Absolute Drift, it still is not detected.

Is that a native game? This may use SDL, which may use hidraw, and then it bypasses the driver. Otherwise, try disabling Steam Input for that game.

FormBurden commented 1 year ago

Just checked out your #393 commit and can say that the rumble issue has been resolved.