paroj / xpad

Linux Kernel Driver for the Xbox/ Xbox 360/ Xbox One Controllers
820 stars 181 forks source link

xone: Wireless Adapter Support (WiFi) #14

Closed Queuecumber closed 4 years ago

Queuecumber commented 8 years ago

I figured I'd open an issue for this, I have the wireless adapter "for windows 10", I haven't done much debugging with the xpad driver but I figured support for this is one of your goals. I can help debug this and/or provide any information you might need.

wjbuys commented 8 years ago

I also just got one, and would be willing to help with debugging.

In case it's useful, here's a Wireshark dump of the USB traffic when plugging in and removing the adapter.

paroj commented 8 years ago

@wjbuys did you dump running linux? If so dumping using windows 10 where the handshake actually succeeds would be more vaulable..

wjbuys commented 8 years ago

@paroj yep, that was on Linux. I don't have a Windows 10 box, will see if I can coax it out of a VM.

wjbuys commented 8 years ago

I've captured the exchange between the wireless adapter and a Windows 10 VM here. I couldn't actually get it to pair with a controller though.

Queuecumber commented 8 years ago

@wjbuys that's weird, was it giving an error or something?

wjbuys commented 8 years ago

@Queuecumber nope, it just went something like:

This might be a Virtualbox issue (or just me, I can't Windows and I've never used the controller with an actual XBox), so getting a real dump would help a lot.

steverweber commented 8 years ago

mac driver with xbox one support under active dev... might have some good code to share :) https://github.com/360Controller/360Controller/pull/151 https://github.com/360Controller/360Controller/issues/160

Queuecumber commented 8 years ago

Here are links to the USB traffic captured from their issue 160

https://drive.google.com/file/d/0B381VMfcesrlaG5fTjl3WjZuc2c/view https://drive.google.com/file/d/0B381VMfcesrlNWZwRkpoTXJBaDA/view https://drive.google.com/file/d/0B381VMfcesrlRmlKN0tPWGVfdFU/view

mooware commented 8 years ago

So, is anyone working on this? I'd like to help, if I can.

I did a USB capture in Windows 10 with two controllers, but I have no idea how to interpret it: https://dl.dropboxusercontent.com/u/267889/xone.pcap

Almamu commented 8 years ago

I can help implementing this, I do have a Windows 10 box with an XBOX One Wireless adapter + a linux box in which I can test. I just need some more info to start reversing the protocol, does Wireshark detect the wireless dongle as a normal network adapter under Windows 10 (if so, can I just do a capture on it or do I need a special driver or something)?

mooware commented 8 years ago

I used usbpcap with Wireshark.

drejjmit commented 8 years ago

Almamu Yes. Under both W10 and W7 it's detected as a Network adapter.

Almamu commented 8 years ago

@wjbuys Make sure that at least USB 2.0 support is enabled in the VM, I had the same problems until I activated it.

tadly commented 8 years ago

Trying to get that thing work with KVM (using libvirt) and USB passthrough to a win10 guest which (I'm assuming) is due to it not being properly recognized by the host (not sure on that though. I'm new to kvm)

What I'm trying to say is: If there's anything I can help with, I'll do my best to do so.

What I've noticed so far:

  1. Adapter does show up on the windows guest as Network adapter
  2. When booting the guest, I get a device descriptor read/64, error -71

Pairing stick and controller does not work. Same behaviour as for @wjbuys with virtualbox

Queuecumber commented 8 years ago

I think at this point we really need someone who can understand the wireshark dumps. Thanks to the mac folks we actually have a couple of dumps floating around (I think). Not that more dumps wouldn't be extremely useful just that the big missing piece is someone who knows how to implement this. I tried to look at it myself but this isn't exactly my area of expertise

Queuecumber commented 8 years ago

Another set of captures courtesy of the mac people

https://drive.google.com/file/d/0B3-WQPnZBRZhRmlNZjltU1pWTms/view

tadly commented 8 years ago

@Queuecumber ah crap, sorry... wanted to share that thread for a while now and kept forgetting about it :/

http://controllermax.com/forums/showthread.php?t=151076&s=0794035b822a0fbaa8e480cb1f8c8676&p=1014946&viewfull=1#post1014946

That's all I know so far...

ghost commented 8 years ago

From looking at the dumps that have been uploaded, I don't think the protocol is too complicated. They're apparently using standard headers on the packets (at least Wireshark seems to recognize them) and the patterns seem relatively consistent. They're definitely not encrypted, and it wouldn't make sense from the engineer's perspective to make them encrypted.

I'm going to play around with these and see what I can do. It'd be really helpful if anyone could make a more extensive dump and annotate it: start recording, plug in without touching anything and see the traffic it produces just from that initial handshake, then systematically press each button once, waiting a second in between, then upload it along with the order that you hit all the buttons in.

For any other devs reading along, the dumps uploaded so far seem to have a pretty simple pattern:

  1. Adapter polls for device
  2. Controller says it's alive
  3. Adapter requests basic configuration information
  4. Controller says it's a usb 1.1 device that's not powered by the wire and supports remote wakeup
  5. Adapter requests more config information
  6. Controller identifies itself as a proprietary interface -- presumably Microsoft specific -- and lists 8 endpoints that probably map to the buttons
  7. Controller sends extra packet that's not standards compliant but is probably used as part of the configuration
  8. Adapter and controller handshake to confirm they understand each other
  9. Adapter and controller ping back and forth with each other very frequently, with the controller including status information that probably includes buttons currently pressed
paroj commented 8 years ago

please try to keep the discussion here focused on getting the controller to work using the adapter. I have opened a new issue regarding WiFi protocol #25. Will clean up the comments here now.

Queuecumber commented 8 years ago

Just to bring this to everyone's attention: https://github.com/360Controller/360Controller/issues/156#issuecomment-211083411

One of the Mac guys has figured something out, nothing definitive yet though. When he releases his code I'll take a look at how he did it and see what happens

stephen304 commented 8 years ago

Looks like he's been committing his code to his fork, if anybody here wants to start tinkering with it: https://github.com/haiduc32/360Controller/commits/master

haiduc32 commented 8 years ago

also please check my latest comment on the mac thread.

haiduc32 commented 8 years ago

@developers - I managed to crack the most important parts of the protocol to the extent that now I have my xbox one controller sending all input commands through the wireless to my mac. you can find the class that is of interest: https://github.com/haiduc32/360Controller/blob/master/WirelessGamingReceiver/OneWirelessGamingReceiver.cpp you can find all the commands in there. most of it is initializatioin, then pairing (or smth). some messages are in ProcessMessage as they are out of sync. some limited information on the messages mostly from ProcessMessage can be found in here: https://docs.google.com/document/d/1AyrhC3gnVAmZyjlCGeJmPauCopRkLN56NyjHiuj8b14/edit?usp=sharing if anyone is serious about working on that let me know if you need help on the protocol and we can setup a skype chat.

cgutman commented 8 years ago

@haiduc32 the Wireless adapter itself is simply a MediaTek MT7216US NIC. The proprietary part is Microsoft's protocol that runs across it (called Xbox GIP apparently). In Microsoft's stack, they seem to use a stock MediaTek provided NIC driver for the adapter itself and their own protocol driver that sits above it. Microsoft then puts a fairly standard HID stack on top of GIP. There are some quirks needed since the Xbox controllers don't send HID report descriptors (to my knowledge), so one would need to be provided by the OS.

I assume you're driving the whole thing from one driver (the NIC itself and GIP that runs atop it). Maybe it would make your life easier to split out the portion dedicated to the MediaTek NIC and implement the GIP driver separately? That may help even more if the new Bluetooth controller uses the same protocol.

I wrote some thoughts on the best way to structure this code in a thread here: http://thread.gmane.org/gmane.linux.kernel.input/50585

mooware commented 8 years ago

A quick note regarding the new Xbox One S controller with Bluetooth support: It already works with Linux (I'm using it with my Steam Link). I suppose this change was all it took: 1405c6a61dfcc7bb8609242aa44948caefdd6c11. I also had to update the controller firmware (which is done through the "Xbox Accessories" Windows 10 app; no idea if there's a way to do it without Windows).

TimoVerbrugghe commented 7 years ago

@mooware: you mean the Xbox One S Controller works with Linux over Bluetooth or using cable only?

mooware commented 7 years ago

@TimoVerbrugghe: Bluetooth. Only tried it with the Steam Link, don't know about regular Linux distributions. I found this commit which seems to contain the relevant changes in the Linux kernel of the Steam Link: https://github.com/ValveSoftware/steamlink-sdk/commit/d6afa93787217033a0f0f5db5f557b252c36260e

ghost commented 7 years ago

I have gotten a cap file for the xbox one wireless controller and adapter. Includes pairing of the controller as well as a single press of every button. Let me know if there is anything else you guys need, would love to see this up and running!

http://www45.zippyshare.com/v/g5JuszyY/file.html

Toniob commented 7 years ago

@mooware @TimoVerbrugghe Currently, the controller is working with a bluetooth connection under a stock distribution (Debian unstable at last). The pairing is ok but to be able to connect the controller, the following sysfs parameter has to be changed : /sys/module/bluetooth/parameters/disable_ertm (from N to Y). The following command will do the trick : $ echo 1 > /sys/module/bluetooth/parameters/disable_ertm After that, everything is fine, the controller is recognised and works really well (except the vibration which is not working). No issue using a cable connection.

ottk3 commented 7 years ago

@mooware did you use the "Microsoft Wireless Adapter" or another BT connection?

mooware commented 7 years ago

@ottk3 The official wireless adapter discussed in this issue doesn't use Bluetooth, if that's what you meant. I was referring specifically to the new Xbox One S controller, which supports Bluetooth and thus doesn't require the wireless adapter.

TheKrane commented 7 years ago

Any progress here? Would like to help out if I can somehow.

paroj commented 7 years ago

someone needs to figure out which of the USB commands used here are really needed: https://github.com/haiduc32/360Controller/blob/master/WirelessGamingReceiver/OneWirelessGamingReceiver.cpp

a first step would be porting the sequence to this driver and see whether we can receive input too.

Note however that the Bluetooth version already works (reportedly) - so if you just want a working gamepad, you might want to consider one of these.

haiduc32 commented 7 years ago

well.. let me put it this way.. if you skip a step in the initialization faze, the next steps will just return you unexpected values, so the chance of making it smaller is pretty slim. In fact I did skip a quite a few message types (after initialization faze), and it seemed to work. The messages looked like keep-alive, and maybe something to do with keyboard and sound, that were out of scope for me.

alfredkrohmer commented 7 years ago

The wireless adapter is actually just a 5 GHz 802.11 wifi dongle. You can sniff the traffic with airodump-ng. I have done a little "reverse engineering" here: https://github.com/paroj/xpad/issues/25#issuecomment-258642789

The chip inside has another USB vendor and product ID, but I think it should be possible to force-bind the appropriate driver to the device. The rest can be done with a link-layer protocol in kernel space or directly from userspace.

Haapavuo commented 7 years ago

Okay. So now it seems that we have enough information to communicate with the controller since we know the essential parts of the protocol.

Now we just need someone who can make a linux driver (or two drivers) to support the protocol that is used.

zommuter commented 7 years ago

@devkid So does that mean one could also use any wifi dongle instead of the Microsoft one provided the driver is written accordingly?

alfredkrohmer commented 7 years ago

@zommuter Yup, at least with any dongle that supports AP mode at 5 GHz. With the builtin WiFi in my laptop I managed to get it to semi-functional state in which I received input data from the controller, but it was very unstable, probably because I did it by injecting raw frames and the Intel driver doesn't seem to be very happy about that. My new 5 GHz WiFi router will probably arrive in a few days and I hope that I'll be able to implement it there with the nl80211 protocol instead of frame injection.

If someone has enough time, one could try to get this driver working by adding the correct USB product and vendor IDs to the driver code. (It bugged out on my system, but might have been a problem with NetworkManager and didn't have any time to continue working on this.)

zommuter commented 7 years ago

@devkid Impressive 👍 Make me wonder why Microsoft bothered with creating their own adapter instead of a any-WiFi-driver though. Yes, they sell it for money, but I bet the development costs are still non-negligible... I'm looking forward to any development in this direction though.

Haapavuo commented 7 years ago

@zommuter Maybe because of the latency and to get rid of other unnecessary overhead? The protocol should also be similar to the one that Xbox One has. Later on they found out that bluetooth can also work quite well... But bluetooth doesn't support as many devices nor wireless audio.

Haapavuo commented 7 years ago

@zommuter Also, since wifi modules were not originally made for this kind of use, the drivers may not easily bend. And not all wifi modules would work anyway. This is a good innovation though and could be used for smart home controlling etc.

zommuter commented 7 years ago

@Haapavuo Makes sense. Well, hopefully someone manages to write a driver then. Too bad I know next to nothing about hardware programming...

pikim commented 7 years ago

Is anyone still working on this? If it helps I have logged different scenarios of plugging the wireless adapter in and out under Windows 7 (see attachment) and pressing some buttons. ~But I can find no similarities with the sequences in haiduc32's code.~

See the included text file for a brief description of the captured scenarios. VID = 0x045e, PID = 0x02e6.

xbox-one-capture.zip

pikim commented 7 years ago

Meanwhile I started to integrate haiduc32's code in this xpad version. What I don't like so far are the thousand controlIn/controlOut function calls. I'd like to have the necessary data in an array and then I'd just step through this array and process each element. Is someone here that knows how to generate the necessary array data from Wireshark capture files? I could need some help or good advice here.

pikim commented 7 years ago

I created a first version that is prepared for the initialization of the Wireless Adapter here. Up to now it is just a skeleton and not working. This is my first touch with Linux drivers, so maybe I have done all "DONT'S" that are around. Perhaps someone with some experience can have a look at it...

~I was not able to find the cut between initialization and operation yet.~ My captures look different and therefore it seems a bit more complicated.

The new file create-onew-array.sh creates the necessary C file that contains the data structure needed for initialization.

Below there is another capture taken the following way:

long-capt.pcap.zip

This is the base for my implementation so far. I'm trying to get in contact with haiduc32, but I'm not sure whether he's still reading comments about this topic.

Any comments or ideas?

pikim commented 7 years ago

Updated the repository. Now there's also a config file generated from my captures. So everything for doing the first steps is available.

Unfortunately xpad isn't loaded at all when connecting the USB adapter. How can I debug what's going on?

pikim commented 7 years ago

@paroj Can you tell me how to use the dev_dbg() functionality? Do I have to compile the kernel to use it?

paroj commented 7 years ago

you can just use it as the module defines DEBUG at https://github.com/paroj/xpad/blob/master/xpad.c#L77.

when the usb dongle is connected xpad_probe is called but it probably immediately bails out because of wrong number of endpoints or unknown device id.

pikim commented 7 years ago

Thanks for that information. In the meantime and with your help I found out how to use the dev_x functions.

The driver is loaded and recognizes the adapter, but no init communication takes place, yet. I'm still working on it and had to fix other issues first.

pikim commented 7 years ago

I made another update. Read about the current state here.