NFC services: Difference between revisions
No edit summary |
Document relevant v3 amiibo NFP changes |
||
| (27 intermediate revisions by 4 users not shown) | |||
| Line 40: | Line 40: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || Initialize | | 0 || [[#Initialize]] | ||
|- | |- | ||
| 1 || Finalize | | 1 || [[#Finalize]] | ||
|- | |- | ||
| 2 || ListDevices | | 2 || [[#ListDevices]] | ||
|- | |- | ||
| 3 || StartDetection | | 3 || [[#StartDetection_2|StartDetection]] | ||
|- | |- | ||
| 4 || StopDetection | | 4 || [[#StopDetection]] | ||
|- | |- | ||
| 5 || Read | | 5 || [[#ReadMifare|Read]] | ||
|- | |- | ||
| 6 || Write | | 6 || [[#WriteMifare|Write]] | ||
|- | |- | ||
| 7 || GetTagInfo | | 7 || [[#GetTagInfo]] | ||
|- | |- | ||
| 8 || GetActivateEventHandle | | 8 || [[#AttachActivateEvent|GetActivateEventHandle]] | ||
|- | |- | ||
| 9 || GetDeactivateEventHandle | | 9 || [[#AttachDeactivateEvent|GetDeactivateEventHandle]] | ||
|- | |- | ||
| 10 || GetState | | 10 || [[#GetState]] | ||
|- | |- | ||
| 11 || GetDeviceState | | 11 || [[#GetDeviceState]] | ||
|- | |- | ||
| 12 || GetNpadId | | 12 || [[#GetNpadId]] | ||
|- | |- | ||
| 13 || [3.0.0+] GetAvailabilityChangeEventHandle | | 13 || [3.0.0+] [[#AttachAvailabilityChangeEvent|GetAvailabilityChangeEventHandle]] | ||
|} | |} | ||
| Line 86: | Line 86: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || InitializeOld | | 0 || [[#Initialize|InitializeOld]] | ||
|- | |- | ||
| 1 || FinalizeOld | | 1 || [[#Finalize|FinalizeOld]] | ||
|- | |- | ||
| 2 || GetStateOld | | 2 || [[#GetStateOld]] | ||
|- | |- | ||
| 3 || IsNfcEnabledOld | | 3 || [[#IsNfcEnabledOld]] | ||
|- | |- | ||
| 400 || [4.0.0+] Initialize | | 400 || [4.0.0+] [[#Initialize]] | ||
|- | |- | ||
| 401 || [4.0.0+] Finalize | | 401 || [4.0.0+] [[#Finalize]] | ||
|- | |- | ||
| 402 || [4.0.0+] GetState | | 402 || [4.0.0+] [[#GetState]] | ||
|- | |- | ||
| 403 || [4.0.0+] IsNfcEnabled | | 403 || [4.0.0+] [[#IsNfcEnabled]] | ||
|- | |- | ||
| 404 || [4.0.0+] ListDevices | | 404 || [4.0.0+] [[#ListDevices]] | ||
|- | |- | ||
| 405 || [4.0.0+] GetDeviceState | | 405 || [4.0.0+] [[#GetDeviceState]] | ||
|- | |- | ||
| 406 || [4.0.0+] GetNpadId | | 406 || [4.0.0+] [[#GetNpadId]] | ||
|- | |- | ||
| 407 || [4.0.0+] AttachAvailabilityChangeEvent | | 407 || [4.0.0+] [[#AttachAvailabilityChangeEvent]] | ||
|- | |- | ||
| 408 || [4.0.0+] StartDetection | | 408 || [4.0.0+] [[#StartDetection]] | ||
|- | |- | ||
| 409 || [4.0.0+] StopDetection | | 409 || [4.0.0+] [[#StopDetection]] | ||
|- | |- | ||
| 410 || [4.0.0+] GetTagInfo | | 410 || [4.0.0+] [[#GetTagInfo]] | ||
|- | |- | ||
| 411 || [4.0.0+] AttachActivateEvent | | 411 || [4.0.0+] [[#AttachActivateEvent]] | ||
|- | |- | ||
| 412 || [4.0.0+] AttachDeactivateEvent | | 412 || [4.0.0+] [[#AttachDeactivateEvent]] | ||
|- | |- | ||
| 1000 || [4.0.0+] ReadMifare | | 1000 || [4.0.0+] [[#ReadMifare]] | ||
|- | |- | ||
| 1001 || [4.0.0+] WriteMifare | | 1001 || [4.0.0+] [[#WriteMifare]] | ||
|- | |- | ||
| 1300 || [4.0.0+] SendCommandByPassThrough | | 1300 || [4.0.0+] [[#SendCommandByPassThrough]] | ||
|- | |- | ||
| 1301 || [4.0.0+] KeepPassThroughSession | | 1301 || [4.0.0+] [[#KeepPassThroughSession]] | ||
|- | |- | ||
| 1302 || [4.0.0+] ReleasePassThroughSession | | 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 = | = nfc:sys = | ||
| Line 148: | Line 193: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || Initialize | | 0 || [[#Initialize]] | ||
|- | |- | ||
| 1 || Finalize | | 1 || [[#Finalize]] | ||
|- | |- | ||
| 2 || GetStateOld | | 2 || [[#GetStateOld]] | ||
|- | |- | ||
| 3 || IsNfcEnabledOld | | 3 || [[#IsNfcEnabledOld]] | ||
|- | |- | ||
| 100 || SetNfcEnabledOld | | 100 || [[#SetNfcEnabledOld]] | ||
|- | |- | ||
| 400 || [4.0.0+] InitializeSystem | | 400 || [4.0.0+] [[#Initialize|InitializeSystem]] | ||
|- | |- | ||
| 401 || [4.0.0+] FinalizeSystem | | 401 || [4.0.0+] [[#Finalize|FinalizeSystem]] | ||
|- | |- | ||
| 402 || [4.0.0+] GetState | | 402 || [4.0.0+] [[#GetState]] | ||
|- | |- | ||
| 403 || [4.0.0+] IsNfcEnabled | | 403 || [4.0.0+] [[#IsNfcEnabled]] | ||
|- | |- | ||
| 404 || [4.0.0+] ListDevices | | 404 || [4.0.0+] [[#ListDevices]] | ||
|- | |- | ||
| 405 || [4.0.0+] GetDeviceState | | 405 || [4.0.0+] [[#GetDeviceState]] | ||
|- | |- | ||
| 406 || [4.0.0+] GetNpadId | | 406 || [4.0.0+] [[#GetNpadId]] | ||
|- | |- | ||
| 407 || [4.0.0+] AttachAvailabilityChangeEvent | | 407 || [4.0.0+] [[#AttachAvailabilityChangeEvent]] | ||
|- | |- | ||
| 408 || [4.0.0+] StartDetection | | 408 || [4.0.0+] [[#StartDetection]] | ||
|- | |- | ||
| 409 || [4.0.0+] StopDetection | | 409 || [4.0.0+] [[#StopDetection]] | ||
|- | |- | ||
| 410 || [4.0.0+] GetTagInfo | | 410 || [4.0.0+] [[#GetTagInfo]] | ||
|- | |- | ||
| 411 || [4.0.0+] AttachActivateEvent | | 411 || [4.0.0+] [[#AttachActivateEvent]] | ||
|- | |- | ||
| 412 || [4.0.0+] AttachDeactivateEvent | | 412 || [4.0.0+] [[#AttachDeactivateEvent]] | ||
|- | |- | ||
| 500 || [4.0.0+] SetNfcEnabled | | 500 || [4.0.0+] [[#SetNfcEnabled]] | ||
|- | |- | ||
| 510 || [7.0.0+] OutputTestWave | | 510 || [7.0.0+] [[#OutputTestWave]] | ||
|- | |- | ||
| 1000 || [4.0.0+] ReadMifare | | 1000 || [4.0.0+] [[#ReadMifare]] | ||
|- | |- | ||
| 1001 || [4.0.0+] WriteMifare | | 1001 || [4.0.0+] [[#WriteMifare]] | ||
|- | |- | ||
| 1300 || [4.0.0+] SendCommandByPassThrough | | 1300 || [4.0.0+] [[#SendCommandByPassThrough]] | ||
|- | |- | ||
| 1301 || [4.0.0+] KeepPassThroughSession | | 1301 || [4.0.0+] [[#KeepPassThroughSession]] | ||
|- | |- | ||
| 1302 || [4.0.0+] ReleasePassThroughSession | | 1302 || [4.0.0+] [[#ReleasePassThroughSession]] | ||
|} | |} | ||
= nfp:user = | === 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". | This is "nn::nfp::detail::IUserManager". | ||
| Line 206: | Line 270: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || CreateUserInterface | | 0 || [[#Create*Interface|CreateUserInterface]] | ||
|} | |} | ||
== IUser == | === IUser === | ||
This is "nn::nfp::detail::IUser". | This is "nn::nfp::detail::IUser". | ||
| Line 216: | Line 280: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || Initialize | | 0 || [[#Initialize*|Initialize]] | ||
|- | |||
| 1 || [[#Finalize*|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". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || [[#Create*Interface|CreateSystemInterface]] | |||
|} | |||
=== ISystem === | |||
This is "nn::nfp::detail::ISystem". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || [[#Initialize*|InitializeSystem]] | |||
|- | |- | ||
| 1 || Finalize | | 1 || [[#Finalize*|FinalizeSystem]] | ||
|- | |- | ||
| 2 || ListDevices | | 2 || [[#ListDevices]] | ||
|- | |- | ||
| 3 || StartDetection | | 3 || [[#StartDetection]] | ||
|- | |- | ||
| 4 || StopDetection | | 4 || [[#StopDetection]] | ||
|- | |- | ||
| 5 || Mount | | 5 || [[#Mount]] | ||
|- | |- | ||
| 6 || Unmount | | 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 = | == nfp:dbg == | ||
This is "nn::nfp::detail::IDebugManager". | This is "nn::nfp::detail::IDebugManager". | ||
| Line 274: | Line 408: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || CreateDebugInterface | | 0 || [[#Create*Interface|CreateDebugInterface]] | ||
|} | |} | ||
== IDebug == | === IDebug === | ||
This is "nn::nfp::detail::IDebug". | This is "nn::nfp::detail::IDebug". | ||
| Line 284: | Line 418: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || InitializeDebug | | 0 || [[#Initialize*|InitializeDebug]] | ||
|- | |- | ||
| 1 || FinalizeDebug | | 1 || [[#Finalize*|FinalizeDebug]] | ||
|- | |- | ||
| 2 || ListDevices | | 2 || [[#ListDevices]] | ||
|- | |- | ||
| 3 || StartDetection | | 3 || [[#StartDetection]] | ||
|- | |- | ||
| 4 || StopDetection | | 4 || [[#StopDetection]] | ||
|- | |- | ||
| 5 || Mount | | 5 || [[#Mount]] | ||
|- | |- | ||
| 6 || Unmount | | 6 || [[#Unmount]] | ||
|- | |- | ||
| 7 || OpenApplicationArea | | 7 || [[#OpenApplicationArea]] | ||
|- | |- | ||
| 8 || GetApplicationArea | | 8 || [[#GetApplicationArea]] | ||
|- | |- | ||
| 9 || SetApplicationArea | | 9 || [[#SetApplicationArea]] | ||
|- | |- | ||
| 10 || Flush | | 10 || [[#Flush]] | ||
|- | |- | ||
| 11 || Restore | | 11 || [[#Restore]] | ||
|- | |- | ||
| 12 || CreateApplicationArea | | 12 || [[#CreateApplicationArea]] | ||
|- | |- | ||
| 13 || GetTagInfo | | 13 || [[#GetTagInfo]] | ||
|- | |- | ||
| 14 || GetRegisterInfo | | 14 || [[#GetRegisterInfo]] | ||
|- | |- | ||
| 15 || GetCommonInfo | | 15 || [[#GetCommonInfo]] | ||
|- | |- | ||
| 16 || GetModelInfo | | 16 || [[#GetModelInfo]] | ||
|- | |- | ||
| 17 || AttachActivateEvent | | 17 || [[#AttachActivateEvent]] | ||
|- | |- | ||
| 18 || AttachDeactivateEvent | | 18 || [[#AttachDeactivateEvent]] | ||
|- | |- | ||
| 19 || GetState | | 19 || [[#GetState]] | ||
|- | |- | ||
| 20 || GetDeviceState | | 20 || [[#GetDeviceState]] | ||
|- | |- | ||
| 21 || GetNpadId | | 21 || [[#GetNpadId]] | ||
|- | |- | ||
| 22 || | | 22 || [[#GetApplicationAreaSize]] | ||
|- | |- | ||
| 23 || [3.0.0+] AttachAvailabilityChangeEvent | | 23 || [3.0.0+] [[#AttachAvailabilityChangeEvent]] | ||
|- | |- | ||
| 24 || [3.0.0+] RecreateApplicationArea | | 24 || [3.0.0+] [[#RecreateApplicationArea]] | ||
|- | |- | ||
| 100 || Format | | 100 || [[#Format]] | ||
|- | |- | ||
| 101 || GetAdminInfo | | 101 || [[#GetAdminInfo]] | ||
|- | |- | ||
| 102 || | | 102 || [[#GetRegisterInfoPrivate]] | ||
|- | |- | ||
| 103 || | | 103 || [[#SetRegisterInfoPrivate]] | ||
|- | |- | ||
| 104 || DeleteRegisterInfo | | 104 || [[#DeleteRegisterInfo]] | ||
|- | |- | ||
| 105 || DeleteApplicationArea | | 105 || [[#DeleteApplicationArea]] | ||
|- | |- | ||
| 106 || ExistsApplicationArea | | 106 || [[#ExistsApplicationArea]] | ||
|- | |- | ||
| 200 || GetAll | | 200 || [[#GetAll]] | ||
|- | |- | ||
| 201 || SetAll | | 201 || [[#SetAll]] | ||
|- | |- | ||
| 202 || FlushDebug | | 202 || [[#FlushDebug]] | ||
|- | |- | ||
| 203 || BreakTag | | 203 || [[#BreakTag]] | ||
|- | |- | ||
| 204 || ReadBackupData | | 204 || [[#ReadBackupData]] | ||
|- | |- | ||
| 205 || WriteBackupData | | 205 || [[#WriteBackupData]] | ||
|- | |- | ||
| 206 || WriteNtf | | 206 || [[#WriteNtf]] | ||
|- | |- | ||
| 300 || [3.0.0-3.0.2] | | 300 || [3.0.0-3.0.2] | ||
| Line 393: | Line 527: | ||
|} | |} | ||
= nfp: | ==== GetAll ==== | ||
This is "nn::nfp:: | 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]]). | |||
[20.5.0+] Amiibo version is no longer hardcoded to value 2, and actually set from the corresponding amiibo ID bits. | |||
==== 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 [[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. | |||
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]]. | |||
[20.5.0+] Internal check "amiibo_version == 2" was changed to "(amiibo_version & 0xFE) == 2" to also cover new v3 amiibos. | |||
=== 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. | |||
[20.5.0+] [[#Amiibo settings]] Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far). | |||
=== 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]]. | |||
[20.5.0+] Internal check "amiibo_version == 2" was changed to "(amiibo_version & 0xFE) == 2" to also cover new v3 amiibos. | |||
=== 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. | |||
[20.5.0+] [[#Amiibo settings]] Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far). | |||
=== 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. | |||
[20.5.0+] Now the Mii CRC32 in [[#Amiibo settings]] is properly computed for v3 amiibos, while for v2 amiibos (as it was done so far)the field is set to a random u16 value. | |||
=== 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. | |||
[20.5.0+] Amiibo version is no longer hardcoded to value 2, and actually set from the corresponding amiibo ID bits. | |||
=== 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. | |||
[20.5.0+] [[#Amiibo settings]] Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far). | |||
=== 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. | |||
[20.5.0+] Now the Mii CRC32 in [[#Amiibo settings]] is properly computed for v3 amiibos, while for v2 amiibos (as it was done so far)the field is set to a random u16 value. | |||
=== 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. | |||
[20.5.0+] [[#Amiibo settings]] Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far). | |||
=== 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x10 || Data | |||
|- | |||
| 0x10 || 0x1 || Block index | |||
|- | |||
| 0x11 || 0x7 || Padding | |||
|- | |||
| 0x18 || 0x10 || [[#MifareKey]] | |||
|} | |||
= State = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Description | |||
|- | |||
| 0 || NonInitialized | |||
|- | |||
| 1 || Initialized | |||
|} | |||
= DeviceState = | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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 = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Description | |||
|- | |||
| 0 || Amiibo | |||
|} | |||
= MountTarget = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Bit || Mask || Description | |||
|- | |||
| 0 || 1 || ROM | |||
|- | |||
| 1 || 2 || RAM | |||
|} | |||
= Date = | |||
This is "nn::nfp::Date": | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x2 || Year | |||
|- | |||
| 0x2 || 0x1 || Month | |||
|- | |||
| 0x3 || 0x1 || Day | |||
|} | |||
= TagInfo = | |||
This is "nn::nfp::TagInfo". This is a 0x58-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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 || Font region | |||
|- | |||
| 0x72 || 0x8E || Reserved | |||
|} | |||
= NfpData = | |||
This is "nn::nfp::NfpData". This is a 0x298-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Description | |||
|- | |||
| 0 || Does no breaking, just flushes | |||
|- | |||
| 1 || Breaks the amiibo data SHA256 HMAC hash (see [[#Plain format]]) | |||
|- | |||
| 2 || Breaks the amiibo header magic (see [[#Amiibo header]]) | |||
|} | |||
= WriteType = | |||
This is "nn::nfp::WriteType". | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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 == | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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 [[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 || 0x1 || [20.5.0+] Backup entry type, depending on amiibo version (0 = v2, 1 = v3), previously reserved/zero | |||
|- | |||
| 0xF || 0xD || Unknown (reserved?) | |||
|- | |||
| 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. | |||
[20.5.0+] The entry data stored is different for v3 amiibos: the first 0x80 bytes of the [[#Raw format]] are stored, then followed by 0x40 internal bytes from the corresponding Noft2 object (what exactly?) and finally followed by the remaining (0x19C) bytes of the raw data, thus now using 0x25C bytes of the entry data (and leaving the remaining 0x5A4 bytes 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" | {| 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]]. | ||
This is | |||
== NTAG215 config == | |||
This is 0x10 bytes. | |||
{| class="wikitable" border="1" | {| 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" | {| class="wikitable" border="1" | ||
|- | |- | ||
! | ! Offset || Size || Description | ||
|- | |||
| 0x0 || 0x1 || Font region (bits0-3) and [[#Amiibo flag]] (bits4-7) | |||
|- | |||
| 0x1 || 0x1 || 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) (big-endian) | |||
|- | |||
| 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 (appears to be reserved for v2 amiibos and used in v3 amiibos, for maybe application area-related purposes?) | |||
|- | |||
| 0xAC || 0x4 || CRC32 of mii data (Ver3StoreData + pad + CRC16) + Application ID byte + Unknown1 + StoreDataExtension + Unknown2 (total of 0x7E bytes) (big-endian) | |||
|} | |} | ||
The country code ID is zeroed when calling [[#SetRegisterInfoPrivate]]. | |||
The application ID byte contains the original application ID hex-digit (only used for Switch 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]] | ||
= 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. | |||
Latest revision as of 22:04, 9 December 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".
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).
[20.5.0+] Amiibo version is no longer hardcoded to value 2, and actually set from the corresponding amiibo ID bits.
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.
[20.5.0+] Internal check "amiibo_version == 2" was changed to "(amiibo_version & 0xFE) == 2" to also cover new v3 amiibos.
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.
[20.5.0+] #Amiibo settings Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far).
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.
[20.5.0+] Internal check "amiibo_version == 2" was changed to "(amiibo_version & 0xFE) == 2" to also cover new v3 amiibos.
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.
[20.5.0+] #Amiibo settings Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far).
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.
[20.5.0+] Now the Mii CRC32 in #Amiibo settings is properly computed for v3 amiibos, while for v2 amiibos (as it was done so far)the field is set to a random u16 value.
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.
[20.5.0+] Amiibo version is no longer hardcoded to value 2, and actually set from the corresponding amiibo ID bits.
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.
[20.5.0+] #Amiibo settings Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far).
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.
[20.5.0+] Now the Mii CRC32 in #Amiibo settings is properly computed for v3 amiibos, while for v2 amiibos (as it was done so far)the field is set to a random u16 value.
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.
[20.5.0+] #Amiibo settings Field `Unknown2` always zeroed for v3 amiibos, while it it conditionally zeroed for v2 amiibos (as it was done so far).
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 | Font region |
| 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 #Plain format) |
| 2 | Breaks the amiibo header magic (see #Amiibo header) |
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 | 0x1 | [20.5.0+] Backup entry type, depending on amiibo version (0 = v2, 1 = v3), previously reserved/zero |
| 0xF | 0xD | Unknown (reserved?) |
| 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.
[20.5.0+] The entry data stored is different for v3 amiibos: the first 0x80 bytes of the #Raw format are stored, then followed by 0x40 internal bytes from the corresponding Noft2 object (what exactly?) and finally followed by the remaining (0x19C) bytes of the raw data, thus now using 0x25C bytes of the entry data (and leaving the remaining 0x5A4 bytes 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 | 0x1 | 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) (big-endian) |
| 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 (appears to be reserved for v2 amiibos and used in v3 amiibos, for maybe application area-related purposes?) |
| 0xAC | 0x4 | CRC32 of mii data (Ver3StoreData + pad + CRC16) + Application ID byte + Unknown1 + StoreDataExtension + Unknown2 (total of 0x7E bytes) (big-endian) |
The country code ID is zeroed when calling #SetRegisterInfoPrivate.
The application ID byte contains the original application ID hex-digit (only used for Switch 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.