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

V12 compatability and Amiibo-NFC support. #110

Open
wants to merge 47 commits into
base: master
Choose a base branch
from

Conversation

Poohl
Copy link

@Poohl Poohl commented May 11, 2021

Overview

This pull request is a combination of my 2 previous ones (#102 and #89), as it was built on top of those and also also has the fixes necessary to work with switchOS V12+ (tested on V12.0.1).

Switch V12 support

This closes #104, potentially #93. It also includes optional flow-control (disabled by default) thus presumably can replace #90.
To make all this happen HCI sockets were used, potentially hindering porting efforts to other systems.
It also makes heavy use of more system-commands to change the MAC-address, which however might not be necessary with the other fixes, according to some new testing.

NFC for Amiibos.

As stated this pull includes #89 and #102. It includes reading amiibos and registering owners. Arbitrary writing is not working yet and the solution to get out of the "writing" screen again is quite hacky but works, but not with anything but registering owners. For this the old --nfc option and the nfc command were reused.
This closes #82 and #77.
The implementation is also not based on joycondroid, thus should not have the issue as in #80 again.

Misc features

  • the click BTN command clicks BTN once. Useful for navigating menus from the cli.
  • the pause and unpause commands disable and enable the input-writer and thus make the controller act more like interrupt mode. This can be useful, as the switch doesn't disconect you for 10s when silent but may if some response is wrong/unexpected. In this mode only buttons work.
  • the debug X command to set the input frequency to XHz. This is intended to be removed, but for now is still very useful to get rid of running too slow problems.

Credit

Special thanks to @thxomas for a V12 POC, @JaredEzz for clarifying it and @Yamakaky for improving the debug scripts.
Also thanks to everyone who helped with debugging to get here.

TODO / Issues

  • after pairing the input frequency is stuck at 15Hz
  • documentation
  • unclean shutdown, as an additional 3 asyncio-threads just die
  • Enable flow control by default.
  • the 6-Axis data is a mess and causes e.g. splatoon2 camera to spin eradically

This was referenced May 11, 2021
@d-lindahl
Copy link

d-lindahl commented May 13, 2021

Tested with the latest 12.0.2 firmware. Controller (Pro controller) connects reliably (ASUS BT-400). Also tested the NFC spoofing, working flawlessly in Animal Crossing New Horizons 👍

@munichi-jasuda
Copy link

Tested with the latest 12.0.2 firmware. Controller (Pro controller) connects reliably (ASUS BT-400). Also tested the NFC spoofing, working flawlessly in Animal Crossing New Horizons 👍

Cheers! Can I get a link to which version of JoyControl you used?

Also I have a few questions.

Did you make changes to ExecStart parameters in bluetooth.service, MAC address using change_btaddr.sh, and device class using sudo hciconfig hci0 class 0x2508? Is the device class listed as 0x2508 when you run sudo bluetoothctl show in the terminal?

@d-lindahl
Copy link

d-lindahl commented May 14, 2021

Tested with the latest 12.0.2 firmware. Controller (Pro controller) connects reliably (ASUS BT-400). Also tested the NFC spoofing, working flawlessly in Animal Crossing New Horizons 👍

Cheers! Can I get a link to which version of JoyControl you used?

Also I have a few questions.

Did you make changes to ExecStart parameters in bluetooth.service, MAC address using change_btaddr.sh, and device class using sudo hciconfig hci0 class 0x2508? Is the device class listed as 0x2508 when you run sudo bluetoothctl show in the terminal?

  • I used the fork that this PR is about: https://github.com/Poohl/joycontrol/tree/amiibo_edits
  • ExecStart=/usr/lib/bluetooth/bluetoothd -C -P sap,input,avrcp - according to Cursed Bluetooth Hardware Poohl/joycontrol#4
  • Joycontrol changes the class automatically to 0x2508 (Verified while running)
  • MAC not changed, checked mine and it was 5C:F3:70:9A:F6:84 while running (this seems to be a thing for the BT-400 that it works no matter what MAC for reasons)
  • Only works when no controllers connected (even physically) but that seems to always be a thing.

@munichi-jasuda
Copy link

munichi-jasuda commented May 14, 2021

@Poohl @d-lindahl

I tried this version, but it seems to disconnect when a second input is provided through the terminal.

There is a way to work around the disconnect though. I close the Change Grip/Order menu manually using the Switch's touch-screen and navigate to the home menu. Then I input "test_buttons" command through the VM terminal, after which the Switch will no longer disconnect when additional button inputs are provided through the terminal.

Sadly, reading Amiibo still gives the same error (2115-0064) and immediately disconnects.

Additional information: ExecStart changed, MAC not changed, device class not changed manually and was not changed automatically even after connecting with the Switch, tried with both JoyCons detached and JoyCons attached.

@Poohl
Copy link
Author

Poohl commented May 14, 2021

@munichi-jasuda The Amiibo read error is known, yet we don't know where it comes from. The only pattern we have is the unchanged class (see Poohl#5).

Try to change it manually and see if that helps.
Also have you tried reconnection? (the -r option) after it was paired? There is a known issue with input-frequency stuck at 15Hz after pairing from the change grip/order menu.
You can also try to set the frequency manually using the debug command (see Misc Features at the top). Frequency should be 60 Hz for Joycons, 120 for Pro Controller. But usually 60 just works for everything.

@munichi-jasuda
Copy link

Ok, this will be pretty long since I will try to explain different scenarios I encountered and how I worked my way around them when connecting to Switch and reading NFC bins.

Firstly, my Switch is updated to 12.0.2v and I was able to connect to JoyControl even with JoyCons attached. One thing to note is that I had connected JoyControl with my Switch before the 12.0.0 update, so it's possible that may have helped reconnect, but I'm not sure. Another thing to note is that that the method I've used to get JoyControl to work may not work for everyone. A different user (@d-lindahl) got JoyControl to work as well, but they used a different method which did not work for me. Hence, it's quite random and not guaranteed to work for everyone sadly.

VERY IMPORTANT: I was suggested to use the -r command of the JoyControl to connect to my Switch but it gave me Error (2113-3204), forcing me to switch off my system. Make sure you save beforehand, and also try this at your own risk.

Let's get started. First, you'll need to download this version of JoyControl (by @Poohl). Follow the instructions to complete installation and setting up.

Next, you'll need to make changes to a system file (located in /lib/systemd/system/bluetooth.service of your VM Ubuntu system). Instructions are provided on the download page, but you'll need permission to make those changes, and I also recommend creating a backup of the file (bluetooth.service). Run the code sudo chown -R your_username:your_group_name /lib/systemd/system/bluetooth.service (sample example: sudo chown abc:abc /lib/systemd/system/bluetooth.service, where abc is your username, and generally the group name is same as your username) to grant permission.

Changing your MAC address may not be necessary; I didn't need to do that.

Once you change the ExecStart parameters in the bluetooth.service file, open the terminal and run the command cd ~/joycontrol, make sure you are in the Change Grip/Order menu of your Switch, and follow-up with sudo python3 ./run_controller_cli.py PRO CONTROLLER. You can open the bluetooth menu (at the top-right menu bar) of Ubuntu to check if your Switch is visible, and also select it manually. This is usually how I connect my Switch to JoyControl. At this point, it's just random. Your Switch may connect or it won't. There's nothing else you can do in this step but keep trying.

If the connection was established, you can proceed to the next step. Otherwise, you'll probably just have to wait until someone else figures out a different method to successfully connect.

Next, you can either input a in the terminal to close the Change Grip/Order menu or do it manually. If your Switch disconnects immediately when a second input is provided, you should instead navigate to the home menu manually using the Switch's touchscreen and input test_buttons command in the terminal. This was quite random, and that's how I work my way around if my Switch disconnects when more than 1 input is provided through the terminal. The test_buttons command will automatically navigate to controller settings and input different buttons to test them. Once you feel like all inputs have been tested, you can press enter in the terminal to stop testing. If your Switch still disconnects when additional commands are given through the terminal, then your only option is to keep trying.

You can also try running the command debug 60 in the terminal when JoyControl connects successfully, then run a to close the menu. As always, if it didn't work, your only option is to keep trying.

When in-game, try running the command debug 120. It feels like the Error 2115-0064 is connected to this command. I would get this error (or nothing will be read) if I tried reading NFC without running debug 120 in the VM terminal.

Finally, it's time to test if you can read Amiibo using JoyControl. Remember to run the nfc command before the reading actually begins to set the nfc data, and then proceed to reading the Amiibo. (for example, if you're reading Amiibo in ACNH, the game will inform you to prepare the Amiibo; this is when you should run the nfc command, and then continue to the reading) If you still get Error 2115-0064, you can keep trying. Sometimes, it works flawlessly, sometimes it'll work after a few tries. There's no guarantee if it'll work for everyone or if it'll work at all.

That's probably it from me. Please note that this is what I tried to get JoyControl to work with my Switch. The way it works is quite random, and hence may not work for everyone.

@Poohl
Copy link
Author

Poohl commented May 16, 2021

@munichi-jasuda Thanks for the detailed report. I'll work it into the README. Only one question: what brand/type bluetooth controller are you using?
I've never encountered the 2113-3204 error yet and am starting to suspect it might be some hardware thing.

Edit: I thought they were the same. The module 113 is the bluetooth, meaning there is some big vulnerability in the bluetooth stack itself. This is probably related to what joycontrol is doing but I'd guess Nintendo will patch this sooner than later.
I also never had 2115-0064 but the code makes a bit more sense: the NFC module (115) is complaining that the device isn't available.
I in general only crashed my switch once (seemed random, didn't note error code).

@munichi-jasuda
Copy link

@munichi-jasuda Thanks for the detailed report. I'll work it into the README. Only one question: what brand/type bluetooth controller are you using?
I've never encountered the 2113-3204 error yet and am starting to suspect it might be some hardware thing.

Edit: I thought they were the same. The module 113 is the bluetooth, meaning there is some big vulnerability in the bluetooth stack itself. This is probably related to what joycontrol is doing but I'd guess Nintendo will patch this sooner than later.
I also never had 2115-0064 but the code makes a bit more sense: the NFC module (115) is complaining that the device isn't available.
I in general only crashed my switch once (seemed random, didn't note error code).

You might be right about the issue being related to Bluetooth hardware.

I don't know how to check what brand/type my Bluetooth controller is (my device is Acer); seems like it is Qualcomm Atheros since I can't find anything else in my Bluetooth settings.

The other user reported being able to get -r to work for ASUS BT-400. Trying that command on mine keeps giving me Error 2113-3204.

Also, I didn't encounter Error 2115-0064 once I ran debug 120 command in the VM terminal. Trying to read Amiibo without running debug 120 command (even if debug 60 was executed before) would always give Error 2115-0064.

@Poohl
Copy link
Author

Poohl commented May 17, 2021

@munichi-jasuda You are in luck: I also have an acer laptop with qualcomm atheros bluetooth and will try to get it working today (ubuntu 20.04). Will keep this thread posted and try to reproduce these issues (I usually test on a raspi 4B). If this is some hardware problem caused by the controller that is simulating, I should be able to see some difference in the bluetooth controller captures between the raspi and the qualcomm.

Update: I can't get it to work. It paired once and kicked me after the second button-press but other than that it just instantly axes the connection. I'm suspecting the SDP shit, as BlueZ gives no fuck about what I tell it. Even manually deleting them from the database doesn't remove them so I'm stuck with 4-7 of them and anything above 3 is known to not work...

@Poohl
Copy link
Author

Poohl commented May 17, 2021

Update 2: I'm very sorry, but after 4 Hrs of testing I declare ubuntu 20.04 (i don't think this is a hardware issue, might be mistaken) a lost cause. Reasons for all the problems:

  • BlueZ's D-bus API constantly crashes. (resulting in Poohl #6)
  • BlueZ won't stop advertising random SDP-records (I have a very persistent "Headset" feature)
  • Ubuntu detects the Switch as Speaker and tries to connect to it, causing all sorts of problems.
  • Ubuntu rf-kills bluetooth sometimes for no good reason
  • Ubuntu really hates it when you yourself mess with the bluetooth-daemon (insert a image where bluetooth is off, reports remote devices and can be turned off at the same time here. Can't do that because nothing short of Gimp can edit images on linux...)

What I tried:

  • installed dependencies
  • modified /lib/systemd/system/bluetooth.service
  • restarted bluetooth
  • reboot
  • delete sdp records using sdptool records local and sdp del <rec_handle> (requires the -C option to bluetoothd)
  • disable all bluez plugins
  • pair
  • reconnect

So if anyone wants to try with 19.10 again... or you could try to prevent ubuntu's shit from ever accessing bluetooth, no idea on how to do that though.

@munichi-jasuda
Copy link

munichi-jasuda commented May 18, 2021

@Poohl

It paired once and kicked me after the second button-press

I used to encounter the same issue, but I work around it by manually navigating to the Switch's home menu using the touchscreen, and executing the command test_buttons in the VM terminal. Once the command automatically tests all inputs, I was able to secure the connection and successfully input additional commands in the VM terminal. Don't know if it'll work for you sadly, since it's very random. Have you tried doing this?

Another way of working through it is to enter the command debug 60 once JoyControl has paired with the Switch, and then follow-up with a to close the Change Grip/Order menu.

I am using Ubuntu 20.04.2 LTS by the way.

Also, I only installed dependencies and made changes to bluetooth.service file in /lib/systemd/system/ and directly got started with pairing to my Switch using the commands cd ~/joycontrol and sudo python3 ./run_controller_cli.py PRO CONTROLLER

Edit:

This is how I manage to connect to my Switch and read NFC flawlessly.

Pre-requisites: Install dependencies (sudo apt install python3-dbus libhidapi-hidraw0 libbluetooth-dev bluez and sudo pip3 install aioconsole hid crc8) and change ExecStart parameters in /lib/systemd/system/bluetooth.service

  1. run cd ~/joycontrol

  2. run sudo python3 ./run_controller_cli.py PRO CONTROLLER

  3. You will be prompted to input password and further asked if you wish to unpair connection with the Switch (if connected previously, since mine was even before the 12.0.0 update); enter n to keep your Switch paired if it was connected before

  4. While the VM terminal waits for establishing connection with Switch, I navigate to the Bluetooth drop-down on top-right, and select "Set Up A New Device", and select the Nintendo Switch from the menu

  5. At this point, if JoyControl fails to connect with the Switch, I just use the button combination "Ctrl+C" to terminate the process, and start over from step 2. Otherwise, I proceed to step 6.

  6. When JoyControl successfully connects with the Switch, you will be able to input button commands through the VM terminal. Usually, pressing a will give out "writer exited' error (meaning I can't input any more commands), which just terminates the connection. Instead, I enter debug 60, which will give out many warnings (ignore them). Then, I input a. (Optional: If your Switch keeps disconnecting with JoyControl, try navigating to the Switch's home menu manually using the touchscreen and input test_buttons through the VM terminal. Once all buttons are tested and you can successfully input additional commands, proceed to step 8, otherwise start over from step 2).

  7. If the Switch still disconnects when additional commands are input through the VM terminal, then start over from step 2. Another thing you could try is skipping step 6 and go for step 6 (Optional). If your Switch no longer disconnects and accepts additional commands through VM terminal proceed to step 8.

  8. Get back into the game, and run debug 120 through VM terminal. (Why? Trying to read Amiibo without running this command always gave me Error 2115-0064)

  9. Read Amiibo. Make sure you prepare the NFC (nfc command) before the reading process actually begins. I have attached a screenshot that shows what the VM terminal looks like when successfully reading Amiibo. If your Switch still displays Error 2115-0064, your best bet is to keep trying (start over from step 2).

Reading Amiibo success:

joycontrol success

joycontrol success isabelle

@Luminger
Copy link

Thanks for the PR! I was able to successfully use this on a Raspberry Pi 3 v1.2 on the latest Raspian. IIRC the controller state seems to be a bit wonky sometimes, but once it's paired and I've used the emulated Pro Controller for inputs in the game, the NFC stuff worked fine.

As a sidenote: The generated Amiibo dumps didn't cut it for me, they were rejected by the game I've tested. I guess that's what supposed to happen, but as I didn't saw the info anywhere: It seems that you need the Amiibos in encrypted form to make this work (which does make sense IMHO as the encryption is most probably done by the Switch and not the controller/reader itself).

Anyhow, everybody's work here is much appreciated!

@@ -1,60 +1,120 @@
# joycontrol

Branch: master->amiibo_edits

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to leave this in the readme for the PR?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's just there because ppl got confused with what Readme is up to date for what branch.
Just tell me and I'll remove it.

@ChristinMilloy
Copy link

I want to thank you for making this effort, because like you I want the NFC support very badly. I ran this on my Xubuntu VM (on which the main branch runs bluetooth flawlessly using a USB dongle), and I'm sorry to say that on your branch I'm consistently getting "address already in use." I think this is a known issue. Please let me know if there are other ways I can help you by testing. I do not have raspberry pi at the moment.

@Poohl
Copy link
Author

Poohl commented May 29, 2021

@ChristinMilloy there are two ways this can happen: plugins (probably input) being enabled (the restart-bluez workaround is not updated) or you restarted joycontrol to quickly (when the disconnect fails the kernel keeps the connection lingering to make sure the other end actually closed it). This can take up to 10s for the socket to actually close and the address to become usable again.
Also @munichi-jasuda Sorry for the long wait, was busy. But I still can't get my Ubuntu to connect. (tried to exit the menu by touchscreen, attached joycon, detached joycon). I also tried while already paired, but reconnecting just fails. I'll try with another BT adapter and if i can get your new-device method working the next few days. For now glad it works for you remains to be seen if we can get this consistent at some point.

@ChristinMilloy
Copy link

Thanks Poohl, scratch my last comment, it worked on Xubuntu once I took your advice and disabled input plugins. In fact I had an easier time connecting than on mart1nro master. However I am getting the connection drop on nfc transmit. I am going to follow more of the suggestions from Poohl issue 4 and report back.

@ChristinMilloy
Copy link

Disregard that, I forgot ending quote. Now everything is working, I am able to read a bin file in ("added nfc content") but the game does not respond to it even though the button inputs are still working.

@Poohl
Copy link
Author

Poohl commented May 31, 2021

@ChristinMilloy Do you get any messages on the terminal/logger? as soon as the read/registration screen is entered, you should get a message stating the MCU was stated and initiallized.

kindfulkirby and others added 2 commits August 20, 2021 08:40
On Raspberry Pi it didn't connect until I ran the HCI command mentioned in issue 4, so it's not just random disconnects.
Also fixed a typo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to connect with Switch update 12.0.0 Add NFC functionality (for amiibos mainly)
6 participants