Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Controller requires pairing to connect #95

Open
poperigby opened this issue Jun 24, 2020 · 33 comments
Open

Controller requires pairing to connect #95

poperigby opened this issue Jun 24, 2020 · 33 comments
Labels
bug Something isn't working

Comments

@poperigby
Copy link

So every time I turn on my controller, it shows the blinky light forever unless I pair it by holding down the XBOX button and the button on the dongle at the same time.

@x4mers
Copy link

x4mers commented Jun 24, 2020

So every time I turn on my controller, it shows the blinky light forever unless I pair it by holding down the XBOX button and the button on the dongle at the same time.

Had the computer just been turned on too, or had it remained on since the last time the controller was used?

Once synced, can you turn off the controller and turn it right back on to a working state, or it fails again even then?

I'm asking, because I'm also having an issue of the controller not syncing on initial use, on many days. However, I turn that computer off every night, so it's always a clean boot when it fails.

I haven't tried the pairing to fix it, I usually just reboot (rarely twice) and it syncs back up on it's own. I've also found that if, while it's happening, I open a terminal and run xow it will fail because the service is already running. It does seem to give the version running under the service a 'kick' though, and the controller will immediately sync to the service.

@poperigby
Copy link
Author

Had the computer just been turned on too, or had it remained on since the last time the controller was used?

Yeah

@ddragic
Copy link

ddragic commented Jun 24, 2020

This sometimes happens to me as well, but it's rare, definitely not every time I power on the controller.

There is probably no need to reboot since this is a userspace driver, power cycling the dongle so the firmware is reloaded should be enough. In my case to fix it I usually just stop the xow service unplug/plug in the dongle and start the service. I don't pair the controller again.

@medusalix
Copy link
Owner

medusalix commented Jun 24, 2020

A USB packet capture with Wireshark when the problem happens might give some insights. I've never had this issue on my side (unless I've reset the pairing by using the controller over USB). It's either some kind of firmware/reset issue or an edge case that requires a fix on xow's side.

@medusalix medusalix added the bug Something isn't working label Jun 24, 2020
@poperigby
Copy link
Author

Is there a guide for doing USB packet capturing for xow?

@m3nowak
Copy link

m3nowak commented Jun 25, 2020

@medusalix

unless I've reset the pairing by using the controller over USB

This turned out to be issue in my case. I suppose not many people are aware of it. Could you add that information in the documentation?

@medusalix
Copy link
Owner

This turned out to be issue in my case. I suppose not many people are aware of it. Could you add that information in the documentation?

Yes, I'll make sure to add that to the README. It applies to bluetooth connections too, they also reset the pairing.

Is there a guide for doing USB packet capturing for xow?

It's pretty simple. You run sudo modprobe usbmon and use Wireshark to record the traffic on the dongle's USB port. There's some helpful advice in this thread.

@medusalix
Copy link
Owner

Oh and I forgot to mention that it might also have something to do with USB power saving. The logs might give additional clues in that case.

@x4mers
Copy link

x4mers commented Jul 11, 2020

I'm also having an issue of the controller not syncing on initial use, on many days.

I installed wireshark, and figured out how to use it, just waiting for it to happen so I could post logs.

It's been 18 days now and it has not failed a single time. It was failing 3 or 4 days a week before I made that post. I don't get it. I'm still running the initial 0.5 release, so that hasn't changed. I wondered if maybe Manjaro pushed a libusb update, but I don't see it listed in recent updates history.

Back when it was failing, journalctl showed normal logs up to dongle initialized (wouldn't log anything after that line). At this point I'm assuming it was some system update that fixed the problem on my end.

The only fault I've had during this period, was a single controller drop while rumbling in Rocket League. The light on the controller stayed on but was unresponsive. Held the button to turn off, and then right back on to continue playing. I'm assuming this is related the pending pull request.

@x4mers
Copy link

x4mers commented Jul 15, 2020

At this point I'm assuming it was some system update that fixed the problem on my end.

Spoke too soon. 22 days after my initial comment, the controller finally failed to connect to the dongle, when I powered the PC on today. For wireshark, I pressed the power button on the controller and let it time out trying to connect, before stopping the capture.

My motherboard manual list two of the USB ports as being 1.1/2.0. Those two are occupied with my APC UPS and the XBox dongle.

Jornalctl_xow.txt
dmesg.txt
Wireshark.pcapng.zip

@medusalix
Copy link
Owner

I couldn't spot any connection attempts from the controller in that Wireshark dump. In fact, the dongle didn't send any packets at all. I don't know whats going on...

@x4mers
Copy link

x4mers commented Aug 18, 2020

@medusalix I spent quite a while last Friday afternoon, trying to get any kind of useful log out of the failure to connect. While the controller failed to connect to the dongle at least 20 times that afternoon, logging was all useless. Journalctl always shows a successful dongle init, up to the dongle initialized message, and then dead after that with no LED on.

I noticed that on the boots that were failures, systemd total boot time was listed as 5secs longer than successful boots. I assumed this was from the service type set to idle. I changed it to exec, and then boot time was the same regardless of success or failure. Service file is back to default now.

With the dongle unresponsive, a capture is useless, so I thought I needed to do a usbpcap during boot to capture the traffic while the dongle is being initialized. I made a service file with ExecStartPre=/sbin/modprobe usbmon & ExecStart=/sbin/tcpdump -i usbmon1 -s 0 -w /home/brad/Desktop/usbtrace.pcap. Problem is, with this running, the controller connects successfully every time. I did shutdown/bootup MANY times and success every time. I then used systemctl to stop and disable my usbtrace.service and in the next 5 shutdown/bootup, the controller failed to connect on boots 2 and 5. Re-enabled the service and went 15 successful boots in a row.

Is it possible something is happening too fast during init, and the handing of the traffic is slowed enough by the filter/capture to make it work successfully? Are you running with usbmon on by default? Maybe that's why it's not reproducible on your end?

usbtrace.service.zip
SuccessOnBoot.pcap.zip

@Merrit
Copy link

Merrit commented Oct 15, 2020

I noticed when I reboot the computer and the controller won't connect, all I have to do is press the button on the dongle and they immediately connect again; is the dongle maybe just asleep / not powered at boot?

@kakra
Copy link
Contributor

kakra commented Oct 16, 2020

I noticed that on the boots that were failures, systemd total boot time was listed as 5secs longer than successful boots. I assumed this was from the service type set to idle. I changed it to exec, and then boot time was the same regardless of success or failure. Service file is back to default now.

The service shouldn't be set to Type=idle anyways because that's probably misusing it as a synchronization point. Instead it needs to Requires= and After= its dependencies properly. idle just considers it for starting as early as possible but puts it at the end of the transaction queue. On fast booting systems that may be reached before the actual dependencies have finished starting. If you put another service into the queue, that may just have delayed the xow service enough. But well: idle isn't a synchronization point. The service should probably not be enabled statically but be triggered by a udev rule. This should be possible by adding ENV{SYSTEMD_WANTS}="xow.service" to a udev rule that matches the dongle vendor/product ID.

See also: #116

@kakra
Copy link
Contributor

kakra commented Oct 16, 2020

Also, Type=idle adds a 5s timeout for the service when it will start regardless of the transaction queue. Since the service has no other dependencies, "idle" will queue it right after system init and start it with a 5s delay from there unless the boot transaction reaches its end before these 5s (and thus the list of idle services). If xow really depends on something in the system being ready, idle is wrong: It needs proper ordering or needs to be triggered by udev. At least this explains the 5s difference you were observing.

@Merrit
Copy link

Merrit commented Feb 2, 2021

It there a way I can maybe work around this issue for the time being?

@kakra
Copy link
Contributor

kakra commented Feb 2, 2021

Latest git version may fix it. Did you try?

@Merrit
Copy link

Merrit commented Feb 3, 2021

Ah, I did not. Will give it a try, thanks! ❤️

@Merrit
Copy link

Merrit commented Feb 3, 2021

Installed latest git version, still have to press dongle button after reboot.

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

Does "dongle button" means "connect button on the dongle" or "connect button on the controller"? Do you need to press just that one button, or both?

@Merrit
Copy link

Merrit commented Feb 4, 2021

After reboot, I:

  • hold the 'Guide' button on the controller to turn it on
  • controller blinks and never connects, then shuts itself off
  • if I check systemctl status xow.service it says it is running and has initialized
  • press the only button on the dongle, it lights up and the controller can immediately connect (never pressing the small sync button on the controller)

If there is any troubleshooting I can do on my end or logs I can gather, etc I am happy to do so ❤️

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

So maybe xow should initialize the dongle in paring mode? You could try adding "ExecPost=kill -SIGUSR1 $MAINPID" to the system service to see if it helps.

For a start, just try sending SIGUSR to it as described in the readme. If this works instead of pushing the button, the ExecPost line may work. But then that's probably rather a work around than a proper solution.

@Merrit
Copy link

Merrit commented Feb 4, 2021

sudo systemctl kill -s SIGUSR1 xow works.

  • Turn on controller, just blinks.
  • sudo systemctl kill -s SIGUSR1 xow => blinking stops, instantly connects.

Editing the service file didn't seem to make a difference.

[Unit]
Description=Xbox One Wireless Dongle Driver

[Service]
Type=idle
ExecStart=/usr/local/bin/xow
ExecPost=kill -SIGUSR1 $MAINPID
DynamicUser=true
Restart=on-success

# Uncomment the following line to enable compatibility mode
# Environment="XOW_COMPATIBILITY=1"

[Install]
WantedBy=multi-user.target

Also tried ExecPost=kill -s -SIGUSR1 $MAINPID in case the -s would make a difference, but no luck there.

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

Oh sorry, my fault: It's ExecStartPost...

After this, check systemctl status xow to see if the ExecStartPost line was actually executed (it would show Process: ... ExecStartPost=... (... status=0/success). It may not work if xow doesn't fork (after all, it's Type=idle).

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

BTW: Maybe you could try if it breaks for you because of Type=idle... Try to compile and install #116

@Merrit
Copy link

Merrit commented Feb 4, 2021

With ExecStartPost it doesn't start up at all.

❯ systemctl status xow.service
● xow.service - Xbox One Wireless Dongle Driver
     Loaded: loaded (/etc/systemd/system/xow.service; enabled; vendor preset: enabled)
     Active: failed (Result: signal) since Thu 2021-02-04 14:03:01 EST; 14s ago
    Process: 1219 ExecStart=/usr/local/bin/xow (code=killed, signal=USR1)
    Process: 1220 ExecStartPost=/usr/bin/kill -SIGUSR1 $MAINPID (code=exited, status=0/SUCCESS)
   Main PID: 1219 (code=killed, signal=USR1)

Feb 04 14:02:58 SHODAN systemd[1]: Started Xbox One Wireless Dongle Driver.
Feb 04 14:03:01 SHODAN xow[1219]: 2021-02-04 14:03:01 INFO  - xow v0.5-24-g9d5a11b ©Severin v. W.
Feb 04 14:03:01 SHODAN systemd[1]: xow.service: Main process exited, code=killed, status=10/USR1
Feb 04 14:03:01 SHODAN systemd[1]: xow.service: Failed with result 'signal'.

I tried installing the build from that pull request, on sudo systemctl enable xow it gives an error (unsure if this is relevant at all):

❯ sudo systemctl enable xow
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template
units). This means they are not meant to be enabled using systemctl.
 
Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's
  .wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
  a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
  D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some
  instance name specified.

On reboot with this pull request version it is same as before:

❯ systemctl status xow.service
● xow.service - Xbox One Wireless Dongle Driver
     Loaded: loaded (/etc/systemd/system/xow.service; static)
     Active: active (running) since Thu 2021-02-04 14:15:44 EST; 28s ago
   Main PID: 1206 (xow)
      Tasks: 4 (limit: 38325)
     Memory: 1.8M
     CGroup: /system.slice/xow.service
             └─1206 /usr/local/bin/xow

Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 36, power: 42
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 40, power: 42
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 44, power: 41
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 48, power: 41
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 149, power: 37
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 153, power: 37
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 157, power: 35
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 161, power: 35
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 DEBUG - Channel 165, power: 35
Feb 04 14:15:45 SHODAN xow[1206]: 2021-02-04 14:15:45 INFO  - Dongle initialized

Controller doesn't connect after reboot but once again sudo systemctl kill -s SIGUSR1 xow fires it up immediately.

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

Yeah, with the pull request, you no longer enable the service, it will start when udev detects the dongle (you should be able to watch this using journalctl -f, then plugging the dongle in). You should remove any dangling symlink from /etc/systemd/system/multi-user.target.wants that links to xow.

I guess your dongle is plugged in at boot time already, so actually not much will change (except that it should load the firmware more reliably).

I think the SIGUSR1 simply gets send too early if the process just dies. Maybe you could try ExecStartPost=sleep 10; kill -SIGUSR1 $MAINPID but I don't know if you could just slam commands together with ; in ExecStartPost.

@Merrit
Copy link

Merrit commented Feb 4, 2021

I tried with the sleep

❯ systemctl status xow.service
● xow.service - Xbox One Wireless Dongle Driver
     Loaded: loaded (/etc/systemd/system/xow.service; static)
     Active: failed (Result: exit-code) since Thu 2021-02-04 14:53:51 EST; 16s ago
    Process: 1269 ExecStart=/usr/local/bin/xow (code=killed, signal=TERM)
    Process: 1270 ExecStartPost=/usr/bin/sleep 10; kill -SIGUSR1 $MAINPID (code=exited, status=1/FAILURE)
   Main PID: 1269 (code=killed, signal=TERM)

Feb 04 14:53:51 SHODAN systemd[1]: Starting Xbox One Wireless Dongle Driver...
Feb 04 14:53:51 SHODAN sleep[1270]: /usr/bin/sleep: invalid option -- 'S'
Feb 04 14:53:51 SHODAN sleep[1270]: Try '/usr/bin/sleep --help' for more information.
Feb 04 14:53:51 SHODAN systemd[1]: xow.service: Control process exited, code=exited, status=1/FAILURE
Feb 04 14:53:51 SHODAN systemd[1]: xow.service: Failed with result 'exit-code'.
Feb 04 14:53:51 SHODAN systemd[1]: Failed to start Xbox One Wireless Dongle Driver.

Also don't see anything related to xow in /etc/systemd/system/multi-user.target.wants/

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

So I'm a bit out of ideas now. You could make it work by making xow start a systemd.timer which in turn triggers the signal then. But this is only getting more and more hacky. Also, forcing xow into pairing mode to connect an already paired controller doesn't seem like the right idea. It properly needs to detect some additional bits of the protocol to detect that a controller wants to connect. I know nothing to little about the protocol details, so @medusalix may have a better clue.

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

I tried with the sleep

Yeah, look at the output: It didn't detect ; as a command separator, so sleep thinks the SIGUSR1 parameter belongs to it. It may work putting these on separate lines of ExecStartPost (first sleep, then kill). But it's a hack, tho it may work for you until a proper fix landed.

Also, more than 10 seconds may be needed - I don't know how long the firmware upload and initialization takes, I think it sometimes took 30 seconds for me.

@kakra
Copy link
Contributor

kakra commented Feb 4, 2021

BTW: You may want to use sudo systemctl edit xow.service to add the additional lines to a separate drop-in file so they don't get overridden on update. systemctl cat xow.service will show you the full picture then. Just put the ExecStartPost lines in a separate files (systemctl edit xow.service), you just need repeat the section name in the drop-in:

[Service]
ExecStartPost=sleep 10
ExecStartPost=kill -SIGUSR1 $MAINPID

@Merrit
Copy link

Merrit commented Feb 5, 2021

So, I have reinstalled my OS for unrelated reasons. (Kubuntu => Manjaro)

I installed xow through the AUR and.. so far cannot reproduce the error anymore. Which is especially odd since I first had this issue on Manjaro, several months ago. That said, this issue was never consistent - sometimes it would work after reboot, sometimes not. Maybe this is just a lucky streak, but I guess I will update here if it happens again..

@jnlsn
Copy link

jnlsn commented Apr 19, 2021

FWIW I seem to be having the same issue on GamerOS 😕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

8 participants