Creating firmware to emulate the Nintendo Switch Pro Controller

Talk about anything concerning the source code.
aterial
Posts: 13
Joined: Fri Sep 22, 2017 7:01 am

Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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.
User avatar
Matlo
Posts: 5768
Joined: Wed Jul 06, 2011 7:01 am
Location: France
Contact:

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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.
GIMX creator
aterial
Posts: 13
Joined: Fri Sep 22, 2017 7:01 am

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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).
User avatar
Matlo
Posts: 5768
Joined: Wed Jul 06, 2011 7:01 am
Location: France
Contact:

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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.
GIMX creator
aterial
Posts: 13
Joined: Fri Sep 22, 2017 7:01 am

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post by aterial »

Was out of town for the last few days, i'll be sure to get you a few more captures by tomorrow!
aterial
Posts: 13
Joined: Fri Sep 22, 2017 7:01 am

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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!
aterial
Posts: 13
Joined: Fri Sep 22, 2017 7:01 am

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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.
aterial
Posts: 13
Joined: Fri Sep 22, 2017 7:01 am

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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.
User avatar
Matlo
Posts: 5768
Joined: Wed Jul 06, 2011 7:01 am
Location: France
Contact:

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post by Matlo »

Share your source code somewhere and I'll have a look at it.
GIMX creator
aterial
Posts: 13
Joined: Fri Sep 22, 2017 7:01 am

Re: Creating firmware to emulate the Nintendo Switch Pro Controller

Post 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.
Post Reply