emilyst / hid-nx-dkms

Alternative Linux kernel HID driver for Nintendo Switch controllers
GNU General Public License v2.0
40 stars 6 forks source link

Bluetooth Pairing Issues #6

Open Leaguesman opened 1 year ago

Leaguesman commented 1 year ago

Hi,

First of all, this driver is much appreciated, as I was previously using a really janky workaround for my N64 NSO controller with the Steam input driver which had odd button mapping and control stick range issues.

However, I'm having some issues with bluetooth pairing. I can pair the controller and connect the first time with no issues. However, any subsequent connection attempts will not work. I need to completely unpair and re-pair the controller for it to work again. I have a hunch that it's not correctly terminating the connection when turning off the controller, as each time I do this process and reconnect, the controller gets the next player input (i.e. on first attempt the player one LED lights up on the controller, on second attempt the player two LED lights up, etc.)

Any thoughts as to why this might be happening? I'm on Manjaro Linux and installed using DPKG as per the instructions, ran modprobe hid-nx, etc. I know bluetooth receivers are notoriously troublesome from device to device, so I'm not convinced my motherboard's bluetooth (which I'm using) is any good.

I'm also not getting rumble in Retroarch, though I am getting it in fftest, so I'm pretty sure I'm just using the wrong Retroarch input/controller driver.

Thanks for any help you can provide.

emilyst commented 1 year ago

Hi,

First of all, this driver is much appreciated, as I was previously using a really janky workaround for my N64 NSO controller with the Steam input driver which had odd button mapping and control stick range issues.

I'm so glad this module helped you. It makes my day. :)

However, I'm having some issues with bluetooth pairing. I can pair the controller and connect the first time with no issues. However, any subsequent connection attempts will not work. I need to completely unpair and re-pair the controller for it to work again.

I haven't encountered this issue. I wanted to see if I could reproduce, but I'm having a hard time getting Bluetooth working properly on my system at the moment. (Unrelated to this.)

Do you get any interesting output from the kernel when you disconnect and attempt to reconnect? (For example, with journalctl -b -e -k.)

I have a hunch that it's not correctly terminating the connection when turning off the controller, as each time I do this process and reconnect, the controller gets the next player input (i.e. on first attempt the player one LED lights up on the controller, on second attempt the player two LED lights up, etc.)

I understand why you would think that, but the LED behavior is something I inherited from the mainline kernel module. It doesn't properly keep track of connections and instead merely increments the number until it wraps back to 1. It is something I've meant to fix, but which has not been a huge priority. The Sony driver probably does what I want, so I could probably copy that sometime.

It's still true there may be some issue when disconnecting and reconnecting in my driver, but the LEDs aren't an indicator of it.

Any thoughts as to why this might be happening? I'm on Manjaro Linux and installed using DPKG as per the instructions, ran modprobe hid-nx, etc. I know bluetooth receivers are notoriously troublesome from device to device, so I'm not convinced my motherboard's bluetooth (which I'm using) is any good.

I am honestly not sure what is causing this. The fact is that little of the behavior within the driver module actually handles Bluetooth stuff. The kernel subsystems for Bluetooth or USB all just sort of forward things to the HID layer, where this driver picks up and attempts to handle it. (There's some Bluetooth specific stuff, but not a lot.)

For purposes of diagnosing, it would be interesting if you could find any interesting output in the system journal.

I would also be interested in knowing if a different Switch controller (like the Switch Pro controller, or a Joy-Con, if you have any handy) exhibit the issue here, or if it's specific to the N64 controller. If the latter, we know the issue is probably either with the controller (unlikely) or my driver (more likely). If the former, it's some issue in your PC hardware or the kernel.

I'm also not getting rumble in Retroarch, though I am getting it in fftest, so I'm pretty sure I'm just using the wrong Retroarch input/controller driver.

Oof, yeah, this is probably an issue with the indirection through the Steam layer, since Steam doesn't really know about my driver. When there's rumble, it has to come from the RetroArch core (which one are you using, by the way?), through to the RetroArch virtual device, to the core input driver, to SDL, to Steam, then to the kernel driver layer. It's a lot of hurdles, and I wouldn't be shocked if the rumble information is getting lost somewhere along the way.

If you want to test this out, you can try switching RetroArch from using the sdl input core to something like udev. It'll require you to reconfigure the controller, but then you can test it without Steam being in the way.

Thanks for any help you can provide.

Thanks again for this useful report. If you can get the additional information or try out some more testing, I would appreciate it. This is unfortunately part of using an "experimental" driver—sometimes you have to experiment. Thanks for bearing with me.

SuperSamus commented 1 year ago

I have a hunch that it's not correctly terminating the connection when turning off the controller, as each time I do this process and reconnect, the controller gets the next player input (i.e. on first attempt the player one LED lights up on the controller, on second attempt the player two LED lights up, etc.)

It's this unrelated issue: https://github.com/DanielOgorchock/linux/issues/41

Leaguesman commented 1 year ago

OK, so when pairing the controller for the first time and connecting successfully, I get this in the system journal:

kernel: Bluetooth: HIDP (Human Interface Emulation) ver 1.2 kernel: Bluetooth: HIDP socket layer initialized kernel: nx 0005:057E:2019.0009: unknown main item tag 0x0 kernel: nx 0005:057E:2019.0009: hidraw8: BLUETOOTH HID v80.01 Gamepad [N64 Controller] on 70:c9:4e:84:0b:4a kernel: nx 0005:057E:2019.0009: controller MAC = 20:0B:CF:17:9D:0C kernel: nx 0005:057E:2019.0009: using factory cal for left stick kernel: nx 0005:057E:2019.0009: using factory cal for right stick kernel: nx 0005:057E:2019.0009: Failed to read left stick cal, using defaults; e=-22 kernel: nx 0005:057E:2019.0009: Failed to read right stick cal, using defaults; e=-22 kernel: input: N64 Controller as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:1/0005:057E:2019.0009/input/input27

After disconnecting and trying to reconnect I get nothing additional in the journal.

On the controller itself, trying to reconnect just shows the LEDs oscillating while it tries to connect, eventually timing out and stopping. On the PC I can see the controller showing as connected in the Bluetooth UI while the LED's are oscillating, then after it times out it shows again as disconnected. So the PC is seeing it while it's trying to reconnect, but the controller is not confirming the connection?

I just tried my Pro Controller as well, which exhibits the same behaviour. I have other controllers that connect via Bluetooth (Xbox, 8BitDo) all of which work fine. Is there some quirk of Nintendo's Bluetooth implementation that my receiver doesn't like I wonder...

Unfortunately I don't have another Bluetooth receiver to test with.

emilyst commented 1 year ago

OK, so when pairing the controller for the first time and connecting successfully, I get this in the system journal:

[...]

That all looks normal to me (except I'm mildly surprised that hid-nx is failing to read the factory calibration, but that's neither here nor there).

After disconnecting and trying to reconnect I get nothing additional in the journal.

Okay, very strange. Not even a disconnection? That could be relevant to the problem.

On the controller itself, trying to reconnect just shows the LEDs oscillating while it tries to connect, eventually timing out and stopping. On the PC I can see the controller showing as connected in the Bluetooth UI while the LED's are oscillating, then after it times out it shows again as disconnected. So the PC is seeing it while it's trying to reconnect, but the controller is not confirming the connection?

Interesting. Puzzling! I am really gonna have to try to reproduce this myself.

I just tried my Pro Controller as well, which exhibits the same behaviour. I have other controllers that connect via Bluetooth (Xbox, 8BitDo) all of which work fine. Is there some quirk of Nintendo's Bluetooth implementation that my receiver doesn't like I wonder...

It's good to know this isn't specific to the N64 controller. My hid-nx module is beginning to look more suspect. Does this issue go away if you try with the mainline hid-nintendo module? (If it's a pain to test this, don't worry about it.)

Unfortunately I don't have another Bluetooth receiver to test with.

I doubt it's your hardware at this point.

In any case, I'll report back if I'm able (or unable) to reproduce this issue. Thanks again for all this information.

emilyst commented 1 year ago

I was finally able to reproduce this myself (so far, with three different controllers). So from here I can diagnose for myself what's going on. This is definitely a valid problem, so I appreciate you helping me with it.

emilyst commented 1 year ago

Honestly, I'm stumped.

I'm finding that I can't connect any of the Switch controllers at all anymore. Even if I entirely uninstall hid-nx and use hid-nintendo. I've tried three different kernel versions, and I get the same result.

I'm going to have to take a step back and think this all over because something is badly borked, and I can't even tell what. Sorry about this.

emilyst commented 1 year ago

Well, neat, now I can't reproduce the problem at all, with either driver. No idea why.

I reinstalled hid-nx and blocked hid-nintendo from loading, restarted, removed the devices in bluetoothctl, re-paired, and they seem fine now?

There is one behavior that still persists, but it was in the mainline hid-nintendo module as well. When you disconnect a controller via Bluetooth, the driver seems to get hung up for about 20 seconds. During this time, reconnections seem to fail. Afterwards, things are okay.

Bluetooth's haunted.

All I can suggest for now is:

Leaguesman commented 1 year ago

Alright, I've now blacklisted the mainline module and removed and reinstalled the hid-nx module, followed by a reboot. Double checked the right things are loaded and unloaded.

Still seeing the same issue unfortunately. I tried waiting for a long period after disconnecting the controller, I tried disconnecting the controller both from the PC's Bluetooth GUI as well as by physically turning the controller off, and in all cases it fails to reconnect.

Given you've been able to both reproduce and not reproduce the issue, it might be outside your control. I recall some similar issues the devs of the the Xbox controller driver xow were having, where you had to tinker with all sorts of low level Bluetooth settings to get it to connect at all.

At any rate, I've now got rumble working across my gaming applications, and I guess Bluetooth will work as long as I re-pair it each time, which honestly is good enough for me. Thanks again for putting the work in.

emilyst commented 1 year ago

Sorry I couldn’t give you a meaningful resolution to this. I’ll leave the issue open in case you or someone else has more information in the future.

tmarki commented 3 months ago

I'm running into this same issue with the latest version or Retropie on a Raspberry Pi 4 and a USB BT adapter, using both a Pro controller and a Switch SNES controller. So sad!

The kernel is 5.10 which is below supported one, so I'm thinking maybe I should try setting up Retroarch on a newer version of Raspberry OS?

nfp0 commented 3 months ago

@tmarki Pairing issues are unlikely to be related to this driver. Kernel 5.10 is indeed a very old kernel, and kernels since 6.8 already include the features of this driver, so you don't even need to install this. I would give it a try with an up-to-date kernel.

tmarki commented 3 months ago

The problem is that the latest RetroPie images are based on Debian 10, which comes with 5.10.

I tried to install it on the newer ones (Debian 11 and 12 based Raspberry OS), but those have omxplayer removed so it's not possible to install RetroPie... They have kernel 6.x and with this driver the controllers work properly, I can disconnect and reconnect them as expected.

I'll keep experimenting and post here again in case I find something that fixes my problem. I just want to use the Switch SNES controller with my Raspberry Pi 4 based RetroPie... 😢

nfp0 commented 3 months ago

I don't think you need this driver to use the SNES controller, as it's detected as a standard HID device. It won't be set to high-report mode, but it should work just fine regardless. That's how I used it before installing this driver.

tmarki commented 3 months ago

I tried it out, and seems like you're right. The reason I thought it was not working is because the lights don't stop going back and forth, but I randomly pressed a button and it seems to be fully functional.

However, the reconnect problem still persist, I have to re-pair every time to be able to use it, which means it's unrelated to this module, so this issue could be closed, at least from my perspective.

Thanks for the replies!

Update: Looks like I found the issue - it was the external bluetooth adapter I was using, the pi's internal adapter works fine and the controller can reconnect after reboot! It still does the light flashing but it plays fine.

nfp0 commented 3 months ago

However, the reconnect problem still persist, I have to re-pair every time to be able to use it, which means it's unrelated to this module, so this issue could be closed, at least from my perspective.

@tmarki To solve this on my Nintendo controllers I had to set FastConnectable = true on /etc/bluetooth/main.conf