dekuNukem / Nintendo_Switch_Reverse_Engineering

A look at inner workings of Joycon and Nintendo Switch
3.47k stars 193 forks source link

Is it possible to listen for packets sent from controller to switch in realtime (during play)? #98

Open dnck opened 4 years ago

dnck commented 4 years ago

Hey, great repo! I'm just beginning to look around , and I thought perhaps someone could point me in the right direction for my goal: I want to build a application that listens for button presses during Switch gameplay, and in response to detected key matches, triggers a Phillip hue hub to change its controlled light states. Think: press the shoot button, and the room lights flash white.

Yamakaky commented 3 years ago

Did you find a way to do this?

Setitch commented 3 years ago

Im also interested, i have got nrf51 dongle but im not sure what to do to be able to hear all switch traffic

Yamakaky commented 3 years ago

Seems hard to do, cf https://github.com/greatscottgadgets/ubertooth/issues/433#issuecomment-754150425

Poohl commented 3 years ago

Hey, is is kindof possible by using a proxy, but that introduces a slight amount of lag.

You can proxy the bluetooth fully, that is capure all traffic via bluetooth and send it via bluetooth again. You might however run up against the limits of a single Bluetooth chip (read, you might need two and a way to control them independently or use a wire of some sort for one connection).

On my Laptop only one Joycon can be captured like this at a time and no Heavy data throughput like NFC, IR work reliably. Also the Pro Controller is sadly completely of limits for me, as it sends 2-4 times the amount of data from a single joycon.

See https://github.com/mart1nro/joycontrol/blob/master/scripts/relay_joycon.py for a full proxy script or if you already have your Proxy registered as a Controller in the Switch you can just use something like

def connect_client_to_sw(bt_addr):
    print("waiting for switch")
    ctl_psm = 17
    itr_psm = 19
    client_ctl = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
    client_itr = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
    client_ctl.connect((bt_addr, ctl_psm))
    client_itr.connect((bt_addr, itr_psm))
    print("connected to sw")
    return client_ctl, client_itr

To connect to Switch and Joycon and send any incoming traffic back out the other side.

Yamakaky commented 3 years ago

Wow, very interesting! What setup do you have then? One bluetooth only?

Poohl commented 3 years ago

Yes, I am currently using simply the bluetooth built into my laptop for both connections: switch <-> laptop <-> joycon.

That's why I also have no experience with setting this up with two cards. You would have to tell Pythons socket api which interface to use or use bluez's api directly.

Yamakaky commented 3 years ago

OMG it works!!! I don't have time to work on that right now, but expect news from me next week!

Setitch commented 3 years ago

Thats great, and can you tell me exactly what to do to be able to listen to them?

Yamakaky commented 3 years ago

I captured some traces here: https://github.com/Yamakaky/joy/tree/master/trace

Poohl commented 3 years ago

hey @Yamakaky , have you tried anything NFC yet? If so any logs would be greatly appreciated.

Also: Do you know of any easy method to import these logs into Wireshark?

Yamakaky commented 3 years ago

NFC: haven't tried it yet, though my software handles the IR camera. I need to get some NFC tags, put amibo data and import it in a game.

Wireshark: I don't think so, but you can record it live with wireshark. I can record a specific trace if you don't have a ringcon.

Poohl commented 3 years ago

Ok, did the IR work? If so it seems your bluetooth might be able to handle the additional load, so any actually working captures of writes would be appreciated.

And regarding ringcon: I'm not intrested in the Ringcon itself, more in anything involving the MCU, as it seems there is a MCU-protocol layer inside these reports and depending on the service another one layer inside this MCU protocol. If I can figure out the MCU protocol I could narrow any problems down to the service specific stuff.

Yamakaky commented 3 years ago

Do you know an easy way to generate IR traffic? There are very few games that use it, and I can't find a way to use the heartrate feature in RingFit on demand.

Poohl commented 3 years ago

The only games I know of (don't own them) are 12Switch (the eating one) and Labo (e.g. piano)

Yamakaky commented 3 years ago

Well, normal gameplay works fine, but the capture script crashes in loop when using the IR for heart pulse measuring XD

Poohl commented 3 years ago

That seems like the buffer overflows or something. Looking at your code https://github.com/Yamakaky/joycontrol/blob/capture-text-file/scripts/relay_joycon.py: In line 35 input seems to be forwarded in chunks of 100b, but in mode 0x31 input packets are 313 bytes in size and cannot be fragmeted as far as I know.

Yamakaky commented 3 years ago

OK, so with a bigger size it still crashes, but a lot less. I managed to capture the pulse measuring: https://github.com/Yamakaky/joy/blob/master/trace/ringfit-session-with-ir.log