Page 1 of 2

Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Fri Sep 29, 2017 8:38 pm
by aterial
I'm interested in creating firmware to mimic the Pro Controller. I've been using the serialusb proxy to capture dumps between the controller and the console, and it seems to work quite well. The switch detects the controller while it's being proxied and everything works as expected, all buttons work and motion/gyro controls work as well. I'm just having trouble figuring out how to handle requests from the switch and to return the proper response since i'm not experienced in LUFA. I'd be more than willing to help Matlo with adding switch controller support to GIMX, as i have a switch, a pro controller, and a working serialusb proxy.

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Sat Sep 30, 2017 8:35 pm
by Matlo
Hi,
I think we can add this for GIMX 8. From this version there will be a unique firmware based on the serialusb firmware.
Please send me your captures.
Also, could you please make a capture with all controls activated one by one? Make sure to write down the order.

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Sun Oct 01, 2017 4:07 am
by aterial
I've actually already created a working firmware that emulates a switch pro controller that can be compatible with GIMX with minimal changes. The only problem with this firmware is that motion/gyro controls are not emulated, since it represents itself as the POKKEN controller (somewhat popular in splatoon to print images as an in-game post). I want to make gyro/accel work because it stands to reason that using a mouse to control a virtual gyro will be more accurate than using the mouse to emulate a joystick.

Anyways, here's the packet dump with my own comments
http://www90.zippyshare.com/v/lKHfHHRB/file.html
The packets with comments are 173, 193, 213, 275, 303, 329, 407, 435, 467, 501, 527, and the big one, 1043. If we can emulate the proper Pro Controller instead of the Pokken controller, we can get motion controls working and possibly increase the accuracy of keyboard/mouse controls on the switch. I can also provide the source for the Pokken controller that shows up as a pro controller on the switch (without gyro/accel ofc).

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Mon Oct 02, 2017 1:50 pm
by Matlo
Thanks.

It would be interesting to make another capture, and to compare both.
Any significant difference is likely to indicate an authentication scheme.

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Thu Oct 05, 2017 12:52 am
by aterial
Was out of town for the last few days, i'll be sure to get you a few more captures by tomorrow!

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Fri Oct 06, 2017 6:13 am
by aterial
Here ya go!
http://www62.zippyshare.com/v/Z84A6Bv9/file.html

All of the dumps are taken from a cold start of the controller connected directly by wire to the rpi that's acting as the host, so if there's any authentication it should be easy to tell.
capture_enable_and_disable_gyro.pcap were me enabling and disabling the splatoon motion controls to see if the controller stops sending gyro/accel data, but it seems like the controller always sends gyro/accel data after some sort of command/delay.
capture_test_gyro.pcap were me holding the B button, releasing it, and rotating the controller Up/Down, Down/Up, Left/Right, and Right/Left to try and decode the accelerometer data, packet timings are

Code: Select all

Packet 3189 is the final packet where B is held the first time, after this packet, the gyro is tilted upwards, and then downwards, and then B is held again, and released, and the gyro is tilted down, and then up. This repeats for left/right.
Packet 4173 is the end of the Up/Down gyro test.
Packet 4531 is the beginning of the Down/Up gyro test.
Packet 6129 is the end of the Up/Down gyro test.
Packet 6569 is the beginning of the Left/Right gyro test.
Packet 8363 is the end of the Left/Right gyro test.
Packet 8701 is the beginning of the Right/Left gyro test.
Packet 10611 is the end of the Left/Right gyro test.
I didn't get much time to dig around the dumps so no comments this tme, but if you need anything or want me to test something, lemme know!

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Sun Oct 08, 2017 4:16 am
by aterial
Finally had time to dig through the packet dumps and i'm pretty sure i nailed down the communication. Here's what i got :

Code: Select all

Note that byte 2 seems to be a counter variable, always incrementing when sent from the controller)
Just for reference, < is from console to controller, > is from controller to console, and the rest is the data transferred in hex
< 0000
< 0000
< 8005
< 0000
< 8001
> 810100036c271bd60304000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
< 8002
> 81020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
< 01000000000000000000033000000000000000000000000000000000000000000000000000000000000000000000000000
> 21aa910080001968733ea8730b800300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000         (Bytes 2, 7-13 seem to be different, possible auth?)
< 8004                                                                                                                                     (Seems to trigger the sending of accel/gyro data)
< 010c0000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000                                       (Byte 2 seems to be different?)
From here the standard input loop begins (Packets 21/30 are continuously sent from the controller)
The console seems to send the controller random 01 packets that start off at 16 length, but after a while change to 10 byte length
< 010d0000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000
< 010e0000000000000000100060000010000000000000000000000000000000000000000000000000000000000000000000
< 010f0000000000000000103d60000019000000000000000000000000000000000000000000000000000000000000000000
< 01000000000000000000010493e310c6b56400043c4e696e74656e646f2053776974636800000000006800953328a05200                                       (This one contains "Nintendo Switch" as an ascii string)
< 01010001404000014040033000000000000000000000000000000000000000000000000000000000000000000000000000

From here it's only 21/30 input packets and the 10 packets from the console until shutdown.
I'll see if i can whip up a quick firmware to do some tests with.

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Thu Oct 12, 2017 6:55 pm
by aterial
I'm running into some issues with the custom firmware. I'm not too experienced with usb stuff, so i'm pretty sure im doing something wrong. When the switch starts sending my firmware the packets, my firmware breaks and doesn't receive it. Checking the proxy dumps it seems like i'm getting a Protocol Error from the firmware to the host.

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Thu Oct 12, 2017 6:57 pm
by Matlo
Share your source code somewhere and I'll have a look at it.

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Posted: Thu Oct 12, 2017 7:08 pm
by aterial
http://www3.zippyshare.com/v/OuXXHw7M/file.html
The descriptors seem to be correct, even if they're not laid out the 'proper' way (as in the usb dump with this firmware and the controller itself are identical).
The problem seems to occur after the switch sends the first 0x00, 0x00 packet. My current code seems to return a protocol error, and the proxy shows this

Code: Select all

configuration: 1
  interface: 0:0
    endpoint: IN INTERRUPT 1
    endpoint: OUT INTERRUPT 1 -> 2
Proxy started successfully. Press ctrl+c to stop it.
libusb_transfer failed with status LIBUSB_TRANSFER_ERROR (endpoint=0x01)
proxy.c:202 usb_write_callback: write transfer failed on endpoint 1 with error: OTHER ERROR
libusb_transfer failed with status LIBUSB_TRANSFER_ERROR (endpoint=0x01)
proxy.c:202 usb_write_callback: write transfer failed on endpoint 1 with error: OTHER ERROR
libusb_transfer failed with status LIBUSB_TRANSFER_ERROR (endpoint=0x01)
proxy.c:202 usb_write_callback: write transfer failed on endpoint 1 with error: OTHER ERROR
libusb_transfer failed with status LIBUSB_TRANSFER_ERROR (endpoint=0x01)
proxy.c:202 usb_write_callback: write transfer failed on endpoint 1 with error: OTHER ERROR
libusb_transfer failed with status LIBUSB_TRANSFER_ERROR (endpoint=0x01)
proxy.c:202 usb_write_callback: write transfer failed on endpoint 1 with error: OTHER ERROR
I'm sure its just something simple but i can't quite figure it out.
Also i'm building this on windows with AtmelStudio, not sure if that's relevant or not

Oh yeah, ignore the header on Joystick.c, i heavily modified that project for my own purposes.