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

HID Protocol for Bluetooth / USB #7

Open
ghost opened this issue Mar 15, 2017 · 185 comments

Comments

@ghost
Copy link

@ghost ghost commented Mar 15, 2017

Hi,

Loving the work you've done - thanks ever so much. Couldn't find you on social media, so am just gonna drop a message here.

Have you been able to sniff the USB or Bluetooth HID protocol it's using? Been trying to bodge a driver together, and don't really have the tools to analyse the protocol. Whilst the buttons and joysticks work fine, I believe the console sends a feature report to the joy-cons to activate gyroscope input. So far I've not had much luck getting the gyroscope and accelerometers to send anything over the standard protocol.

Could be me, or it could be Nintendo's very kind way of introducing security through obscurity.
Some help on the matter would be great if you are free.

Thanks

@alejandrorangel

This comment has been minimized.

Copy link

@alejandrorangel alejandrorangel commented Mar 15, 2017

I'm also working to reverse engineer the joycons, I found this documentation. I think that Nintendo might use something similar to the joycons.

[http://wiibrew.org/wiki/Wiimote](Wiimote HID)

@dekuNukem

This comment has been minimized.

Copy link
Owner

@dekuNukem dekuNukem commented Mar 15, 2017

thanks, I did figure out the accelerometer and gyroscope data in the joycon status packet today, but only in the physical connection bewteen the joycon and console. I haven't began working on the bluetooth level yet, but I'll keep it in mind when I do.

@forerofore

This comment has been minimized.

Copy link

@forerofore forerofore commented Mar 16, 2017

just to make you guys aware, there is a program similar to glovepie called freepie, the possibility of developing a module for the joycons may be faster/easier than an entire new driver. thanks and gj with all of this.

heres the link btw
[http://andersmalmgren.github.io/FreePIE/]

@ghost

This comment has been minimized.

Copy link
Author

@ghost ghost commented Mar 16, 2017

@alejandrorangel Cool, thanks for that. I might try and throw some of the Wiimote packets at it this weekend and see if it reacts to any of them.

@aspalmer

This comment has been minimized.

Copy link

@aspalmer aspalmer commented Mar 16, 2017

Over USB the pro controller just does a handshake, then switches to bluetooth.
Descriptor:
procontroller descriptor.txt
Beagle analyzer trace:
data-center-windows-x86_64-v6.72.zip

@ghost

This comment has been minimized.

Copy link
Author

@ghost ghost commented Mar 21, 2017

@aspalmer That actually makes sense from the HID reports I was getting back, actually. Was able to get the HID info from the USB device, although no data was being sent. However when I paired the USB and Bluetooth together using some test code, I noticed one thing.
Over the USB, the HID protocol reports that there are 2 extra components called "Z-Acceleration, and Z-Rotation". I can only imagine this is the gyroscope and accelerometer. However, as it was over USB, no data was sent. This leads me to believe you do indeed have to send a feature report packet to the controller via bluetooth to enable the gyro/acc.

Also, via USB the HID device is reported as a "stick" or "joystick", versus the Bluetooth HID which reports as "gamepad". Can actually see this from the descriptor you sent over actually.

@rlaferla

This comment has been minimized.

Copy link

@rlaferla rlaferla commented Mar 23, 2017

I'd love to see an iOS API for the JoyCon via Bluetooth.

UPDATE: iOS uses its own Bluetooth controller specification which means it does not work natively with the Joy-Con or Switch Pro controllers.

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Mar 25, 2017

I have some notes on the Bluetooth hid buttons. The left stick & right stick buttons are adjacent button numbers. So are + - and home, capture.

It sends the stick data as hat input, though. (0-8, 8 is neutral, 0 is up) Annoying.

@fossephate

This comment has been minimized.

Copy link

@fossephate fossephate commented Mar 26, 2017

@riking What are you using to capture the Bluetooth traffic?

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Mar 27, 2017

@mfosse Oh, I just straight up connected the joycon to my Linux laptop and read the input data with hidapi. So it's default drivers.

Was about to try sending some of the 0x19 packets as OUPTUT or FEATURE reports and see what happens.


So when I hid_write a packet with command 0x01, I get this response back:

Joycon R: Packet 0x21
C9 8E 80 00 00 00 00 00 
E6 C8 6F 01 81 01 0C 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 

Joycon R: Packet 0x21
8F 8E 80 00 00 00 00 00 
E6 A8 6F 01 80 00 03 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 

Joycon L: Packet 0x21
4F 8E 00 01 4F 9F 57 89
00 00 00 20 81 01 0C 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 

Perhaps Byte 0 is the checksum? I should try calculating it.

Byte 1 is always 0x8E. Byte 2, 3, 4 is the button status.

    case 0x21: // Packet 0x21
        // Button status:
        // Byte 1: 0x8E
        //  Byte 2
        //   Bit 0: JR Y
        //   Bit 1: JR X
        //   Bit 2: JR B
        //   Bit 3: JR A
        //   Bit 4: JR SR
        //   Bit 5: JR SL
        //   Bit 6: JR R
        //   Bit 7: JR ZR
        // Byte 4
        //   Bit 0: JL Down
        //   Bit 1: JL Up
        //   Bit 2: JL Right
        //   Bit 3: JL Left
        //   Bit 4: JL SR
        //   Bit 5: JL SL
        //   Bit 6: JL L
        //   Bit 7: JL ZL
        // Byte 3
        //   Bit 2: RStick
        //   Bit 3: LStick
        //   Bit 4: Home
        //   Bit 5: Capture

Next 3 bytes are only set by the left joycon. Next 3 bytes are only set by the right joycon. Haven't figured out what data they carry. Found the stick data! They seem relatively stable when the stick isn't moving.

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Mar 27, 2017

Yup, I found the stick data.

uint8_t *pckt = buf65 + 2; // skip the HID header (0x21) and checksum byte
// print buttons...
uint8_t *stick_data;
if (jc->left_right == 1) {
    stick_data = pckt + 4;
} else {
    stick_data = pckt + 7;
}
uint8_t stick_unk = stick_data[0]; // maybe checksum
// horizontal stick is nibble swapped??
uint8_t stick_hz = ((stick_data[1] & 0x0F) << 4) | ((stick_data[1] & 0xF0) >> 4);
uint8_t stick_vert = stick_data[2];
printf("Stick %c: [%02X] %d %d\n", L_OR_R(jc->left_right), stick_unk, -128 + (int)(unsigned int)stick_hz, -128 + (int)(unsigned int)stick_vert);

Haven't figured out the last bit of data. It only seems to send a couple of bit patterns:

(L) 10 81 01 0C
(L) 10 80 00 03
(L) 10 80 0C 03
(L) 40 80 00 03

(R) 01 80 00 03
(R) 03 80 00 03
(R) 03 81 01 0B

Definitely not the gyro data.

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Mar 28, 2017

Oooookay, looks like I'm going to need to pair the controllers before I move further - they started connecting to someone else's console, which is erroring out my Bluetooth stack.

Here's what I have so far:
https://github.com/riking/joycon/blob/master/src/joycon_input.c
https://github.com/riking/joycon/blob/master/src/joycon.h

@ghost

This comment has been minimized.

Copy link
Author

@ghost ghost commented Mar 28, 2017

Can confirm the joy-cons and pro controller do operate using the standard HID protocol, all except the gyro and accelerometer.

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Mar 28, 2017

I've got a working "combine both joycons into a single controller device" program here: https://github.com/riking/joycon

@fossephate

This comment has been minimized.

Copy link

@fossephate fossephate commented Apr 3, 2017

I'm working on a vJoy feeder for the JoyCons here: https://github.com/mfosse/JoyCon-Driver

@shinyquagsire23

This comment has been minimized.

Copy link
Contributor

@shinyquagsire23 shinyquagsire23 commented Apr 8, 2017

The Charging Joy-Con grip seems to have two interfaces with an in/out endpoint per interface for each Joy-Con. I haven't managed to get any replies from input I've sent, however the Joy-Con grip, once an HID session is started, seems to send packets matching the first MAC address handshake command for UART every time the Joy-Con are inserted and ejected. The format seems to go as follows:

81 01 <03 for eject, 00 otherwise> <inserted Joy-Con type, 01 for Left, 02 for right> <MAC>

This can also be observed from Wireshark:

The charging grip also has the same STM32 chip as the pro controller, and the same 5-pin layout found on the dock. Maybe the firmware can be dumped same as the dock to learn more about UART and Bluetooth commands @dekuNukem?

@shinyquagsire23

This comment has been minimized.

Copy link
Contributor

@shinyquagsire23 shinyquagsire23 commented Apr 8, 2017

Checked out the USB capture from @aspalmer and sending 0x80 0x01 gives me that MAC packet. It seems to respond to some of the other output reports in the capture similarly, so it seems that two Joy-Con in a charging grip effectively functions as a Pro Controller with two interfaces.

@a7a00

This comment has been minimized.

Copy link

@a7a00 a7a00 commented Apr 9, 2017

Guys, please see #11; I don't think the HD rumble data is HID compliant.

@shinyquagsire23

This comment has been minimized.

Copy link
Contributor

@shinyquagsire23 shinyquagsire23 commented Apr 9, 2017

I have the firmware for the Joy-Con charging grip, doing a quick search for A1 A2 A3 A4 gets me a hit so it does seem that they talk to Joy-Con and have some sort of shim to HID. The firmware is pretty small though, 0x10000 bytes total. Willing to bet there's a point where UART and HID have to match up, that or this thing is a dedicated MAC address fetcher but I have my doubts there.

EDIT: For anyone else's curiousity, the 5 througholes are an SWD debug interface, from top to bottom:

??
SWDIO
GND
VDD
SWCLK

I also had to tap the test pad above the middle bottom screw for nRST. Dumping is pretty straightforward with OpenOCD.

EDIT 2: It seems this thing is definitely capable of sending post-handshake UART packets, and most of the handshake is done by the device, though for post-handshake packets the question is how it gets triggered I suppose:

@fossephate

This comment has been minimized.

Copy link

@fossephate fossephate commented Apr 9, 2017

Has anyone managed to read any gyroscope or accelerometer data over bluetooth? I haven't had any luck so far.

@fossephate

This comment has been minimized.

Copy link

@fossephate fossephate commented Apr 9, 2017

@riking I figured out what stick_unknown is
it appears that the X component of the stick data isn't just nibble reversed, specifically, the second nibble of second byte is combined with the first nibble of the first byte to get the correct X stick value:

uint8_t stick_horizontal = ((stick_data[1] & 0x0F) << 4) | ((stick_data[0] & 0xF0) >> 4);

I don't have any idea what the other nibbles are, they seem random to me, but I haven't looked at them too closely.

@shinyquagsire23

This comment has been minimized.

Copy link
Contributor

@shinyquagsire23 shinyquagsire23 commented Apr 10, 2017

It seems there is indeed a set of HID commands which allow sending UART commands, however they cannot be accessed until handshaking is complete, and I'm not sure of the command to do that (seems to be done elsewhere from the main loop).

Commands which seem to exist at 0x0800BB00 are:

80 01 (Handled elsewhere? Returns MAC packet)
80 02 (Do two handshakes 19 01 03 07 00 91 10 00, 19 01 03 0B 00 91 12 04)
80 03 (Do baud switch)
80 04 (Set something to 1)
80 05 (Set something to 0)
80 06 (Something with sending post-handshake command 01 00 00 00 00 00 00 00 01 06 00 00, maybe baud related as well?)
80 91 ... (Send pre-handshake command? Has some weird lookup table stuff)
80 92 ... (Something with pre-handshake commands?)
01 ... (Send post-handshake command? Sends 0x31-large UART starting with 19 01 03 07 00 92 00 00 with checksum edited in and the rest of the HID request pinned on)
10 ... (Same as above)

EDIT: turns out the 'lookup table' stuff for 80 91 is actually for incoming UART data size, just managed to send a raw pre-handshake UART packet like such:

memset(buf, 0x00, 0x100);
buf[0] = 0x80;
buf[1] = 0x91;
buf[2] = 0x01;
buf[3] = 0x0;
buf[4] = 0x0;
buf[5] = 0x0;
buf[6] = 0x0;
hid_write(handle_l, buf, 0x7);

And the resulting data I got back was the MAC packet in a slightly different form:

81 91 00 94 01 08 00 00 3c 68 01 fd bf e8 8a bb 7c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

EDIT 2: Seems 80 92 actually works to a degree to send post-handshake commands (with pre-handshake headers?), this works to get something resembling an input packet, but none of the actual input shows up.

memset(buf, 0x00, 0x100);
buf[0] = 0x80;
buf[1] = 0x92;
buf[2] = 0x00;
buf[3] = 0x01;
buf[4] = 0x0;
buf[5] = 0x0;
buf[6] = 0x69;
buf[8] = 0x1F;
hid_exchange(handle_l, buf, 0x9);

EDIT 3: For the record...

Since the firmware tells me this, these are the return sizes for any 19 01 03 07 00 91 XX ... UART command:

01 - 0xF
03, 05, 06, 07, 13, anything else? - 0xB
18 - 0x37
40 - The size specified in the u16 following the XX command
@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Apr 11, 2017

I left my controllers on the grip for a few days and now the status packet[1] is 0x6E on the R, but it's still 0x8E on the L. Battery level?

EDIT: Docked the controller for a bit and it's back to 0x8E. Definitely a single nibble of battery

Also, noticed something weird. The kernel is always returning 0 for the number of actual bytes written 🤔 This may be why I had no response to writes other than 0x1 🤔

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Apr 11, 2017

Here's what the Linux Kernel gives for the report descriptor over bluetooth:

https://www.irccloud.com/pastebin/P60ntzyH/

@shinyquagsire23 can you dump /sys/kernel/debug/hid/*/rdesc with the Charging Grip?

@shinyquagsire23

This comment has been minimized.

Copy link
Contributor

@shinyquagsire23 shinyquagsire23 commented Apr 11, 2017

@riking That file doesn't seem to exist for me, but the charging grip also doesn't function as a controller by default.

Also, I've managed to get a full initialization of the Joy-Con via the charging grip. The charging grip is able to send any UART command, so I am able to pull for full input at around 16ms per input, in addition to being able to dump my Joy-Con SPI firmware over HID. My HID program can be found at my repo, https://github.com/shinyquagsire23/HID-Joy-Con-Whispering

Hopefully with that, it should be possible to test Joy-Con functionality more in-depth. I did try to have the same HID commands sent over Bluetooth but it seems it's not the same protocol, unfortunately...

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Apr 11, 2017

Sorry, the underscores weren't meant to be literal - replace them with the kernel-assigned device identifier.
The file should be there if hidapi can open the device, so sudo ls the directory.

but it seems it's not the same protocol, unfortunately...

Dang :(

@shinyquagsire23

This comment has been minimized.

Copy link
Contributor

@shinyquagsire23 shinyquagsire23 commented Apr 11, 2017

@riking Ah, I did replace the underscores but I guess I forgot to escape something and it failed, https://gist.github.com/shinyquagsire23/89ea38220e221950a233cd23f2fde28f

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Apr 11, 2017

Okay, wow. Much more straightforward than the Bluetooth dump. Looks like a charging grip is almost all you need to use the joycons as a controller, I'll have to get one and add button mapping support in to my program.

Still doesn't help with the Bluetooth protocol except to reinforce that yes, 0x80 is definitely a bridge to the wires and it's definitely not available over Bluetooth.

@ghost

This comment has been minimized.

Copy link
Author

@ghost ghost commented Apr 11, 2017

Bit of a long shot, but input 33 and 129 look like pitch/yaw inputs of a gyro

@riking

This comment has been minimized.

Copy link
Contributor

@riking riking commented Apr 12, 2017

33 is the status report (0x21) sent in reply to a 0x1 HID output report and parsed here https://github.com/riking/joycon/blob/master/src/joycon_input.c#L53

@NathanReeves

This comment has been minimized.

Copy link

@NathanReeves NathanReeves commented Jun 28, 2018

Sending correct reports:
[00:00:13.449] LOG -- hid_device.c.297: HID Connected
[00:00:13.459] EVT <= 13 05 01 81 00 01 00
[00:00:13.463] EVT <= 38 04 81 00 80 0C
[00:00:13.472] EVT <= 6E 00
[00:00:13.475] CMD => 35 0C 05 01 81 00 05 00
[00:00:13.479] EVT <= 6E 00
[00:00:13.483] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.489] EVT <= 6E 00
[00:00:13.500] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.501] EVT <= 6E 00
[00:00:13.509] EVT <= 1B 03 81 00 01
[00:00:13.510] EVT <= 13 05 01 81 00 01 00
[00:00:13.512] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.517] EVT <= 6E 00
[00:00:13.521] EVT <= 13 05 01 81 00 01 00
[00:00:13.528] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.531] EVT <= 6E 00
[00:00:13.553] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.554] EVT <= 6E 00
[00:00:13.565] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.566] EVT <= 6E 00
[00:00:13.577] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.578] EVT <= 6E 00
[00:00:13.589] ACL => 81 00 11 00 0D 00 4E 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:13.590] EVT <= 6E 00
[00:00:13.590] EVT <= 1B 03 81 00 05
[00:00:13.593] ACL <= 81 20 36 00 32 00 43 00 A2 01 0E 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[00:00:13.615] ACL => 81 00 36 00 32 00 4E 00 A1 21 05 8E 00 00 00 00 00 00 2F C8 74 0B 82 02 03 89 02 02 30 AE A4 06 4A 3E 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[00:00:13.632] EVT <= 13 05 01 81 00 01 00
[00:00:13.636] EVT <= 6E 00
[00:00:13.639] CMD => 35 0C 05 01 81 00 01 00
[00:00:13.643] EVT <= 6E 00
[00:00:13.658] ACL <= 81 20 0C 00 08 00 01 00 06 08 04 00 43 00 4E 00
[00:00:13.658] LOG -- l2cap.c.2463: L2CAP signaling handler code 6, state 12
[00:00:13.661] ACL => 81 00 0C 00 08 00 01 00 07 08 04 00 43 00 4E 00
[00:00:13.667] LOG -- l2cap.c.906: L2CAP_EVENT_CHANNEL_CLOSED local_cid 0x43
[00:00:13.674] EVT <= 71 02 43 00
[00:00:13.677] LOG -- hid_device.c.309: HID Interrupt closed
[00:00:13.682] LOG -- hid_device.c.314: HID Disconnected

Could this still be a timeout issue?

@gettinwet

This comment has been minimized.

Copy link

@gettinwet gettinwet commented Jun 28, 2018

That doesn't look like a timeout, maybe you answered wrong, I don't know, I'm not so familiar with Switch protocol, but to me, that 0B before 82 is kinda suspicious. Anyway, you've successfully lured Switch to ask you question, that's already a step forward.

@DickyT

This comment has been minimized.

Copy link

@DickyT DickyT commented Jul 15, 2018

@timmeh87 @NathanReeves Thank you for your information on simulating Joy-Con. Actually I have this idea to make a fake Joy-Con using Raspberry Pi. Before I start everything, I just wonder if it is actually doable, or the bluetooth channel is actually encrypted, and it is not able to stimulate a brand new Joy-Con?

@YouTubePlays

This comment has been minimized.

Copy link

@YouTubePlays YouTubePlays commented Nov 24, 2018

Did anyone successfully spoofed JoyCon over Bluetooth?
I would like to spoof JoyCon over Bluetooth however I could not figure out how?
It would be useful if anyone has L2CAP server or client for JoyCon.

Or Let me know I am so far off 😃

@YouTubePlays

This comment has been minimized.

Copy link

@YouTubePlays YouTubePlays commented Dec 2, 2018

@timmeh87 @NathanReeves Thank you for your information on simulating Joy-Con. Actually I have this idea to make a fake Joy-Con using Raspberry Pi. Before I start everything, I just wonder if it is actually doable, or the bluetooth channel is actually encrypted, and it is not able to stimulate a brand new Joy-Con?

@DickyT I was able to spoof parts of joycon bluetooth protocol. So I think it is definitely possible. If you wanna work together on same spoofing project I am open let me know.

Here you can see I was able to connect to switch and pair as joycon and send commands. I used mostly timmeh87's notes

@timmeh87

This comment has been minimized.

Copy link

@timmeh87 timmeh87 commented Dec 2, 2018

Yes the spoofing is everywhere if you look hard enough. This git is probably THE source on the internet for information so you came to the right place. Im working on something thats covered with an NDA but here is a british person raving about some hardware that could be found in the wild over a year ago

https://www.youtube.com/watch?v=I6CZIip90ws

@shabbir-hussain

This comment has been minimized.

Copy link

@shabbir-hussain shabbir-hussain commented Dec 2, 2018

@timmeh87 I'm wondering if the CC2564 bluetooth module is still the best tool for spoofing or @NathanReeves mentioned using ESP32? Any other hardware you'd recommend that makes the job easy?

@NathanReeves

This comment has been minimized.

Copy link

@NathanReeves NathanReeves commented Dec 6, 2018

I’m using BTStack on ESP32 by the way, there’s good support. I haven’t had success yet though.

Quick question for anyone who has successfully spoofed: how long before the switch times out?

From my packet log it took me 21 ms to respond, is that too long? Currently I’m able to get as far as receiving the 03 30 report, my switch displays the device is paired before it disconnects. I’m guessing I’m answering correctly, big-endian address and sending 0s for SPI data, but I’m not too confident my timing is solid.

@shabbir-hussain

This comment has been minimized.

Copy link

@shabbir-hussain shabbir-hussain commented Dec 7, 2018

It seems like an ESP32 is easier to develop on that the CC2564. @NathanReeves do you have sample code you can share?

@galli-leo

This comment has been minimized.

Copy link

@galli-leo galli-leo commented Jan 6, 2019

@YouTubePlays @DickyT @NathanReeves I want to create a program to connect other controllers to the switch via bluetooth. Could you share any progress you guys made on spoofing the joycons? Also would any of you be willing to cooperate in building a library for spoofing the joycons?

@DickyT

This comment has been minimized.

Copy link

@DickyT DickyT commented Jan 8, 2019

@galli-leo Actually I did not work on it anymore. I am very new to the Bluetooth protocol and I am getting difficulties when debugging it.

@YouTubePlays

This comment has been minimized.

Copy link

@YouTubePlays YouTubePlays commented Jan 11, 2019

@galli-leo I think I would be interested in the idea of making a library but I dont know how much time I can commit.

@Molorius

This comment has been minimized.

Copy link

@Molorius Molorius commented Jan 31, 2019

EDIT: This was my misunderstanding of the framework I was using (BTstack), these messages are internal errors and not from the Switch.

I could use some help debugging l2cap packets. This may just be the way my framework handles packets, but I'm having trouble understanding them. I am using an esp32 with BTstack to make the connection. I got the Switch (MAC address 04:03:D6:27:E6:C0) to connect to my esp32. I am only listening, I am not sending any packets out. This is after a fresh reboot of both devices, but the Switch has seen the esp32's MAC address before. The esp32's name is "Pro Controller", the class is 0x2508 (mimicking the Pro Controller), the MAC is random.

Initial connection l2cap packet:
72 0E C0 E6 27 D6 03 04 81 00 11 00 40 00 40 00

After about 3/4 of a second it successfully connects to psm 17, channel id 64 and sends:
70 16 00 C0 E6 27 D6 03 04 81 00 11 00 40 00 40 00 64 00 BC 02 00 00 01

When it disconnects it sends this:
71 02 40 00

I couldn't seem to match these packets to any of the above discussion (such as CRC), except for the MAC address.
Interestingly, the Switch still attempts to pair even in airplane mode when you go to Controllers -> Change Grip/Order. Another interesting thing is that the Switch connects to psm 17 initially, but my Linux computer connects to psm 1 initially (I haven't tested too many psms though; just the common ones, 17, and 31).

@Molorius

This comment has been minimized.

Copy link

@Molorius Molorius commented Jan 31, 2019

Also, it took me a while to find the SDP records of the Switch and a controller so here they are.

"Nintendo Switch"
Class 0x00043c

Service RecHandle: 0x10000
Service Class ID List:
    "Generic Attribute" (0x1801)
Protocol Descriptor List:
    "L2CAP" (0x0100)
        PSM: 31
    "ATT" (0x0007)
        uint16: 0x0001
        uint16: 0x0005

Service RecHandle: 0x10001
Service Class ID List:
    "Generic Access" (0x1800)
Protocol Descriptor List:
    "L2CAP" (0x0100)
        PSM: 31
    "ATT" (0x0007)
        uint16: 0x0014
        uint16: 0x001a
"Pro Controller"
Class 0x002508

Service Name: Wireless Gamepad
Service Description: Gamepad
Service RecHandle: 0x0
Service Class ID List:
    "SDP Server" (0x1000)
Protocol Descriptor List:
    "L2CAP" (0x01000)
        PSM: 1
    "SDP" (0x0001)
Language Base Attr List:
    code_ISO639: 0x656e
    encoding: 0x6a
    base_offset: 0x100
Profile Descriptor List:
    "" (0x0100)
    Version: 0x0100

Service Name: Wireless Gamepad
Service Description: Gamepad
Service Provider: Nintendo
Service RecHandle: 0x10000
Service Class ID List:
    "Human Interface Device" (0x1124)
Protocol Descriptor List:
    "L2CAP" (0x0100)
        PSM: 17
    "HIDP" (0x0011)
Language Base Attr List:
    code_ISO639: 0x656e
    encoding: 0x6a
    base_offset: 0x100

Edit: Left and Right joycons have the same SDP record and class as the Pro Controller, but with the names "Joy-Con (L)" and "Joy-Con (R)".

@Molorius

This comment has been minimized.

Copy link

@Molorius Molorius commented Feb 3, 2019

New problem found! Or at least I couldn't see any documentation on it above. The Pro Controller and Joy-Cons send different packets depending on whether it thinks it's connected to a Switch or something else. Note that these are all l2cap packets. Note that my device is just reading, it is not sending any packets. Here's the first few packets with a random host name:

A1 3F 00 00 08 10 00 EF FF 10 00 FF FF
A1 3F 00 00 08 30 78 BF 82 40 79 8F 85
A1 3F 00 00 08 20 78 EF 82 10 79 BF 85

This is well documented already.

But if you set the host's name to "Nintendo Switch", it sends different packets. It does not matter what class you set the host to. Here's the first few packets from a Pro Controller:

A1 30 00 40 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 15 40 00 00 00 83 27 7D 98 67 7A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 19 40 00 00 00 82 57 7D 93 37 7A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Here's the first few from a right Joy-Con:

A1 30 00 80 00 00 00 00 00 00 93 99 66 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 5B 8E 00 00 00 00 00 00 E0 68 73 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 5F 8E 00 00 00 00 00 00 DF 58 73 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 62 8E 00 00 00 00 00 00 E0 68 73 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0xA1 states that is a data hid input, that's standard. 0x30 appears to be the length of the remaining packet, but the length is always the same. I'm fairly new to bluetooth, is there a standard layer on top of hid?


EDIT here's from a different Pro Controller:

A1 30 00 80 00 00 00 00 10 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 18 80 00 00 00 4D E8 74 E9 D7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 1D 80 00 00 00 4E F8 74 E8 B7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 1F 80 00 00 00 4E 08 75 E9 E7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 24 80 00 00 00 4E 28 75 E8 F7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

And from the same controller after rebooting both devices:

A1 30 00 60 00 00 00 01 10 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 1B 60 00 00 00 3D F8 76 E5 A7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 1F 60 00 00 00 3E 28 77 E8 B7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 22 60 00 00 00 3F 48 77 E8 B7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A1 30 26 60 00 00 00 3E 38 77 E7 B7 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@Molorius

This comment has been minimized.

Copy link

@Molorius Molorius commented Feb 3, 2019

Wait, apparently I don't know how to read. This is also well documented in the link above. Thank you for all the hard work you put into that documentation! I'll stop spamming this thread.

@atrevett

This comment has been minimized.

Copy link

@atrevett atrevett commented Feb 25, 2019

Hey guys!

Wanted to say all the info is great! I recently started trying to spoof a Pro Controller over bluetooth and I'm pretty excited to see several others have made some good progress.

I've been trying to get the Nintendo switch to initiate a connection to my bluetooth dongle, but its seeming to be fairly stubborn (I advertise and have the device discoverable, but I don't see any L2CAP or SDP traffic in wireshark for the BT adapter). I think this is because also having issues setting up my SDP server to match the pro controller's entries exactly. I'm currently using pybluez so the best I can do is modify the service class, protocol descriptor, and profile descriptors, but not some of the other attributes I noticed the controller had.

Anyone here have a similiar setup they managed to get working? I'm on Ubuntu 18 with Bluez (5.x) as the bluetooth stack. I'm currently trying to program in Python using pybluez as the library, though I'm not having much luck modifying the SDP Server entries through something like sdptool either.

Any pointers are helpful. I'm trying to take a purely software approach on this one, as I'm not very handy with circuit boards. Once I can get the switch sending anything, I feel like there's more than enough information here to get going on my own.

@fluffymadness

This comment has been minimized.

Copy link

@fluffymadness fluffymadness commented Mar 31, 2019

Does anyone have the bluetooth hid descriptor of the Nintendo Switch Pro Controller?
According to some comments above it should be different to the usb one.
Thanks.

@fluffymadness

This comment has been minimized.

Copy link

@fluffymadness fluffymadness commented Apr 18, 2019

I'm using btstack, and trying to replicate @NathanReeves example above
I'm not really sure what I'm doing wrong. I'm playing around for a few hours now, but the switch won't send me a 0x2 request at all. Maybe someone is doing the same thing. The logs look normal to me.

[00:00:04.878] LOG -- btstack_link_key_db_tlv.c.165: store with tag 42544c0e
[00:00:04.885] LOG -- btstack_tlv_esp32.c.54: tag 42544c0e -> 42544C0E
[00:00:04.891] LOG -- btstack_tlv_esp32.c.98: store tag 42544C0E
[00:00:04.898] EVT <= 08 04 00 80 00 01
[00:00:04.900] LOG -- hci.c.4245: hci_emit_security_level 2 for handle 80
[00:00:04.907] EVT <= E0 03 80 00 02
[00:00:04.910] LOG -- l2cap.c.2224: l2cap - security level update for handle 0x0080
[00:00:04.918] ACL <= 80 20 0C 00 08 00 01 00 02 04 04 00 11 00 43 00
[00:00:04.924] LOG -- l2cap.c.1864: channel 0x3ffd06b0, local_cid 0x0040
[00:00:04.930] LOG -- hci.c.4348: gap_request_security_level requested level 2, planned level 0, current level 2
[00:00:04.940] LOG -- hci.c.4245: hci_emit_security_level 2 for handle 80
[00:00:04.947] EVT <= E0 03 80 00 02
[00:00:04.950] LOG -- l2cap.c.2224: l2cap - security level update for handle 0x0080
[00:00:04.958] LOG -- l2cap.c.2234: channel 0x3ffd06b0, cid 0040 - state 5: actual 2 >= required 2?
[00:00:04.966] LOG -- l2cap.c.939: L2CAP_EVENT_INCOMING_CONNECTION addr 64:B5:C6:4C:43:9A handle 0x80 psm 0x11 local_cid 0x40 remote_cid 0x43
[00:00:04.979] EVT <= 72 0E 9A 43 4C C6 B5 64 80 00 11 00 40 00 43 00
[00:00:04.985] LOG -- l2cap.c.2345: L2CAP_ACCEPT_CONNECTION local_cid 0x40
[00:00:04.992] ACL => 80 00 10 00 0C 00 01 00 03 04 08 00 40 00 43 00 00 00 00 00
[00:00:04.999] EVT <= 6E 00
[00:00:05.002] ACL => 80 00 10 00 0C 00 01 00 04 01 08 00 43 00 00 00 01 02 64 00
[00:00:05.009] LOG -- l2cap.c.1100: l2cap_stop_rtx for local cid 0x40
[00:00:05.015] LOG -- l2cap.c.1109: l2cap_start_rtx for local cid 0x40
[00:00:05.021] EVT <= 6E 00
[00:00:05.024] CMD => 35 0C 05 01 80 00 01 00
[00:00:05.028] EVT <= 13 05 01 80 00 01 00
[00:00:05.032] ACL <= 80 20 0C 00 08 00 01 00 02 05 04 00 13 00 42 00
[00:00:05.038] LOG -- l2cap.c.1864: channel 0x3ffd071c, local_cid 0x0041
[00:00:05.045] LOG -- hci.c.4348: gap_request_security_level requested level 2, planned level 0, current level 2
[00:00:05.054] LOG -- hci.c.4245: hci_emit_security_level 2 for handle 80
[00:00:05.061] EVT <= E0 03 80 00 02
[00:00:05.064] LOG -- l2cap.c.2224: l2cap - security level update for handle 0x0080
[00:00:05.072] LOG -- l2cap.c.2234: channel 0x3ffd071c, cid 0041 - state 5: actual 2 >= required 2?
[00:00:05.080] LOG -- l2cap.c.939: L2CAP_EVENT_INCOMING_CONNECTION addr 64:B5:C6:4C:43:9A handle 0x80 psm 0x13 local_cid 0x41 remote_cid 0x42
[00:00:05.093] EVT <= 72 0E 9A 43 4C C6 B5 64 80 00 13 00 41 00 42 00
[00:00:05.099] LOG -- l2cap.c.2345: L2CAP_ACCEPT_CONNECTION local_cid 0x41
[00:00:05.106] LOG -- l2cap.c.2234: channel 0x3ffd06b0, cid 0040 - state 11: actual 2 >= required 2?
[00:00:05.115] EVT <= 13 05 01 80 00 01 00
[00:00:05.119] ACL <= 80 20 10 00 0C 00 01 00 04 06 08 00 40 00 00 00 01 02 BC 02
[00:00:05.126] LOG -- l2cap.c.2550: L2CAP signaling handler code 4, state 11
[00:00:05.133] LOG -- l2cap.c.2401: Remote MTU 700
[00:00:05.137] ACL <= 80 20 0E 00 0A 00 01 00 05 01 06 00 40 00 00 00 00 00
[00:00:05.144] LOG -- l2cap.c.2550: L2CAP signaling handler code 5, state 11
[00:00:05.151] LOG -- l2cap.c.1100: l2cap_stop_rtx for local cid 0x40
[00:00:05.157] LOG -- l2cap.c.2481: l2cap_signaling_handle_configure_response
[00:00:05.164] EVT <= 6E 00
[00:00:05.166] ACL => 80 00 10 00 0C 00 01 00 03 05 08 00 41 00 42 00 00 00 00 00
[00:00:05.174] EVT <= 6E 00
[00:00:05.176] ACL => 80 00 10 00 0C 00 01 00 04 02 08 00 42 00 00 00 01 02 64 00
[00:00:05.184] LOG -- l2cap.c.1100: l2cap_stop_rtx for local cid 0x41
[00:00:05.190] LOG -- l2cap.c.1109: l2cap_start_rtx for local cid 0x41
[00:00:05.196] EVT <= 13 05 01 80 00 01 00
[00:00:05.200] ACL <= 80 20 10 00 0C 00 01 00 04 07 08 00 41 00 00 00 01 02 BC 02
[00:00:05.207] LOG -- l2cap.c.2550: L2CAP signaling handler code 4, state 11
[00:00:05.214] LOG -- l2cap.c.2401: Remote MTU 700
[00:00:05.218] EVT <= 13 05 01 80 00 01 00
[00:00:05.222] ACL <= 80 20 0E 00 0A 00 01 00 05 02 06 00 41 00 00 00 00 00
[00:00:05.229] LOG -- l2cap.c.2550: L2CAP signaling handler code 5, state 11
[00:00:05.236] LOG -- l2cap.c.1100: l2cap_stop_rtx for local cid 0x41
[00:00:05.242] LOG -- l2cap.c.2481: l2cap_signaling_handle_configure_response
[00:00:05.249] EVT <= 6E 00
[00:00:05.251] ACL => 80 00 12 00 0E 00 01 00 05 07 0A 00 42 00 00 00 00 00 01 02 64 00
[00:00:05.259] LOG -- l2cap.c.905: L2CAP_EVENT_CHANNEL_OPENED status 0x0 addr 64:B5:C6:4C:43:9A handle 0x80 psm 0x13 local_cid 0x41 remote_cid 0x42 local_mtu 100, remote_mtu 700, flush_timeout 0
[00:00:05.276] EVT <= 70 18 00 9A 43 4C C6 B5 64 80 00 13 00 41 00 42 00 64 00 BC 02 00 00 01 00 00
Hid connected
[00:00:05.286] LOG -- btgamepad.c.177: HID Connected

[00:00:05.291] EVT <= 13 05 01 80 00 01 00
[00:00:05.295] EVT <= 6E 00
[00:00:05.298] ACL => 80 00 12 00 0E 00 01 00 05 06 0A 00 43 00 00 00 00 00 01 02 64 00
[00:00:05.306] LOG -- l2cap.c.905: L2CAP_EVENT_CHANNEL_OPENED status 0x0 addr 64:B5:C6:4C:43:9A handle 0x80 psm 0x11 local_cid 0x40 remote_cid 0x43 local_mtu 100, remote_mtu 700, flush_timeout 0
[00:00:05.323] EVT <= 70 18 00 9A 43 4C C6 B5 64 80 00 11 00 40 00 43 00 64 00 BC 02 00 00 01 00 00
[00:00:05.332] EVT <= 13 05 01 80 00 01 00
[00:00:05.335] EVT <= 38 04 80 00 80 0C
[00:00:05.339] EVT <= 6E 00
[00:00:05.342] EVT <= 78 02 41 00
[00:00:05.345] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.352] EVT <= 6E 00
[00:00:05.355] EVT <= 78 02 41 00
[00:00:05.358] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.366] EVT <= 6E 00
[00:00:05.368] EVT <= 78 02 41 00
[00:00:05.371] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.379] EVT <= 6E 00
[00:00:05.381] EVT <= 78 02 41 00
[00:00:05.385] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.392] EVT <= 6E 00
[00:00:05.395] EVT <= 78 02 41 00
[00:00:05.398] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.406] EVT <= 1B 03 80 00 01
[00:00:05.409] EVT <= 13 05 01 80 00 01 00
[00:00:05.413] EVT <= 13 05 01 80 00 01 00
[00:00:05.417] EVT <= 6E 00
[00:00:05.419] EVT <= 78 02 41 00
[00:00:05.422] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.430] EVT <= 13 05 01 80 00 01 00
[00:00:05.434] EVT <= 6E 00
[00:00:05.436] EVT <= 78 02 41 00
[00:00:05.440] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.447] EVT <= 6E 00
[00:00:05.450] EVT <= 78 02 41 00
[00:00:05.453] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.460] EVT <= 6E 00
[00:00:05.463] EVT <= 78 02 41 00
[00:00:05.466] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.474] EVT <= 6E 00
[00:00:05.476] EVT <= 78 02 41 00
[00:00:05.479] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.487] EVT <= 6E 00
[00:00:05.490] EVT <= 78 02 41 00
[00:00:05.493] ACL => 80 00 11 00 0D 00 42 00 A1 3F 00 00 08 00 80 00 80 00 80 00 80
[00:00:05.500] EVT <= 1B 03 80 00 05
[00:00:05.504] ACL <= 80 20 0C 00 08 00 01 00 06 08 04 00 41 00 42 00
[00:00:05.510] LOG -- l2cap.c.2550: L2CAP signaling handler code 6, state 12
[00:00:05.517] EVT <= 13 05 01 80 00 01 00
[00:00:05.521] EVT <= 6E 00
[00:00:05.523] ACL => 80 00 0C 00 08 00 01 00 07 08 04 00 41 00 42 00
[00:00:05.529] LOG -- l2cap.c.933: L2CAP_EVENT_CHANNEL_CLOSED local_cid 0x41
[00:00:05.536] EVT <= 71 02 41 00
[00:00:05.539] LOG -- l2cap.c.1100: l2cap_stop_rtx for local cid 0x41
[00:00:05.545] EVT <= 6E 00
[00:00:05.548] CMD => 35 0C 05 01 80 00 06 00
[00:00:05.552] EVT <= 6E 00
[00:00:05.556] ACL <= 80 20 0C 00 08 00 01 00 06 09 04 00 40 00 43 00
[00:00:05.561] LOG -- l2cap.c.2550: L2CAP signaling handler code 6, state 12
[00:00:05.568] ACL => 80 00 0C 00 08 00 01 00 07 09 04 00 40 00 43 00
[00:00:05.574] LOG -- l2cap.c.933: L2CAP_EVENT_CHANNEL_CLOSED local_cid 0x40
[00:00:05.581] EVT <= 71 02 40 00
Hid disconnected
[00:00:05.586] LOG -- btgamepad.c.182: HID Disconnected
@NathanReeves

This comment has been minimized.

Copy link

@NathanReeves NathanReeves commented Apr 18, 2019

@fluffymadness
Hey,
The reports you’re sending should work. Make sure your devices name is either Pro Controller, Joy-Con(R) or Joy-Con(L)
The timeout/rejection from the switch looks exactly like what I’m getting every time...

For anyone following the ESP32, I’m switching hardware to the cc256x to see if it’s a hardware specific problem. ESP32 has some limited Bluetooth features, you can’t set the MAC address for example.

@fluffymadness

This comment has been minimized.

Copy link

@fluffymadness fluffymadness commented Apr 18, 2019

you can set the mac on esp32.

#include "esp_system.h"
uint8_t mac[] = {0x98, 0xB6, 0xE9, 0x43, 0x26, 0xCC};
esp_base_mac_addr_set(mac);

@fluffymadness

This comment has been minimized.

Copy link

@fluffymadness fluffymadness commented Apr 18, 2019

my device name is pro controller hmmm.
do I need additional sdp entries beside that one?
hid_create_sdp_record(hid_service_buffer, 0x10000, 0x2508, 0, 0, 0, 0, reportMap, sizeof(reportMap), service_name);

Also I have no log entry of hid interrupt anywhere...maybe that is an additional problem?

edit: Is a correct hid report map needed? I sent the one from usb, which is probably wrong for bt.
( i truncated the garbage entries after the last button report)

edit2: My logs look kinda identical, but I never get a 0x02 request command from the switch
that you have

@NathanReeves

This comment has been minimized.

Copy link

@NathanReeves NathanReeves commented Apr 18, 2019

Oh I thought the MAC was burned into the eFuse but it does look like you can set a custom one, I’ll check that out, thank you

Yeah you should make sure your sdp record contains the HID interrupt/control channels.
I’ll post my code tonight

@fluffymadness

This comment has been minimized.

Copy link

@fluffymadness fluffymadness commented Apr 18, 2019

Thank you :)

@fluffymadness

This comment has been minimized.

Copy link

@fluffymadness fluffymadness commented Apr 18, 2019

Maybe we can somehow work on this together. I already have custom code for a switch fightstick on my repositiory. Getting something similar working via bluetooth would be great.

@fluffymadness

This comment has been minimized.

Copy link

@fluffymadness fluffymadness commented Apr 18, 2019

Another thing. If you are trying out code for esp32 again, be sure to be on the develop branch of btstack and have the newest esp-idf commit from master. Btstack master is broken.
See bluekitchen/btstack#202

@NathanReeves

This comment has been minimized.

Copy link

@NathanReeves NathanReeves commented Apr 18, 2019

I’m down, I’d love to get some open source code going

https://discord.gg/ef5AxG
I created a discord for joycon spoofing if anyone wants to get into this issue

@Ced2911

This comment has been minimized.

Copy link

@Ced2911 Ced2911 commented May 15, 2019

Has anyone tried to emulate 1 joycon over usb ? it should be possible to use the bt hid descriptor over usb ? subcommand should be emuled ?

@mattrcampbell

This comment has been minimized.

Copy link

@mattrcampbell mattrcampbell commented May 17, 2019

I attempting to add support for the joycon to the USB_Host_Shield_2.0 library. Forgive me if I have just missed it, but am I correct in my understanding that we have not yet figured out how to do a SYNC with a brand new out of the box pair of joycons using JUST bluetooth? Or am I missing something?

@Ced2911

This comment has been minimized.

Copy link

@Ced2911 Ced2911 commented May 25, 2019

Hi, i'm trying to emulate a pro controller over usb, but no input on the switch side.
Swich request in loop the device info
Do someone know what is wrong ?
https://pastebin.com/qX55jGm5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.