Difference between revisions of "NFC services"

From Nintendo Switch Brew
Jump to navigation Jump to search
(Improved NFP structs, detailed some NFP commands, detailed amiibo information and structures)
Line 259: Line 259:
 
= nfp services =
 
= nfp services =
  
These are used for amiibo support (nfp = Nintendo Figurine Protocol, internal name for amiibo protocol)
+
These are used for amiibo support (nfp = Nintendo Figurine Protocol, internal name for amiibo protocol).
 +
 
 +
Check [[Error codes]] for result codes that these commands may return on error.
  
 
== nfp:user ==
 
== nfp:user ==
Line 527: Line 529:
 
==== GetAll ====
 
==== GetAll ====
 
Takes an input [[#DeviceHandle]], a type-0x1A output buffer containing [[#NfpData]], no output.
 
Takes an input [[#DeviceHandle]], a type-0x1A output buffer containing [[#NfpData]], no output.
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just converts data from the internal [[#Amiibo settings]] to the output data. The last write date is not validated here (unlike with [[#GetCommonInfo]]).
  
 
==== SetAll ====
 
==== SetAll ====
 
Takes an input [[#DeviceHandle]], a type-0x19 input buffer containing [[#NfpData]], no output.
 
Takes an input [[#DeviceHandle]], a type-0x19 input buffer containing [[#NfpData]], no output.
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just converts data from the input data to the internal [[#Amiibo settings]]. No flushing / writing to the amiibo is done in this command.
  
 
==== FlushDebug ====
 
==== FlushDebug ====
 
Takes an input [[#DeviceHandle]], no output.
 
Takes an input [[#DeviceHandle]], no output.
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0.
  
 
==== BreakTag ====
 
==== BreakTag ====
 
Takes an input [[#DeviceHandle]], an input u32 [[#BreakType]], no output.
 
Takes an input [[#DeviceHandle]], an input u32 [[#BreakType]], no output.
 +
 +
Calls an internal function with the input [[#BreakType]]. This first reads amiibo data (like [[#Mount]] and other commands), then saves the read amiibo in the [[#Backup data]], then depending on the type performs some logic (this changes are thus not saved in the backup), and finally flushes the modified amiibo (writes it to the figurine).
 +
 +
[[#BreakType]] 0 does nothing (it is used as a flushing command, used by many other commands).
 +
 +
[[#BreakType]] 1 breaks the data SHA256 HMAC hash (doing "raw_fmt->data_sha256_hmac_hash[0] ^= 0x80u;", see [[#Amiibo settings]])
 +
 +
[[#BreakType]] 2 sets the amiibo header magic (see [[#Amiibo settings]]) to 0x00 (which beaks the figurine since this magic is checked to be 0xA5 in several places).
  
 
==== ReadBackupData ====
 
==== ReadBackupData ====
 
Takes an input [[#DeviceHandle]], a type-0x6 output buffer, and an output u32 (read_size).
 
Takes an input [[#DeviceHandle]], a type-0x6 output buffer, and an output u32 (read_size).
 +
 +
This reads from the raw [[#Backup data]].
  
 
==== WriteBackupData ====
 
==== WriteBackupData ====
 
Takes an input [[#DeviceHandle]], a type-0x5 input buffer, no output.
 
Takes an input [[#DeviceHandle]], a type-0x5 input buffer, no output.
  
The buffer size must be less or equal than 0x1FBD20.
+
This writes directly to the raw [[#Backup data]]. The buffer size must be less or equal than the backup data size (0x1FBD20).
  
 
==== WriteNtf ====
 
==== WriteNtf ====
Line 558: Line 582:
 
Takes a PID, an [[AM_services|AppletResourceUserId]], an u64 placeholder for the PID, a type-0x5 input buffer containing an array of [[#RequiredMcuVersionData]], no output.
 
Takes a PID, an [[AM_services|AppletResourceUserId]], an u64 placeholder for the PID, a type-0x5 input buffer containing an array of [[#RequiredMcuVersionData]], no output.
  
Internally this is mostly the same for each service, this differs depending on the service/cmd however.
+
Internally this is mostly the same for each service.
 +
 
 +
The input PID is internally used to get the process application ID when needed.
  
 
=== Finalize* ===
 
=== Finalize* ===
 
No input/output.
 
No input/output.
  
Internally this is mostly the same for each service, this differs depending on the service/cmd however.
+
Internally this is mostly the same for each service.
  
 
=== ListDevices ===
 
=== ListDevices ===
Line 580: Line 606:
 
=== Mount ===
 
=== Mount ===
 
Takes an input [[#DeviceHandle]], an input u32 [[#ModelType]] and an input u32 [[#MountTarget]], no output.
 
Takes an input [[#DeviceHandle]], an input u32 [[#ModelType]] and an input u32 [[#MountTarget]], no output.
 +
 +
Creates an internal object that manages mounted amiibo data. This step loads the amiibo [[#Raw format]], saves it in [[#Backup data]], and converts/decrypts it internally into a [[#Plain format]].
  
 
=== Unmount ===
 
=== Unmount ===
 
Takes an input [[#DeviceHandle]], no output.
 
Takes an input [[#DeviceHandle]], no output.
 +
 +
Requires the amiibo to be mounted. Disposes the internal object that manages mounted amiibo data.
  
 
=== OpenApplicationArea ===
 
=== OpenApplicationArea ===
 
Takes an input [[#DeviceHandle]] and an input u32 [[#Access ID]], no output.
 
Takes an input [[#DeviceHandle]] and an input u32 [[#Access ID]], no output.
  
The amiibo must be already using its application area with the input access ID (the game must have already created savedata there). Result 0x10073 will be returned if no application area exists, result 0x13073 will be returned if the application area is currently used with a different access ID.
+
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist (checks the [[#Amiibo flag]]). Just sets an internal flag to 1 if the provided access ID and the application area access ID match.
  
 
=== GetApplicationArea ===
 
=== GetApplicationArea ===
Takes an input [[#DeviceHandle]] and a type-0x6 output buffer, returns an output u32 size.
+
Takes an input [[#DeviceHandle]] and a type-0x6 output [[#Application area]] data buffer, returns an output u32 size.
 +
 
 +
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist and be opened (see [[#OpenApplicationArea]]).
  
 
Reads the buffer data in the application area and returns the size read from the application area.
 
Reads the buffer data in the application area and returns the size read from the application area.
 
 
The application area needs to be opened first.
 
  
 
=== SetApplicationArea ===
 
=== SetApplicationArea ===
Takes an input [[#DeviceHandle]] and a type-0x5 input buffer, no output.
+
Takes an input [[#DeviceHandle]] and a type-0x5 input [[#Application area]] data buffer, no output.
  
Writes the buffer data in the application area.
+
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist and be opened (see [[#OpenApplicationArea]]).
  
The application area needs to be opened first.
+
Writes the buffer data in the application area. The remaining data out of the total 0xD8-bytes is filled with randomly generated bytes.
  
 
=== Flush ===
 
=== Flush ===
 
Takes an input [[#DeviceHandle]], no output.
 
Takes an input [[#DeviceHandle]], no output.
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Performs CRC verifications, updates write counters (see [[#Amiibo settings]]) and then calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0.
  
 
=== Restore ===
 
=== Restore ===
 
Takes an input [[#DeviceHandle]], no output.
 
Takes an input [[#DeviceHandle]], no output.
 +
 +
Reloads amiibo data (same internal functions as [[#Mount]]) and writes the data to the amiibo again. If reading the amiibo fails, it tries to load the [[#Raw data]] from the [[#Backup data]].
  
 
=== CreateApplicationArea ===
 
=== CreateApplicationArea ===
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output.
+
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input [[#Application area]] data buffer, no output.
  
Creates the application area with the input access ID, and writes the buffer data there.
+
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 
 +
Sets the new application ID / access ID values (even if an application area already existed), updates CRC values, updates write counters (see [[#Amiibo settings]]), copies input data, fills remaining space with random bytes, and then calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0.
  
 
=== GetTagInfo ===
 
=== GetTagInfo ===
Line 620: Line 657:
 
=== GetRegisterInfo ===
 
=== GetRegisterInfo ===
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfo]].
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfo]].
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just converts data from the internal [[#Amiibo settings]] to the output info.
  
 
=== GetCommonInfo ===
 
=== GetCommonInfo ===
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#CommonInfo]].
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#CommonInfo]].
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Converts data from the internal [[#Amiibo settings]] to the output info. The last write date is validated, defaulting it to 2000-1-1 if the validation fails.
  
 
=== GetModelInfo ===
 
=== GetModelInfo ===
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#ModelInfo]].
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#ModelInfo]].
 +
 +
Requires the amiibo to be mounted with [[#MountType]] ROM.
 +
 +
Just converts data from the internal [[#Amiibo settings]] to the output info.
  
 
=== AttachActivateEvent ===
 
=== AttachActivateEvent ===
Line 643: Line 692:
 
Takes an input [[#DeviceHandle]], returns an output u32 [[#DeviceState]].
 
Takes an input [[#DeviceHandle]], returns an output u32 [[#DeviceState]].
  
The returned state is loaded from a lookup table. nfp services uses the same table, mifare uses a separate one, and the nfc services use another separate table.
+
The returned state is mapped from the internal state value through lookup tables. nfp services uses the same table, mifare uses a separate one, and the nfc services use another separate table.
  
 
=== GetNpadId ===
 
=== GetNpadId ===
Line 651: Line 700:
 
Takes an input [[#DeviceHandle]], returns an output u32 size.
 
Takes an input [[#DeviceHandle]], returns an output u32 size.
  
Actually returns a hardcoded value of 0xD8.
+
Returns a hardcoded value of 0xD8.
  
 
=== AttachAvailabilityChangeEvent ===
 
=== AttachAvailabilityChangeEvent ===
Line 659: Line 708:
  
 
=== RecreateApplicationArea ===
 
=== RecreateApplicationArea ===
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output.
+
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input [[#Application area]] data buffer, no output.
 +
 
 +
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist and be opened (see [[#OpenApplicationArea]]).
  
Recreates the application area with the input access ID, and writes the buffer data there.
+
Performs the same logic as [[#SetApplicationArea]] but without checking the current access ID, just overwriting it.
  
 
=== Format ===
 
=== Format ===
Line 668: Line 719:
 
=== GetAdminInfo ===
 
=== GetAdminInfo ===
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#AdminInfo]].
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#AdminInfo]].
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just converts data from the internal [[#Amiibo settings]] to the output info.
  
 
=== GetRegisterInfoPrivate ===
 
=== GetRegisterInfoPrivate ===
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfoPrivate]].
 
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfoPrivate]].
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just converts data from the internal [[#Amiibo settings]] to the output info.
  
 
=== SetRegisterInfoPrivate ===
 
=== SetRegisterInfoPrivate ===
 
Takes an input [[#DeviceHandle]] and a type-0x19 input buffer containing a [[#RegisterInfoPrivate]].
 
Takes an input [[#DeviceHandle]] and a type-0x19 input buffer containing a [[#RegisterInfoPrivate]].
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just converts data from the input info to the internal [[#Amiibo settings]]. No flushing / writing to the amiibo is done in this command.
  
 
=== DeleteRegisterInfo ===
 
=== DeleteRegisterInfo ===
 
Takes an input [[#DeviceHandle]], no output.
 
Takes an input [[#DeviceHandle]], no output.
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
All [[#RegisterInfo]]-related fields in the internal [[#Amiibo settings]] are filled with random bytes, and the amiibo-initialized [[#Amiibo flag]] is removed. Finally, it calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0.
  
 
=== DeleteApplicationArea ===
 
=== DeleteApplicationArea ===
 
Takes an input [[#DeviceHandle]], no output.
 
Takes an input [[#DeviceHandle]], no output.
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
All [[#Application area]]-related fields in the internal [[#Amiibo settings]] are filled with random bytes, and the corresponding [[#Amiibo flag]] is removed. Finally, it calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0.
  
 
=== ExistsApplicationArea ===
 
=== ExistsApplicationArea ===
 
Takes an input [[#DeviceHandle]], returns an output u8/bool.
 
Takes an input [[#DeviceHandle]], returns an output u8/bool.
 +
 +
Requires the amiibo to be mounted with [[#MountType]] RAM.
 +
 +
Just returns whether the corresponding [[#Amiibo flag]] in the internal [[#Amiibo settings]] is set.
  
 
= RequiredMcuVersionData =
 
= RequiredMcuVersionData =
Line 786: Line 861:
 
|-
 
|-
 
| 5 || Unavailable
 
| 5 || Unavailable
|-
 
| 6 || Finalized
 
 
|}
 
|}
 +
 +
State 5 is not used/exposed with all nfc commands :it is only used with nfp and mifare, see [[#GetDeviceState]].
  
 
= ModelType =
 
= ModelType =
Line 803: Line 878:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Value || Description
+
! Bit || Mask || Description
|-
 
| 1 || ROM
 
 
|-
 
|-
| 2 || RAM
+
| 0 || 1 || ROM
 
|-
 
|-
| 3 || All
+
| 1 || 2 || RAM
 
|}
 
|}
  
Line 858: Line 931:
 
| 0x58 || 0x4 || First write date (see [[#Date]])
 
| 0x58 || 0x4 || First write date (see [[#Date]])
 
|-
 
|-
| 0x5C || 0x29 || Amiibo name (NUL-terminated UTF-8 string)
+
| 0x5C || 0x29 || Amiibo name (NUL-terminated UTF-8 string, converted from UTF-16)
 
|-
 
|-
| 0x85 || 0x1 || Font region
+
| 0x85 || 0x1 || Font region (masked bits from [[#Amiibo settings]])
 
|-
 
|-
 
| 0x86 || 0x7A || Reserved
 
| 0x86 || 0x7A || Reserved
Line 892: Line 965:
 
! Offset || Size || Description
 
! Offset || Size || Description
 
|-
 
|-
| 0x0 || 0x2 || Game and character ID
+
| 0x0 || 0x3 || Character ID (same as in [[#Amiibo ID]])
 
|-
 
|-
| 0x2 || 0x1 || Character variant
+
| 0x3 || 0x1 || Series ID (same as in [[#Amiibo ID]])
 
|-
 
|-
| 0x3 || 0x1 || Figure type
+
| 0x4 || 0x2 || Numbering ID (byte-swapped value in [[#Amiibo ID]])
 
|-
 
|-
| 0x4 || 0x2 || Model number
+
| 0x6 || 0x1 || NFP type  (same as in [[#Amiibo ID]])
 
|-
 
|-
| 0x6 || 0x1 || Series
+
| 0x7 || 0x39 || Reserved
 +
|}
 +
 
 +
= Application area version =
 +
 
 +
Note: unofficial name.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value || Description
 
|-
 
|-
| 0x7 || 0x39 || Reserved
+
| 0xFF || Invalid (application area does not exist)
 +
|-
 +
| 0 || Nintendo 3DS
 +
|-
 +
| 1 || Nintendo Wii U
 +
|-
 +
| 2 || Nintendo 3DS (v2?)
 +
|-
 +
| 3 || Nintendo Switch
 
|}
 
|}
 +
 +
This value corresponds to hex-digit 7 of application IDs (3DS and Wii U title IDs have 0/1 at that position).
 +
 +
NFC computes it by taking (app_id_be >> 36) & 0xF.
 +
 +
Since Switch games do not follow this trend, the application ID in [[#Amiibo settings]] is stored as bswap64(application_id & 0xFFFFFFFF0FFFFFFF | 0x30000000) by [[#CreateApplicationArea]], force-setting the hex-digit (presumably so that older consoles will recognize it).
  
 
= AdminInfo =
 
= AdminInfo =
Line 912: Line 1,008:
 
! Offset || Size || Description
 
! Offset || Size || Description
 
|-
 
|-
| 0x0 || 0x8 || Program ID (From the Wii U, 3DS or Switch title who created the application area)
+
| 0x0 || 0x8 || Application ID of the game owning the application area (original value, see [[#Amiibo settings]])
 
|-
 
|-
| 0x8 || 0x4 || [[#Access ID]]
+
| 0x8 || 0x4 || [[#Amiibo settings]] [[#Access ID]] (byte-swapped)
 
|-
 
|-
| 0xC || 0x2 || CRC32 change counter
+
| 0xC || 0x2 || [[#Amiibo settings]] terminal ID CRC32 change counter
 
|-
 
|-
| 0xE || 0x1 || Flags (bit0 = amiibo was initialized in console settings, bit1 = has application area, bit2/bit3 unknown)
+
| 0xE || 0x1 || [[#Amiibo settings]] flags, bit-shifted: bit0=[[#Amiibo flag]] bit4 and so on
 
|-
 
|-
| 0xF || 0x1 || Unknown, hardcoded to 0x2
+
| 0xF || 0x1 || Unknown, hardcoded to 0x02 (tag type? amiibo version?)
 
|-
 
|-
| 0x10 || 0x1 || 0xFF if there is no application area, related to the console of the application area game otherwise (0/2 = 3DS, 1 = Wii U, 3 = Switch)
+
| 0x10 || 0x1 || [[#Application area version]]
 
|-
 
|-
 
| 0x11 || 0x7 || Padding
 
| 0x11 || 0x7 || Padding
Line 942: Line 1,038:
 
| 0x44 || 0x4 || First write date (see [[#Date]])
 
| 0x44 || 0x4 || First write date (see [[#Date]])
 
|-
 
|-
| 0x48 || 0x29 || Amiibo name (NUL-terminated string)
+
| 0x48 || 0x29 || Amiibo name (NUL-terminated UTF-8 string, converted from UTF-16)
 
|-
 
|-
 
| 0x71 || 0x1 || Unknown
 
| 0x71 || 0x1 || Unknown
Line 956: Line 1,052:
 
! Offset || Size || Description
 
! Offset || Size || Description
 
|-
 
|-
| 0x0 || 0x1 || Magic (Always 0xA5)
+
| 0x0 || 0x1 || [[#Amiibo header]] magic (Always 0xA5)
 
|-
 
|-
 
| 0x1 || 0x1 || Reserved
 
| 0x1 || 0x1 || Reserved
 
|-
 
|-
| 0x2 || 0x1 || Write counter
+
| 0x2 || 0x2 || [[#Amiibo header]] write counter (byte-swapped)
 
|-
 
|-
| 0x3 || 0x1 || Reserved
+
| 0x4 || 0x4 || [[#Amiibo settings]] terminal ID CRC32 (byte-swapped)
|-
 
| 0x4 || 0x4 || Settings CRC32
 
 
|-
 
|-
 
| 0x8 || 0x38 || Reserved
 
| 0x8 || 0x38 || Reserved
 
|-
 
|-
| 0x40 || 0x40 || [[#CommonInfo]]
+
| 0x40 || 0x40 || Same contents as [[#CommonInfo]]
 
|-
 
|-
| 0x80 || 0x5C || Mii char info V3 (see https://www.3dbrew.org/wiki/Mii#Mii_format)
+
| 0x80 || 0x5C || [[#Amiibo settings]] mii Ver3StoreData, format used in 3DS (see https://www.3dbrew.org/wiki/Mii#Mii_format)
 
|-
 
|-
 
| 0xDC || 0x2 || Padding
 
| 0xDC || 0x2 || Padding
 
|-
 
|-
| 0xDE || 0x2 || Mii char info V3 CRC16
+
| 0xDE || 0x2 || [[#Amiibo settings]] mii CRC16
 
|-
 
|-
| 0xE0 || 0x8 || Mii StoreDataExtension
+
| 0xE0 || 0x8 || [[#Amiibo settings]] mii StoreDataExtension
 
|-
 
|-
 
| 0xE8 || 0x4 || First write date (see [[#Date]])
 
| 0xE8 || 0x4 || First write date (see [[#Date]])
 
|-
 
|-
| 0xEC || 0xB * 2 || Amiibo name (NUL-terminated UTF-16 string)
+
| 0xEC || 0x16 (2*11) || Amiibo name (NUL-terminated UTF-16 string, byte-swapped from [[#Amiibo settings]])
 
|-
 
|-
| 0x102 || 0x1 || Settings flags (bit4 = amiibo was initialized in console settings, bit5 = has application area)
+
| 0x102 || 0x1 || [[#Amiibo settings]] font region
 
|-
 
|-
 
| 0x103 || 0x1 || Unknown, normally zero
 
| 0x103 || 0x1 || Unknown, normally zero
 
|-
 
|-
| 0x104 || 0x4 || Register Info CRC32
+
| 0x104 || 0x4 || [[#Amiibo settings]] mii CRC32 (byte-swapped)
 
|-
 
|-
| 0x108 || 0x4 * 5 || Unknown, normally zero
+
| 0x108 || 0x14 || [[#Amiibo settings]] unknown 0x14 bytes, normally zero
 
|-
 
|-
 
| 0x11c || 0x64 || Reserved
 
| 0x11c || 0x64 || Reserved
 
|-
 
|-
| 0x180 || 0x8 || Program ID (From the Wii U, 3DS or Switch title who created the application area)
+
| 0x180 || 0x8 || [[#Amiibo settings]] modified application ID (byte-swapped)
 
|-
 
|-
| 0x188 || 0x4 || [[#Access ID]]
+
| 0x188 || 0x4 || [[#Amiibo settings]] [[#Access ID]] (byte-swapped)
 
|-
 
|-
| 0x18c || 0x2 || Settings CRC32 change counter
+
| 0x18c || 0x2 || [[#Amiibo settings]] terminal ID CRC32 change counter (byte-swapped)
 
|-
 
|-
| 0x18e || 0x1 || Font region
+
| 0x18e || 0x1 || [[#Amiibo settings]] flags (bit-shifted, same as with [[#AdminInfo]])
 
|-
 
|-
| 0x18f || 0x1 || Tag type, hardcoded to 0x2
+
| 0x18f || 0x1 || Hardcoded to 0x02 (tag type? amiibo version?)
 
|-
 
|-
| 0x190 || 0x1 || Console type, (3DS = 0, Wiiu = 1, 3DSv2 = 2, switch = 3, not set = 0xFF)
+
| 0x190 || 0x1 || [[#Application area version]]
 
|-
 
|-
| 0x191 || 0x1 || (Original Program ID >> 0x24) & 0xF byte (Program ID has this byte swapped with console type)
+
| 0x191 || 0x1 || Application ID byte (see [[#Amiibo settings]])
 
|-
 
|-
 
| 0x192 || 0x2E || Reserved
 
| 0x192 || 0x2E || Reserved
 
|-
 
|-
| 0x1c0 || 0xd8 || Application area data
+
| 0x1c0 || 0xD8 || [[#Application area]]
 
|}
 
|}
  
 
= BreakType =
 
= BreakType =
This is "nn::nfp::BreakType".
+
This is "nn::nfp::BreakType". For more details, see [[#BreakTag]].
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,018: Line 1,112:
 
! Value || Description
 
! Value || Description
 
|-
 
|-
| 0 || ?
+
| 0 || Does no breaking, just flushes
 
|-
 
|-
| 1 || ?
+
| 1 || Breaks the amiibo data SHA256 HMAC hash (see [[#Amiibo settings]])
 
|-
 
|-
| 2 || ?
+
| 2 || Breaks the amiibo header magic (see [[#Amiibo settings]])
 
|}
 
|}
  
Line 1,039: Line 1,133:
 
|}
 
|}
  
= Access ID =
+
= Application area =
 +
 
 +
This is a 0xD8 byte region for per-game amiibo savedata. Only one game may use the application area.
 +
 
 +
== Access ID ==
 
Access IDs are game-unique u32s used to access the amiibo application area.
 
Access IDs are game-unique u32s used to access the amiibo application area.
 +
 +
== Nintendo 3DS titles ==
  
 
For a list of Nintendo 3DS access IDs, see https://www.3dbrew.org/wiki/Amiibo#Games_using_Amiibo_AppData.
 
For a list of Nintendo 3DS access IDs, see https://www.3dbrew.org/wiki/Amiibo#Games_using_Amiibo_AppData.
Line 1,062: Line 1,162:
 
| The Legend of Zelda: Link's Awakening || 0x3B440400
 
| The Legend of Zelda: Link's Awakening || 0x3B440400
 
|}
 
|}
 +
 +
= Backup data =
 +
 +
Note: unofficial name.
 +
 +
Backup data is stored at [[Flash_Filesystem#SystemSaveData|data]]:/nfp_backup.dat. It has a total size of 0x1FBD20 bytes, and has the following format:
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x20 || [[#Backup header]]
 +
|-
 +
| 0x20 || 0x7D00 (0x20*1000) || [[#Backup entry header]] array
 +
|-
 +
| 0x7D20 || 0x1F4000 (0x800*1000) || [[#Backup entry data]] array
 +
|}
 +
 +
There is a maximum of 1000 entries. This can be accessed by [[#ReadBackupData]] and [[#WriteBackupData]] commands.
 +
 +
== Backup header ==
 +
 +
Note: unofficial name.
 +
 +
This is 0x20 bytes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x2 || Unknown (zero?)
 +
|-
 +
| 0x2 || 0x2 || Entry count
 +
|-
 +
| 0x4 || 0x2 || Next free entry index
 +
|-
 +
| 0x6 || 0x2 || Unknown (zero?)
 +
|-
 +
| 0x8 || 0x8 || Unknown (zero?)
 +
|-
 +
| 0x10 || 0x8 || Unknown (zero?)
 +
|-
 +
| 0x18 || 0x4 || Unknown (zero?)
 +
|-
 +
| 0x1C || 0x4 || CRC32 of the 0x1C bytes above
 +
|}
 +
 +
== Backup entry header ==
 +
 +
Note: unofficial name.
 +
 +
This is 0x20 bytes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x1 || UUID length
 +
|-
 +
| 0x1 || 0xA || UUID
 +
|-
 +
| 0xB || 0x1 || Padding
 +
|-
 +
| 0xC || 0x2 || Packed date (when this entry was written)
 +
|-
 +
| 0xE || 0xE || Unknown (zero?)
 +
|-
 +
| 0x1C || 0x4 || CRC32 of the 0x1C bytes above
 +
|}
 +
 +
== Backup entry data ==
 +
 +
Note: unofficial name.
 +
 +
This is a 0x800 bytes (per-entry data).
 +
 +
NFC writes here the amiibo [[#Raw format]], while the remaining 0x5E4 bytes are unused.
 +
 +
= Amiibo =
 +
 +
== Raw format ==
 +
 +
Note: unofficial name.
 +
 +
This is 0x21C bytes.
 +
 +
This is the raw format initially read by NFC (as well as other amiibo dumping tools). It has the following format:
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8 || [[#NTAG215 data 1]]
 +
|-
 +
| 0x8 || 0x8 || [[#NTAG215 data 2]]
 +
|-
 +
| 0x10 || 0x4 || [[#Amiibo header]]
 +
|-
 +
| 0x14 || 0x20 || Encrypted section 1
 +
|-
 +
| 0x34 || 0x20 || Tag SHA256 HMAC hash: hash over plain tag data, see [[#Plain format]]
 +
|-
 +
| 0x54 || 0x2C || [[#Amiibo ID entry]]
 +
|-
 +
| 0x80 || 0x20 || Data SHA256 HMAC hash: hash over plain data, see [[#Plain format]]
 +
|-
 +
| 0xA0 || 0x114 || Encrypted section 2
 +
|-
 +
| 0x1B4 || 0x54 || Encrypted section 3
 +
|-
 +
| 0x208 || 0x4 || [[#NTAG215 dynamic lock]]
 +
|-
 +
| 0x20C || 0x10 || [[#NTAG215 config]]
 +
|}
 +
 +
All non-NTAG215 fields are specific of amiibo (located in the user memory pages of the tag). For more details on the page layout, see https://www.3dbrew.org/wiki/Amiibo.
 +
 +
The three encrypted sections combined in order (a total of 0x188 bytes) are decrypted to get the [[#Amiibo settings]] and the [[#Application area]], in that order.
 +
 +
== Plain format ==
 +
 +
This is 0x21C bytes.
 +
 +
Note: unofficial name.
 +
 +
This format contains reordered and decrypted amiibo data:
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8 || [[#NTAG215 data 2]]
 +
|-
 +
| 0x8 || 0x20 || Data SHA256 HMAC hash: hash over 0x1DF bytes, starting at offset 0x29 ([[#Amiibo header]] write counter) until [[#Amiibo ID entry]]
 +
|-
 +
| 0x28 || 0x4 || [[#Amiibo header]]
 +
|-
 +
| 0x2C || 0xB0 || [[#Amiibo settings]]
 +
|-
 +
| 0xDC || 0xD8 || [[#Application area]]
 +
|-
 +
| 0x1B4 || 0x20 || Tag SHA256 HMAC hash: hash over 0x34 bytes below ([[#NTAG215 data 1]] and [[#Amiibo ID entry]])
 +
|-
 +
| 0x1D4 || 0x8 || [[#NTAG215 data 1]]
 +
|-
 +
| 0x1DC || 0x2C || [[#Amiibo ID entry]]
 +
|-
 +
| 0x208 || 0x4 || [[#NTAG215 dynamic lock]]
 +
|-
 +
| 0x20C || 0x10 || [[#NTAG215 config]]
 +
|}
 +
 +
When converting from [[#Raw format]] to [[#Plain format]], both SHA256 HMAC hashes are tested, otherwise an error is returned internally.
 +
 +
== NTAG215 data 1 ==
 +
 +
This is 0x8 bytes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8 || NTAG215 9-byte manufacturer serial number (first 8 bytes)
 +
|}
 +
 +
== NTAG215 data 2 ==
 +
 +
This is 0x8 bytes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x1 || NTAG215 9-byte manufacturer serial number (last byte)
 +
|-
 +
| 0x1 || 0x1 || Internal
 +
|-
 +
| 0x2 || 0x2 || Static lock bytes
 +
|-
 +
| 0x4 || 0x4 || Capability Container (CC) bytes
 +
|}
 +
 +
NFC checks that the static lock bytes match 0xE00F when converting from [[#Raw format]] to [[#Plain format]].
 +
 +
== NTAG215 dynamic lock ==
 +
 +
This is 0x4 bytes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x3 || Dynamic lock bytes
 +
|-
 +
| 0x3 || 0x1 || RFUI
 +
|}
 +
 +
NFC checks the dynamic lock state when converting from [[#Raw format]] to [[#Plain format]].
 +
 +
== NTAG215 config ==
 +
 +
This is 0x10 bytes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x4 || CFG0
 +
|-
 +
| 0x4 || 0x4 || CFG1
 +
|-
 +
| 0x8 || 0x4 || PWD
 +
|-
 +
| 0xC || 0x2 || PACK
 +
|-
 +
| 0xE || 0x2 || RFUI
 +
|}
 +
 +
NFC checks that the CFG0 and CFG1 match 0x4000000 and 0x5F when converting from [[#Raw format]] to [[#Plain format]].
 +
 +
== Amiibo header ==
 +
 +
This is 0x4 bytes.
 +
 +
Note: unofficial name.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x1 || Magic (0xA5)
 +
|-
 +
| 0x1 || 0x2 || Write counter (big-endian)
 +
|-
 +
| 0x3 || 0x1 || Version (0x00)
 +
|}
 +
 +
== Amiibo ID ==
 +
 +
This is 0x8 bytes.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x3 || Character ID: bits0-9 = game ID, bits10-15 = character ID, bits16-23 = character variant
 +
|-
 +
| 0x3 || 0x1 || Series ID
 +
|-
 +
| 0x4 || 0x2 || Numbering ID (big-endian)
 +
|-
 +
| 0x6 || 0x1 || NFP type (figurine type)
 +
|-
 +
| 0x7 || 0x1 || Version? (0x02)
 +
|}
 +
 +
== Amiibo ID entry ==
 +
 +
This is 0x2C bytes.
 +
 +
Note: unofficial name.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8 || [[#Amiibo ID]]
 +
|-
 +
| 0x8 || 0x4 || Unknown
 +
|-
 +
| 0xC || 0x20 || Unknown, maybe some hash
 +
|}
 +
 +
== Amiibo flag ==
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bit || Mask || Description
 +
|-
 +
| 4 || 0x10 || Initialized in console settings
 +
|-
 +
| 5 || 0x20 || Application area exists (was created by some game)
 +
|}
 +
 +
== Amiibo date ==
 +
 +
This is a date packed in 2 bytes:
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bits || Description
 +
|-
 +
| 0-4 || Day
 +
|-
 +
| 5-8 || Month
 +
|-
 +
| 9-15 || Year (relative to 2000)
 +
|}
 +
 +
== Amiibo settings ==
 +
 +
This is 0xB0 bytes.
 +
 +
Note: unofficial name.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x1 || Font region (bits0-3) and [[#Amiibo flag]] (bits4-7)
 +
|-
 +
| 0x1 || 0x2 || Country code ID
 +
|-
 +
| 0x2 || 0x2 || Counter of the times the terminal ID CRC32 has changed (big-endian)
 +
|-
 +
| 0x4 || 0x2 || First write date (big-endian, see [[#Amiibo date]] for format in little-endian)
 +
|-
 +
| 0x6 || 0x2 || Last write date (big-endian, see [[#Amiibo date]] for format in little-endian)
 +
|-
 +
| 0x8 || 0x4 || CRC32 of NFC terminal ID (8 bytes, see below)
 +
|-
 +
| 0xC || 0x14 (2*10) || Amiibo name (UTF16-BE, not null-terminated)
 +
|-
 +
| 0x20 || 0x5C || Mii in Ver3StoreData format, see https://www.3dbrew.org/wiki/Mii#Mii_format
 +
|-
 +
| 0x7C || 0x2 || Unused/padding
 +
|-
 +
| 0x7E || 0x2 || CRC16 of the mii data (0x60 bytes, last 4-bytes zeroed)
 +
|-
 +
| 0x80 || 0x8 || Application ID of the game owning the application area (big-endian) (modified, see [[#Application area version]])
 +
|-
 +
| 0x88 || 0x2 || Write counter (big-endian)
 +
|-
 +
| 0x8A || 0x4 || Access ID of the game owning the application area (big-endian)
 +
|-
 +
| 0x8E || 0x1 || Application ID byte: (Application ID >> 28) & 0xFF
 +
|-
 +
| 0x8F || 0x1 || Unknown1
 +
|-
 +
| 0x90 || 0x8 || Mii StoreDataExtension
 +
|-
 +
| 0x98 || 0x14 || Unknown2
 +
|-
 +
| 0xAC || 0x4 || CRC32 of mii data (Ver3StoreData + pad + CRC16) +  Application ID byte + Unknown1 + StoreDataExtension + Unknown2 (total of 0x7E bytes)
 +
|}
 +
 +
The country code ID is zeroed when calling [[#SetRegisterInfoPrivate]].
 +
 +
The application ID byte contains the original application ID hex-digit (only used for Switcj games, see [[#Application area version]]), so it can be to restore the original value (which is needed for [[#GetAdminInfo]]).
 +
 +
The terminal ID is a randomly-generated 8-byte value that is re-generated every time [[#Initialize]] is called (thus every nfc/nfp/mifare session), and saved at [[Flash_Filesystem#SystemSaveData|data]]:/nfc_terminal_id.dat.
 +
 +
= Play report =
 +
 +
In nfp [[#Unmount]] and [[#Format]] commands, and if [[System Settings|setting]] <code>nfp!play_report</code> is true, a [[BCAT services|play report]] is sent with the following fields: <code>Uid</code>, <code>CharacterId</code>, <code>NumberingId</code>, <code>SeriesId</code>, <code>NfpType</code> (from the current [[#Amiibo ID]]), <code>ApplicationId</code>, <code>AccessInfo</code>, <code>DeviceType</code>.
  
 
[[Category:Services]]
 
[[Category:Services]]

Revision as of 14:13, 18 May 2025

nfc:am

This is "nn::nfc::am::detail::IAmManager".

Cmd Name
0 CreateAmInterface

IAm

This is "nn::nfc::am::detail::IAm".

Cmd Name
0 Initialize
1 Finalize
2 NotifyForegroundApplet

nfc:mf:u

This is "nn::nfc::mifare::detail::IUserManager".

Cmd Name
0 CreateUserInterface

IUser

This is "nn::nfc::mifare::detail::IUser".

Cmd Name
0 #Initialize
1 #Finalize
2 #ListDevices
3 StartDetection
4 #StopDetection
5 Read
6 Write
7 #GetTagInfo
8 GetActivateEventHandle
9 GetDeactivateEventHandle
10 #GetState
11 #GetDeviceState
12 #GetNpadId
13 [3.0.0+] GetAvailabilityChangeEventHandle

nfc:user

This is "nn::nfc::detail::IUserManager".

Cmd Name
0 CreateUserInterface

IUser

This is "nn::nfc::detail::IUser".

Cmd Name
0 InitializeOld
1 FinalizeOld
2 #GetStateOld
3 #IsNfcEnabledOld
400 [4.0.0+] #Initialize
401 [4.0.0+] #Finalize
402 [4.0.0+] #GetState
403 [4.0.0+] #IsNfcEnabled
404 [4.0.0+] #ListDevices
405 [4.0.0+] #GetDeviceState
406 [4.0.0+] #GetNpadId
407 [4.0.0+] #AttachAvailabilityChangeEvent
408 [4.0.0+] #StartDetection
409 [4.0.0+] #StopDetection
410 [4.0.0+] #GetTagInfo
411 [4.0.0+] #AttachActivateEvent
412 [4.0.0+] #AttachDeactivateEvent
1000 [4.0.0+] #ReadMifare
1001 [4.0.0+] #WriteMifare
1300 [4.0.0+] #SendCommandByPassThrough
1301 [4.0.0+] #KeepPassThroughSession
1302 [4.0.0+] #ReleasePassThroughSession

GetStateOld

No input, returns an output u32.

IsNfcEnabledOld

No input, returns an output bool.

This runs the same code as #IsNfcEnabled.

GetState

No input, returns an output u32.

This replaces #GetStateOld.

IsNfcEnabled

No input, returns an output bool.

This replaces #IsNfcEnabledOld.

StartDetection

Takes an input #DeviceHandle and a #NfcProtocol, no output.

StopDetection

Takes an input #DeviceHandle, no output.

ReadMifare

Takes an input #DeviceHandle, a type-0x6 output buffer containing an array of #MifareReadBlockData, a type-0x5 input buffer containing an array of #MifareReadBlockParameter, no output.

sdknso passes the same user-specified array-count for both buffers.

WriteMifare

Takes an input #DeviceHandle, a type-0x5 input buffer containing an array of #MifareWriteBlockParameter, no output.

SendCommandByPassThrough

Takes an input #DeviceHandle, a nn::TimeSpan timeout, a type-0x6 output buffer, a type-0x5 input buffer, returns an output u32 out_size.

sdknso copies the output u32 into an u64. This is the actual size which was copied into the output buffer.

This allows using a raw NFC command. The input buffer contains the command data (id + params), and the output buffer contains the response.

KeepPassThroughSession

Takes an input #DeviceHandle, no output.

ReleasePassThroughSession

Takes an input #DeviceHandle, no output.

nfc:sys

This is "nn::nfc::detail::ISystemManager".

Cmd Name
0 CreateSystemInterface

ISystem

This is "nn::nfc::detail::ISystem".

Cmd Name
0 #Initialize
1 #Finalize
2 #GetStateOld
3 #IsNfcEnabledOld
100 #SetNfcEnabledOld
400 [4.0.0+] InitializeSystem
401 [4.0.0+] FinalizeSystem
402 [4.0.0+] #GetState
403 [4.0.0+] #IsNfcEnabled
404 [4.0.0+] #ListDevices
405 [4.0.0+] #GetDeviceState
406 [4.0.0+] #GetNpadId
407 [4.0.0+] #AttachAvailabilityChangeEvent
408 [4.0.0+] #StartDetection
409 [4.0.0+] #StopDetection
410 [4.0.0+] #GetTagInfo
411 [4.0.0+] #AttachActivateEvent
412 [4.0.0+] #AttachDeactivateEvent
500 [4.0.0+] #SetNfcEnabled
510 [7.0.0+] #OutputTestWave
1000 [4.0.0+] #ReadMifare
1001 [4.0.0+] #WriteMifare
1300 [4.0.0+] #SendCommandByPassThrough
1301 [4.0.0+] #KeepPassThroughSession
1302 [4.0.0+] #ReleasePassThroughSession

SetNfcEnabledOld

Takes an input bool, no output.

This runs the same code as #SetNfcEnabled.

SetNfcEnabled

Takes an input bool, no output.

This replaces #SetNfcEnabledOld.

OutputTestWave

Takes an input bool and a #TestWaveType, no output.

nfp services

These are used for amiibo support (nfp = Nintendo Figurine Protocol, internal name for amiibo protocol).

Check Error codes for result codes that these commands may return on error.

nfp:user

This is "nn::nfp::detail::IUserManager".

Cmd Name
0 CreateUserInterface

IUser

This is "nn::nfp::detail::IUser".

Cmd Name
0 Initialize
1 Finalize
2 #ListDevices
3 #StartDetection
4 #StopDetection
5 #Mount
6 #Unmount
7 #OpenApplicationArea
8 #GetApplicationArea
9 #SetApplicationArea
10 #Flush
11 #Restore
12 #CreateApplicationArea
13 #GetTagInfo
14 #GetRegisterInfo
15 #GetCommonInfo
16 #GetModelInfo
17 #AttachActivateEvent
18 #AttachDeactivateEvent
19 #GetState
20 #GetDeviceState
21 #GetNpadId
22 #GetApplicationAreaSize
23 [3.0.0+] #AttachAvailabilityChangeEvent
24 [3.0.0+] #RecreateApplicationArea

nfp:sys

This is "nn::nfp::detail::ISystemManager".

Cmd Name
0 CreateSystemInterface

ISystem

This is "nn::nfp::detail::ISystem".

Cmd Name
0 InitializeSystem
1 FinalizeSystem
2 #ListDevices
3 #StartDetection
4 #StopDetection
5 #Mount
6 #Unmount
10 #Flush
11 #Restore
13 #GetTagInfo
14 #GetRegisterInfo
15 #GetCommonInfo
16 #GetModelInfo
17 #AttachActivateEvent
18 #AttachDeactivateEvent
19 #GetState
20 #GetDeviceState
21 #GetNpadId
23 [3.0.0+] #AttachAvailabilityChangeEvent
100 #Format
101 #GetAdminInfo
102 #GetRegisterInfoPrivate
103 #SetRegisterInfoPrivate
104 #DeleteRegisterInfo
105 #DeleteApplicationArea
106 #ExistsApplicationArea

nfp:dbg

This is "nn::nfp::detail::IDebugManager".

Cmd Name
0 CreateDebugInterface

IDebug

This is "nn::nfp::detail::IDebug".

Cmd Name
0 InitializeDebug
1 FinalizeDebug
2 #ListDevices
3 #StartDetection
4 #StopDetection
5 #Mount
6 #Unmount
7 #OpenApplicationArea
8 #GetApplicationArea
9 #SetApplicationArea
10 #Flush
11 #Restore
12 #CreateApplicationArea
13 #GetTagInfo
14 #GetRegisterInfo
15 #GetCommonInfo
16 #GetModelInfo
17 #AttachActivateEvent
18 #AttachDeactivateEvent
19 #GetState
20 #GetDeviceState
21 #GetNpadId
22 #GetApplicationAreaSize
23 [3.0.0+] #AttachAvailabilityChangeEvent
24 [3.0.0+] #RecreateApplicationArea
100 #Format
101 #GetAdminInfo
102 #GetRegisterInfoPrivate
103 #SetRegisterInfoPrivate
104 #DeleteRegisterInfo
105 #DeleteApplicationArea
106 #ExistsApplicationArea
200 #GetAll
201 #SetAll
202 #FlushDebug
203 #BreakTag
204 #ReadBackupData
205 #WriteBackupData
206 #WriteNtf
300 [3.0.0-3.0.2]
301 [3.0.0-3.0.2]
302 [3.0.0-3.0.2]
303 [3.0.0-3.0.2]
304 [3.0.0-3.0.2]
305 [3.0.0-3.0.2]
306 [3.0.0-3.0.2]
307 [3.0.0-3.0.2]
308 [3.0.0-3.0.2]
309 [3.0.0-3.0.2]
310 [3.0.0-3.0.2]
311 [3.0.0-3.0.2]
312 [3.0.0-3.0.2]
313 [3.0.0-3.0.2]
314 [3.0.0-3.0.2]

GetAll

Takes an input #DeviceHandle, a type-0x1A output buffer containing #NfpData, no output.

Requires the amiibo to be mounted with #MountType RAM.

Just converts data from the internal #Amiibo settings to the output data. The last write date is not validated here (unlike with #GetCommonInfo).

SetAll

Takes an input #DeviceHandle, a type-0x19 input buffer containing #NfpData, no output.

Requires the amiibo to be mounted with #MountType RAM.

Just converts data from the input data to the internal #Amiibo settings. No flushing / writing to the amiibo is done in this command.

FlushDebug

Takes an input #DeviceHandle, no output.

Requires the amiibo to be mounted with #MountType RAM.

Just calls internally the same function as #BreakTag with #BreakType 0.

BreakTag

Takes an input #DeviceHandle, an input u32 #BreakType, no output.

Calls an internal function with the input #BreakType. This first reads amiibo data (like #Mount and other commands), then saves the read amiibo in the #Backup data, then depending on the type performs some logic (this changes are thus not saved in the backup), and finally flushes the modified amiibo (writes it to the figurine).

#BreakType 0 does nothing (it is used as a flushing command, used by many other commands).

#BreakType 1 breaks the data SHA256 HMAC hash (doing "raw_fmt->data_sha256_hmac_hash[0] ^= 0x80u;", see #Amiibo settings)

#BreakType 2 sets the amiibo header magic (see #Amiibo settings) to 0x00 (which beaks the figurine since this magic is checked to be 0xA5 in several places).

ReadBackupData

Takes an input #DeviceHandle, a type-0x6 output buffer, and an output u32 (read_size).

This reads from the raw #Backup data.

WriteBackupData

Takes an input #DeviceHandle, a type-0x5 input buffer, no output.

This writes directly to the raw #Backup data. The buffer size must be less or equal than the backup data size (0x1FBD20).

WriteNtf

Takes an input #DeviceHandle, an input u32 #WriteType, a type-0x5 input buffer, no output.

The input buffer size must match 0x2A0. This handles Amiibo crypto, etc.

Common

Create*Interface

Returns an output interface (#IUser, #ISystem or #IDebug depending on the service).

Initialize*

Takes a PID, an AppletResourceUserId, an u64 placeholder for the PID, a type-0x5 input buffer containing an array of #RequiredMcuVersionData, no output.

Internally this is mostly the same for each service.

The input PID is internally used to get the process application ID when needed.

Finalize*

No input/output.

Internally this is mostly the same for each service.

ListDevices

Takes a type-0xA output buffer containing an array of #DeviceHandle, returns an output s32 total_out.

This can return a maximum of 0xA entries.

StartDetection

Takes an input #DeviceHandle, no output.

This runs the same code as nfc #StartDetection with #NfcProtocol = -1.

StopDetection

Takes an input #DeviceHandle, no output.

Mount

Takes an input #DeviceHandle, an input u32 #ModelType and an input u32 #MountTarget, no output.

Creates an internal object that manages mounted amiibo data. This step loads the amiibo #Raw format, saves it in #Backup data, and converts/decrypts it internally into a #Plain format.

Unmount

Takes an input #DeviceHandle, no output.

Requires the amiibo to be mounted. Disposes the internal object that manages mounted amiibo data.

OpenApplicationArea

Takes an input #DeviceHandle and an input u32 #Access ID, no output.

Requires the amiibo to be mounted with #MountType RAM, and the application area to exist (checks the #Amiibo flag). Just sets an internal flag to 1 if the provided access ID and the application area access ID match.

GetApplicationArea

Takes an input #DeviceHandle and a type-0x6 output #Application area data buffer, returns an output u32 size.

Requires the amiibo to be mounted with #MountType RAM, and the application area to exist and be opened (see #OpenApplicationArea).

Reads the buffer data in the application area and returns the size read from the application area.

SetApplicationArea

Takes an input #DeviceHandle and a type-0x5 input #Application area data buffer, no output.

Requires the amiibo to be mounted with #MountType RAM, and the application area to exist and be opened (see #OpenApplicationArea).

Writes the buffer data in the application area. The remaining data out of the total 0xD8-bytes is filled with randomly generated bytes.

Flush

Takes an input #DeviceHandle, no output.

Requires the amiibo to be mounted with #MountType RAM.

Performs CRC verifications, updates write counters (see #Amiibo settings) and then calls internally the same function as #BreakTag with #BreakType 0.

Restore

Takes an input #DeviceHandle, no output.

Reloads amiibo data (same internal functions as #Mount) and writes the data to the amiibo again. If reading the amiibo fails, it tries to load the #Raw data from the #Backup data.

CreateApplicationArea

Takes an input #DeviceHandle, an input u32 #Access ID and a type-0x5 input #Application area data buffer, no output.

Requires the amiibo to be mounted with #MountType RAM.

Sets the new application ID / access ID values (even if an application area already existed), updates CRC values, updates write counters (see #Amiibo settings), copies input data, fills remaining space with random bytes, and then calls internally the same function as #BreakTag with #BreakType 0.

GetTagInfo

Takes an input #DeviceHandle and a type-0x1A output buffer containing a #TagInfo.

GetRegisterInfo

Takes an input #DeviceHandle and a type-0x1A output buffer containing a #RegisterInfo.

Requires the amiibo to be mounted with #MountType RAM.

Just converts data from the internal #Amiibo settings to the output info.

GetCommonInfo

Takes an input #DeviceHandle and a type-0x1A output buffer containing a #CommonInfo.

Requires the amiibo to be mounted with #MountType RAM.

Converts data from the internal #Amiibo settings to the output info. The last write date is validated, defaulting it to 2000-1-1 if the validation fails.

GetModelInfo

Takes an input #DeviceHandle and a type-0x1A output buffer containing a #ModelInfo.

Requires the amiibo to be mounted with #MountType ROM.

Just converts data from the internal #Amiibo settings to the output info.

AttachActivateEvent

Takes an input #DeviceHandle, returns an output Event handle.

sdknso uses EventClearMode=1.

AttachDeactivateEvent

Takes an input #DeviceHandle, returns an output Event handle.

sdknso uses EventClearMode=1.

GetState

Returns an output u32 #State.

GetDeviceState

Takes an input #DeviceHandle, returns an output u32 #DeviceState.

The returned state is mapped from the internal state value through lookup tables. nfp services uses the same table, mifare uses a separate one, and the nfc services use another separate table.

GetNpadId

Takes an input #DeviceHandle, returns an output u32 NpadId.

GetApplicationAreaSize

Takes an input #DeviceHandle, returns an output u32 size.

Returns a hardcoded value of 0xD8.

AttachAvailabilityChangeEvent

No input, returns an output Event handle.

sdknso uses EventClearMode=1.

RecreateApplicationArea

Takes an input #DeviceHandle, an input u32 #Access ID and a type-0x5 input #Application area data buffer, no output.

Requires the amiibo to be mounted with #MountType RAM, and the application area to exist and be opened (see #OpenApplicationArea).

Performs the same logic as #SetApplicationArea but without checking the current access ID, just overwriting it.

Format

Takes an input #DeviceHandle, no output.

GetAdminInfo

Takes an input #DeviceHandle and a type-0x1A output buffer containing a #AdminInfo.

Requires the amiibo to be mounted with #MountType RAM.

Just converts data from the internal #Amiibo settings to the output info.

GetRegisterInfoPrivate

Takes an input #DeviceHandle and a type-0x1A output buffer containing a #RegisterInfoPrivate.

Requires the amiibo to be mounted with #MountType RAM.

Just converts data from the internal #Amiibo settings to the output info.

SetRegisterInfoPrivate

Takes an input #DeviceHandle and a type-0x19 input buffer containing a #RegisterInfoPrivate.

Requires the amiibo to be mounted with #MountType RAM.

Just converts data from the input info to the internal #Amiibo settings. No flushing / writing to the amiibo is done in this command.

DeleteRegisterInfo

Takes an input #DeviceHandle, no output.

Requires the amiibo to be mounted with #MountType RAM.

All #RegisterInfo-related fields in the internal #Amiibo settings are filled with random bytes, and the amiibo-initialized #Amiibo flag is removed. Finally, it calls internally the same function as #BreakTag with #BreakType 0.

DeleteApplicationArea

Takes an input #DeviceHandle, no output.

Requires the amiibo to be mounted with #MountType RAM.

All #Application area-related fields in the internal #Amiibo settings are filled with random bytes, and the corresponding #Amiibo flag is removed. Finally, it calls internally the same function as #BreakTag with #BreakType 0.

ExistsApplicationArea

Takes an input #DeviceHandle, returns an output u8/bool.

Requires the amiibo to be mounted with #MountType RAM.

Just returns whether the corresponding #Amiibo flag in the internal #Amiibo settings is set.

RequiredMcuVersionData

In sdknso, the global data containing the array data for this is "nn::nfc::client::RequiredMcuVersionData". The array entry is 0x20-bytes.

DeviceHandle

This is "nn::nfc::DeviceHandle". This is a 8-byte struct with 4-byte alignment.

NfcProtocol

This is s32 enum "nn::nfc::NfcProtocol". Value -1 can be used as a default.

TestWaveType

This is u32 enum "nn::nfc::TestWaveType".

MifareKey

This is a 0x10-byte struct.

Offset Size Description
0x0 0x1 MifareCommand
0x1 0x1 Unknown
0x2 0x6 Padding
0x8 0x6 Key data
0xE 0x2 Padding

MifareReadBlockData

This is "nn::nfc::MifareReadBlockData". This is a 0x18-byte struct.

Offset Size Description
0x0 0x10 Data
0x10 0x1 Block index
0x11 0x7 Padding

MifareReadBlockParameter

This is "nn::nfc::MifareReadBlockParameter". This is a 0x18-byte struct.

Offset Size Description
0x0 0x1 Block index
0x1 0x7 Padding
0x8 0x10 #MifareKey

MifareWriteBlockParameter

This is "nn::nfc::MifareWriteBlockParameter". This is a 0x28-byte struct.

Offset Size Description
0x0 0x10 Data
0x10 0x1 Block index
0x11 0x7 Padding
0x18 0x10 #MifareKey

State

Value Description
0 NonInitialized
1 Initialized

DeviceState

Value Description
0 Initialized
1 Searching for tag
2 Tag found
3 Tag removed
4 Tag mounted
5 Unavailable

State 5 is not used/exposed with all nfc commands :it is only used with nfp and mifare, see #GetDeviceState.

ModelType

Value Description
0 Amiibo

MountTarget

Bit Mask Description
0 1 ROM
1 2 RAM

Date

This is "nn::nfp::Date":

Offset Size Description
0x0 0x2 Year
0x2 0x1 Month
0x3 0x1 Day

TagInfo

This is "nn::nfp::TagInfo". This is a 0x58-byte struct.

Offset Size Description
0x0 0xA UUID
0xA 0x1 UUID length
0xB 0x15 Reserved
0x20 0x4 Protocol
0x24 0x4 Tag type
0x28 0x30 Reserved

RegisterInfo

This is "nn::nfp::RegisterInfo". This is a 0x100-byte struct.

Offset Size Description
0x0 0x58 Mii CharInfo (see mii services)
0x58 0x4 First write date (see #Date)
0x5C 0x29 Amiibo name (NUL-terminated UTF-8 string, converted from UTF-16)
0x85 0x1 Font region (masked bits from #Amiibo settings)
0x86 0x7A Reserved

CommonInfo

This is ""nn::nfp::CommonInfo". This is a 0x40-byte struct.

Offset Size Description
0x0 0x4 Last write date (see #Date)
0x4 0x2 Write counter
0x6 0x1 Version
0x7 0x1 Padding
0x8 0x4 Application area size (hardcoded to be 0xD8, like in #GetApplicationAreaSize)
0xC 0x34 Reserved

ModelInfo

This is "nn::nfp::ModelInfo". This is a 0x40-byte struct.

Offset Size Description
0x0 0x3 Character ID (same as in #Amiibo ID)
0x3 0x1 Series ID (same as in #Amiibo ID)
0x4 0x2 Numbering ID (byte-swapped value in #Amiibo ID)
0x6 0x1 NFP type (same as in #Amiibo ID)
0x7 0x39 Reserved

Application area version

Note: unofficial name.

Value Description
0xFF Invalid (application area does not exist)
0 Nintendo 3DS
1 Nintendo Wii U
2 Nintendo 3DS (v2?)
3 Nintendo Switch

This value corresponds to hex-digit 7 of application IDs (3DS and Wii U title IDs have 0/1 at that position).

NFC computes it by taking (app_id_be >> 36) & 0xF.

Since Switch games do not follow this trend, the application ID in #Amiibo settings is stored as bswap64(application_id & 0xFFFFFFFF0FFFFFFF | 0x30000000) by #CreateApplicationArea, force-setting the hex-digit (presumably so that older consoles will recognize it).

AdminInfo

This is "nn::nfp::AdminInfo". This is a 0x40-byte struct.

Offset Size Description
0x0 0x8 Application ID of the game owning the application area (original value, see #Amiibo settings)
0x8 0x4 #Amiibo settings #Access ID (byte-swapped)
0xC 0x2 #Amiibo settings terminal ID CRC32 change counter
0xE 0x1 #Amiibo settings flags, bit-shifted: bit0=#Amiibo flag bit4 and so on
0xF 0x1 Unknown, hardcoded to 0x02 (tag type? amiibo version?)
0x10 0x1 #Application area version
0x11 0x7 Padding
0x18 0x28 Reserved

RegisterInfoPrivate

This is "nn::nfp::RegisterInfoPrivate". This is a 0x100-byte struct.

This is almost identical to #RegisterInfo, but containing mii data as a StoreData instead of a CharInfo and more reserved bytes.

Offset Size Description
0x0 0x44 Mii StoreData (see mii services)
0x44 0x4 First write date (see #Date)
0x48 0x29 Amiibo name (NUL-terminated UTF-8 string, converted from UTF-16)
0x71 0x1 Unknown
0x72 0x8E Reserved

NfpData

This is "nn::nfp::NfpData". This is a 0x298-byte struct.

Offset Size Description
0x0 0x1 #Amiibo header magic (Always 0xA5)
0x1 0x1 Reserved
0x2 0x2 #Amiibo header write counter (byte-swapped)
0x4 0x4 #Amiibo settings terminal ID CRC32 (byte-swapped)
0x8 0x38 Reserved
0x40 0x40 Same contents as #CommonInfo
0x80 0x5C #Amiibo settings mii Ver3StoreData, format used in 3DS (see https://www.3dbrew.org/wiki/Mii#Mii_format)
0xDC 0x2 Padding
0xDE 0x2 #Amiibo settings mii CRC16
0xE0 0x8 #Amiibo settings mii StoreDataExtension
0xE8 0x4 First write date (see #Date)
0xEC 0x16 (2*11) Amiibo name (NUL-terminated UTF-16 string, byte-swapped from #Amiibo settings)
0x102 0x1 #Amiibo settings font region
0x103 0x1 Unknown, normally zero
0x104 0x4 #Amiibo settings mii CRC32 (byte-swapped)
0x108 0x14 #Amiibo settings unknown 0x14 bytes, normally zero
0x11c 0x64 Reserved
0x180 0x8 #Amiibo settings modified application ID (byte-swapped)
0x188 0x4 #Amiibo settings #Access ID (byte-swapped)
0x18c 0x2 #Amiibo settings terminal ID CRC32 change counter (byte-swapped)
0x18e 0x1 #Amiibo settings flags (bit-shifted, same as with #AdminInfo)
0x18f 0x1 Hardcoded to 0x02 (tag type? amiibo version?)
0x190 0x1 #Application area version
0x191 0x1 Application ID byte (see #Amiibo settings)
0x192 0x2E Reserved
0x1c0 0xD8 #Application area

BreakType

This is "nn::nfp::BreakType". For more details, see #BreakTag.

Value Description
0 Does no breaking, just flushes
1 Breaks the amiibo data SHA256 HMAC hash (see #Amiibo settings)
2 Breaks the amiibo header magic (see #Amiibo settings)

Value 0 is internally used in some places, aside for #BreakTag commands called externally.

WriteType

This is "nn::nfp::WriteType".

Value Description
0 ?
1 ?

Application area

This is a 0xD8 byte region for per-game amiibo savedata. Only one game may use the application area.

Access ID

Access IDs are game-unique u32s used to access the amiibo application area.

Nintendo 3DS titles

For a list of Nintendo 3DS access IDs, see https://www.3dbrew.org/wiki/Amiibo#Games_using_Amiibo_AppData.

Nintendo Switch titles

Game Access ID
Splatoon 2 0x10162B00
Shovel Knight: Treasure Trove 0x1016E100
The Legend of Zelda: Breath of the Wild 0x1019C800
Super Smash Bros. Ultimate 0x34F80200
Splatoon 3 0x38600500
The Legend of Zelda: Link's Awakening 0x3B440400

Backup data

Note: unofficial name.

Backup data is stored at data:/nfp_backup.dat. It has a total size of 0x1FBD20 bytes, and has the following format:

Offset Size Description
0x0 0x20 #Backup header
0x20 0x7D00 (0x20*1000) #Backup entry header array
0x7D20 0x1F4000 (0x800*1000) #Backup entry data array

There is a maximum of 1000 entries. This can be accessed by #ReadBackupData and #WriteBackupData commands.

Backup header

Note: unofficial name.

This is 0x20 bytes.

Offset Size Description
0x0 0x2 Unknown (zero?)
0x2 0x2 Entry count
0x4 0x2 Next free entry index
0x6 0x2 Unknown (zero?)
0x8 0x8 Unknown (zero?)
0x10 0x8 Unknown (zero?)
0x18 0x4 Unknown (zero?)
0x1C 0x4 CRC32 of the 0x1C bytes above

Backup entry header

Note: unofficial name.

This is 0x20 bytes.

Offset Size Description
0x0 0x1 UUID length
0x1 0xA UUID
0xB 0x1 Padding
0xC 0x2 Packed date (when this entry was written)
0xE 0xE Unknown (zero?)
0x1C 0x4 CRC32 of the 0x1C bytes above

Backup entry data

Note: unofficial name.

This is a 0x800 bytes (per-entry data).

NFC writes here the amiibo #Raw format, while the remaining 0x5E4 bytes are unused.

Amiibo

Raw format

Note: unofficial name.

This is 0x21C bytes.

This is the raw format initially read by NFC (as well as other amiibo dumping tools). It has the following format:

Offset Size Description
0x0 0x8 #NTAG215 data 1
0x8 0x8 #NTAG215 data 2
0x10 0x4 #Amiibo header
0x14 0x20 Encrypted section 1
0x34 0x20 Tag SHA256 HMAC hash: hash over plain tag data, see #Plain format
0x54 0x2C #Amiibo ID entry
0x80 0x20 Data SHA256 HMAC hash: hash over plain data, see #Plain format
0xA0 0x114 Encrypted section 2
0x1B4 0x54 Encrypted section 3
0x208 0x4 #NTAG215 dynamic lock
0x20C 0x10 #NTAG215 config

All non-NTAG215 fields are specific of amiibo (located in the user memory pages of the tag). For more details on the page layout, see https://www.3dbrew.org/wiki/Amiibo.

The three encrypted sections combined in order (a total of 0x188 bytes) are decrypted to get the #Amiibo settings and the #Application area, in that order.

Plain format

This is 0x21C bytes.

Note: unofficial name.

This format contains reordered and decrypted amiibo data:

Offset Size Description
0x0 0x8 #NTAG215 data 2
0x8 0x20 Data SHA256 HMAC hash: hash over 0x1DF bytes, starting at offset 0x29 (#Amiibo header write counter) until #Amiibo ID entry
0x28 0x4 #Amiibo header
0x2C 0xB0 #Amiibo settings
0xDC 0xD8 #Application area
0x1B4 0x20 Tag SHA256 HMAC hash: hash over 0x34 bytes below (#NTAG215 data 1 and #Amiibo ID entry)
0x1D4 0x8 #NTAG215 data 1
0x1DC 0x2C #Amiibo ID entry
0x208 0x4 #NTAG215 dynamic lock
0x20C 0x10 #NTAG215 config

When converting from #Raw format to #Plain format, both SHA256 HMAC hashes are tested, otherwise an error is returned internally.

NTAG215 data 1

This is 0x8 bytes.

Offset Size Description
0x0 0x8 NTAG215 9-byte manufacturer serial number (first 8 bytes)

NTAG215 data 2

This is 0x8 bytes.

Offset Size Description
0x0 0x1 NTAG215 9-byte manufacturer serial number (last byte)
0x1 0x1 Internal
0x2 0x2 Static lock bytes
0x4 0x4 Capability Container (CC) bytes

NFC checks that the static lock bytes match 0xE00F when converting from #Raw format to #Plain format.

NTAG215 dynamic lock

This is 0x4 bytes.

Offset Size Description
0x0 0x3 Dynamic lock bytes
0x3 0x1 RFUI

NFC checks the dynamic lock state when converting from #Raw format to #Plain format.

NTAG215 config

This is 0x10 bytes.

Offset Size Description
0x0 0x4 CFG0
0x4 0x4 CFG1
0x8 0x4 PWD
0xC 0x2 PACK
0xE 0x2 RFUI

NFC checks that the CFG0 and CFG1 match 0x4000000 and 0x5F when converting from #Raw format to #Plain format.

Amiibo header

This is 0x4 bytes.

Note: unofficial name.

Offset Size Description
0x0 0x1 Magic (0xA5)
0x1 0x2 Write counter (big-endian)
0x3 0x1 Version (0x00)

Amiibo ID

This is 0x8 bytes.

Offset Size Description
0x0 0x3 Character ID: bits0-9 = game ID, bits10-15 = character ID, bits16-23 = character variant
0x3 0x1 Series ID
0x4 0x2 Numbering ID (big-endian)
0x6 0x1 NFP type (figurine type)
0x7 0x1 Version? (0x02)

Amiibo ID entry

This is 0x2C bytes.

Note: unofficial name.

Offset Size Description
0x0 0x8 #Amiibo ID
0x8 0x4 Unknown
0xC 0x20 Unknown, maybe some hash

Amiibo flag

Bit Mask Description
4 0x10 Initialized in console settings
5 0x20 Application area exists (was created by some game)

Amiibo date

This is a date packed in 2 bytes:

Bits Description
0-4 Day
5-8 Month
9-15 Year (relative to 2000)

Amiibo settings

This is 0xB0 bytes.

Note: unofficial name.

Offset Size Description
0x0 0x1 Font region (bits0-3) and #Amiibo flag (bits4-7)
0x1 0x2 Country code ID
0x2 0x2 Counter of the times the terminal ID CRC32 has changed (big-endian)
0x4 0x2 First write date (big-endian, see #Amiibo date for format in little-endian)
0x6 0x2 Last write date (big-endian, see #Amiibo date for format in little-endian)
0x8 0x4 CRC32 of NFC terminal ID (8 bytes, see below)
0xC 0x14 (2*10) Amiibo name (UTF16-BE, not null-terminated)
0x20 0x5C Mii in Ver3StoreData format, see https://www.3dbrew.org/wiki/Mii#Mii_format
0x7C 0x2 Unused/padding
0x7E 0x2 CRC16 of the mii data (0x60 bytes, last 4-bytes zeroed)
0x80 0x8 Application ID of the game owning the application area (big-endian) (modified, see #Application area version)
0x88 0x2 Write counter (big-endian)
0x8A 0x4 Access ID of the game owning the application area (big-endian)
0x8E 0x1 Application ID byte: (Application ID >> 28) & 0xFF
0x8F 0x1 Unknown1
0x90 0x8 Mii StoreDataExtension
0x98 0x14 Unknown2
0xAC 0x4 CRC32 of mii data (Ver3StoreData + pad + CRC16) + Application ID byte + Unknown1 + StoreDataExtension + Unknown2 (total of 0x7E bytes)

The country code ID is zeroed when calling #SetRegisterInfoPrivate.

The application ID byte contains the original application ID hex-digit (only used for Switcj games, see #Application area version), so it can be to restore the original value (which is needed for #GetAdminInfo).

The terminal ID is a randomly-generated 8-byte value that is re-generated every time #Initialize is called (thus every nfc/nfp/mifare session), and saved at data:/nfc_terminal_id.dat.

Play report

In nfp #Unmount and #Format commands, and if setting nfp!play_report is true, a play report is sent with the following fields: Uid, CharacterId, NumberingId, SeriesId, NfpType (from the current #Amiibo ID), ApplicationId, AccessInfo, DeviceType.

RomFS

[9.0.0+] The nfc-sysmodule RomFS contains:

 ST21NFCD_01_05_6811.bin

These are firmware files for the NFC IC inside Switch Lite units.