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

Feature: Amiibo NFC reading support #89

Closed
wants to merge 41 commits into from
Closed

Conversation

Poohl
Copy link

@Poohl Poohl commented Dec 9, 2020

This mainly implements enough of the NFC functionality to simulate amiibos for reading. The implementations core is in mcu.py, but this is not some rewrite of the old copyrighted code.

There are still some hacks in detecting and storing the tag but it seems stable om my end.

This is currently only tested using Splatoon2 and Pro-Controller on my laptop (Acer spin 5) using PopOS based on Ubuntu 20.04 running bluez 5.53-0ubuntu3

my command to test this:

python3 run_controller_cli.py -d hci0 -r --nfc PRO_CONTROLLER

And it successfully transmits the amiibos data and wants me to register a user.

TODO:

  • more MCU-functionallity
  • NFC-Write
  • validate right Joycon working
  • validate registered Amiibo working

Other changes in the merge:

  • removed this reader injection into transport
  • added "click" command
  • partially fixed the input-speed-change improving latency
  • some documentation on how it works

@mart1nro
Copy link
Owner

Thanks, I'm going to test this as soon as I have the time.

Btw, besides the first google search result, MCU stands for microcontroller unit (https://en.wikipedia.org/wiki/Microcontroller) :)

@Poohl
Copy link
Author

Poohl commented Jan 31, 2021

Sorry for the delay, but thanks I'll change the name.

I checked BOTW myself and since this for some reason doesn't require you to register a owner it seems to just work.

I also noticed that #90 also includes a fix for the flow control problem that seems to work better than mine, I can try to integrate that one or would you want to?

@DarkPro1337
Copy link

Not worked on my Switch Lite, putted in nfc command a regular amiibo for BoTW and nothing happens on the amiibo adding to mii screen, and these two lines spam in the terminal.
JoyControl was hosted on the Raspberry Pi 4B with latest Raspbian OS.
image

@Poohl
Copy link
Author

Poohl commented Mar 18, 2021

@DarkPro1337 Two things: First I assume you are on the 'register owner and name' screen in the settings, that sadly isn't working yet but you don't even need it, as botw works with unregistered amiibos.

Second the 'not implemented length' means just that, the nfc tag you passed is not of the expected size. This might be an issue in the code (I'll check, I have a few commits only local but they should be unrelated), but please check that the file you use is exactly 540 bytes, anything else is not an amiibo. If you have another size you might have the decrypted version exported by tagmo or some format with the image embedded or UID stripped. This implementation needs the raw binary image that would be stored on the NFC tag.

The 'set NFC tag data' is just telling you it picked up on the tag you set.

@DarkPro1337
Copy link

@Poohl oh, thanks, I'll try to check these amiibo dumps later. Maybe they are just corrupted due the archivation.

But just sending amiibos on the botw screen also does nothing (amiibos was enabled).

@Poohl
Copy link
Author

Poohl commented Mar 18, 2021

I assume you have the Amiibo rune active. Does the terminal view that the Switch requested 0x31 Input mode? The Expected sequence of events is
0. open the rune

  1. switch requests 0x31 mode
  2. switch configures NFC (0x21 command)
  3. switch starts and stopps polling a few times
  4. switch requests the tag be read
  5. tag is send back

@Poohl Poohl mentioned this pull request Mar 21, 2021
@thxomas
Copy link

thxomas commented Apr 5, 2021

@Poohl thanks for your work.
I tried to use an amiibo in Botw and got the same length errors. I hacked a little further and noticed that the zelda game sends a 572 bytes payload instead of 540.
I just changed the code to let it continue and the game worked as expected ! I dumped the data payload ( botw_nfc_data.bin.log )
Keep up !

@Poohl
Copy link
Author

Poohl commented Apr 5, 2021

@thxomas are you on the amiibo_edits branch? Did you use multiple amiibos in a single run of joycontrol? And regardless, what was your fix?

I know of a few length issues on the amiibo_writing branch, but i thought the other one was fixed...

@thxomas
Copy link

thxomas commented Apr 6, 2021

Oh, I notice now, I used your fork, not a branch from this project. (I'm not really confident with git yet)
The fix was quick and dirty : I just commented out the "return" instruction after length check in mcu.py
And yes, multiple amiibos in the same session worked the same way.

I will try again with the amiibo_writing branch and report.

EDIT: Yes, I was previously on amiibo_edits branch. and I'm having more lowlevel issues with the amiibo_writing branch ATM (connection from switch doesn't work, I have to use the reconnect option, and as soon as I leave the Grip screen I get No data received/Connection Lost). I'd be happy to help in DM if you want/need.

@Poohl
Copy link
Author

Poohl commented Apr 6, 2021

The amiibo_edits branch i would consider more stable than amiibo_writing, the second still has a bunch of dirty hacks that make the register owner work, but nohing else yet. (Both of them are only in my fork, this is the thread to merge them into mart1nro's project)

Regarding low level issues: look at the reset and restart Bluetooth scrips in amiibo_writing/scrips most notably the folder in /var/<bluetooth_or_so_not_sure> mentioned likes to corrupt.

Ps: are there dms on GitHub or are you talking of another platform? Help is always appreciated.

@choss
Copy link

choss commented Apr 7, 2021

@Poohl thanks for your work.
I tried to use an amiibo in Botw and got the same length errors. I hacked a little further and noticed that the zelda game sends a 572 bytes payload instead of 540.
I just changed the code to let it continue and the game worked as expected ! I dumped the data payload ( botw_nfc_data.bin.log )
Keep up !

The Mismatch in payload size is easily explainable:

  • An amiibo is 540 bytes long as "user" payload
  • The other bytes are additional non writable information from factory (signature of the manufactorer)
  • BotW sends the whole tag, the last 32 byte can be safely ignored

https://gbatemp.net/threads/making-amiibo-ntag215s.413050/page-37
https://www.nxp.com/docs/en/data-sheet/NTAG213_215_216.pdf (section 8.9)

@Poohl
Copy link
Author

Poohl commented Apr 15, 2021

@choss So what you're saying is there is additional data at the NFC-tags end?
I couldn't find it (my nfc-dump app produces 540 bytes when dumping a Link-Archer amiibo) or anywhere that it's used. I can however assure you that BOTW does not send the entire tag (or at least not care if you don't), since the line responsible cuts off at 540:

self.nfc_tag_data[245:540]

I'll update the NFC-tag loader to accept these longer tags. Are they always 572 bytes long?

@choss
Copy link

choss commented Apr 15, 2021

Yes as far as I can tell from the spec it is always 572 bytes long. So it should be fine :) The last bytes are anyway only the vendor signature and "static"

Poohl added 19 commits April 15, 2021 19:23
Huge thanks to @thxomas for the POC and
@JaredEzz for resources on how to get it working on my hardware
- change_btaddr now accepts a optional argument as the mac to set it to
- change_btaddr has some doc how to get it working
- remote_capture now works without sudo by default
- hcimon: example script how to capture HCI messages
- mount: example how to easily develop remotely (not on a raspi)
- transport not accepts an optional flow-control argument to prevent insane lag
- refactored protocoll.py
- now ues realtime instead of just bumping timer on every call
- centrallized handling of report creation
- Manual workaround for V12 disconnects
  * Flow Control
  * pause & unpause commands to go to interrupt mode
  * automated mashing on pairing screen
- Automated BT_addr change
- "-r auto" to reconnect to a paired switch
- warnings when connecting with weird settings
- transport now always has write_lock
- changed naming to be similar to asyncio.Transport
- Refactored outgoing flow control to conform to asyncio.Transport
- disabled outgoing flow control by default
- made user prompts silenced by default
- removed anticipate mechnism
- removed anticipate command
@Poohl
Copy link
Author

Poohl commented May 11, 2021

I will create a new Pull request with updated info for everything. Will edit the comment to contain a link.
It's Pull request #110 .

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.

None yet

5 participants