Nintendo_Switch_Reverse_Engineering icon indicating copy to clipboard operation
Nintendo_Switch_Reverse_Engineering copied to clipboard

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

Open dnck opened this issue 4 years ago • 17 comments

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.

dnck avatar Apr 11 '20 10:04 dnck

Did you find a way to do this?

Yamakaky avatar Jan 04 '21 16:01 Yamakaky

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

Setitch avatar Jan 21 '21 20:01 Setitch

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

Yamakaky avatar Jan 23 '21 11:01 Yamakaky

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.

Poohl avatar Feb 01 '21 11:02 Poohl

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

Yamakaky avatar Feb 01 '21 19:02 Yamakaky

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.

Poohl avatar Feb 02 '21 00:02 Poohl

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

Yamakaky avatar Feb 04 '21 19:02 Yamakaky

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

Setitch avatar Feb 04 '21 22:02 Setitch

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

Yamakaky avatar Feb 07 '21 15:02 Yamakaky

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?

Poohl avatar Feb 08 '21 19:02 Poohl

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.

Yamakaky avatar Feb 08 '21 20:02 Yamakaky

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.

Poohl avatar Feb 08 '21 20:02 Poohl

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.

Yamakaky avatar Feb 08 '21 21:02 Yamakaky

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

Poohl avatar Feb 08 '21 21:02 Poohl

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

Yamakaky avatar Feb 09 '21 14:02 Yamakaky

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.

Poohl avatar Feb 09 '21 15:02 Poohl

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

Yamakaky avatar Feb 09 '21 15:02 Yamakaky