https://switchbrew.org/w/api.php?action=feedcontributions&user=XorTroll&feedformat=atomNintendo Switch Brew - User contributions [en]2024-03-28T22:54:30ZUser contributionsMediaWiki 1.35.8https://switchbrew.org/w/index.php?title=NFC_services&diff=11680NFC services2022-04-21T18:07:42Z<p>XorTroll: Document some nfp IDebug commands and types</p>
<hr />
<div>= nfc:am =<br />
This is "nn::nfc::am::detail::IAmManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateAmInterface<br />
|}<br />
<br />
== IAm ==<br />
This is "nn::nfc::am::detail::IAm".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || Initialize<br />
|-<br />
| 1 || Finalize<br />
|-<br />
| 2 || NotifyForegroundApplet<br />
|}<br />
<br />
= nfc:mf:u =<br />
This is "nn::nfc::mifare::detail::IUserManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateUserInterface<br />
|}<br />
<br />
== IUser ==<br />
This is "nn::nfc::mifare::detail::IUser".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize]]<br />
|-<br />
| 1 || [[#Finalize]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection_2|StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#ReadMifare|Read]]<br />
|-<br />
| 6 || [[#WriteMifare|Write]]<br />
|-<br />
| 7 || [[#GetTagInfo]]<br />
|-<br />
| 8 || [[#AttachActivateEvent|GetActivateEventHandle]]<br />
|-<br />
| 9 || [[#AttachDeactivateEvent|GetDeactivateEventHandle]]<br />
|-<br />
| 10 || [[#GetState]]<br />
|-<br />
| 11 || [[#GetDeviceState]]<br />
|-<br />
| 12 || [[#GetNpadId]]<br />
|-<br />
| 13 || [3.0.0+] [[#AttachAvailabilityChangeEvent|GetAvailabilityChangeEventHandle]]<br />
|}<br />
<br />
= nfc:user =<br />
This is "nn::nfc::detail::IUserManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateUserInterface<br />
|}<br />
<br />
== IUser ==<br />
This is "nn::nfc::detail::IUser".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize|InitializeOld]]<br />
|-<br />
| 1 || [[#Finalize|FinalizeOld]]<br />
|-<br />
| 2 || [[#GetStateOld]]<br />
|-<br />
| 3 || [[#IsNfcEnabledOld]]<br />
|-<br />
| 400 || [4.0.0+] [[#Initialize]]<br />
|-<br />
| 401 || [4.0.0+] [[#Finalize]]<br />
|-<br />
| 402 || [4.0.0+] [[#GetState]]<br />
|-<br />
| 403 || [4.0.0+] [[#IsNfcEnabled]]<br />
|-<br />
| 404 || [4.0.0+] [[#ListDevices]]<br />
|-<br />
| 405 || [4.0.0+] [[#GetDeviceState]]<br />
|-<br />
| 406 || [4.0.0+] [[#GetNpadId]]<br />
|-<br />
| 407 || [4.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 408 || [4.0.0+] [[#StartDetection]]<br />
|-<br />
| 409 || [4.0.0+] [[#StopDetection]]<br />
|-<br />
| 410 || [4.0.0+] [[#GetTagInfo]]<br />
|-<br />
| 411 || [4.0.0+] [[#AttachActivateEvent]]<br />
|-<br />
| 412 || [4.0.0+] [[#AttachDeactivateEvent]]<br />
|-<br />
| 1000 || [4.0.0+] [[#ReadMifare]]<br />
|-<br />
| 1001 || [4.0.0+] [[#WriteMifare]]<br />
|-<br />
| 1300 || [4.0.0+] [[#SendCommandByPassThrough]]<br />
|-<br />
| 1301 || [4.0.0+] [[#KeepPassThroughSession]]<br />
|-<br />
| 1302 || [4.0.0+] [[#ReleasePassThroughSession]]<br />
|}<br />
<br />
=== GetStateOld ===<br />
No input, returns an output u32.<br />
<br />
=== IsNfcEnabledOld ===<br />
No input, returns an output bool.<br />
<br />
This runs the same code as [[#IsNfcEnabled]].<br />
<br />
=== GetState ===<br />
No input, returns an output u32.<br />
<br />
This replaces [[#GetStateOld]].<br />
<br />
=== IsNfcEnabled ===<br />
No input, returns an output bool.<br />
<br />
This replaces [[#IsNfcEnabledOld]].<br />
<br />
=== StartDetection ===<br />
Takes an input [[#DeviceHandle]] and a [[#NfcProtocol]], no output.<br />
<br />
=== StopDetection ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== ReadMifare ===<br />
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.<br />
<br />
sdknso passes the same user-specified array-count for both buffers.<br />
<br />
=== WriteMifare ===<br />
Takes an input [[#DeviceHandle]], a type-0x5 input buffer containing an array of [[#MifareWriteBlockParameter]], no output.<br />
<br />
=== SendCommandByPassThrough ===<br />
Takes an input [[#DeviceHandle]], a nn::TimeSpan timeout, a type-0x6 output buffer, a type-0x5 input buffer, returns an output u32 out_size.<br />
<br />
sdknso copies the output u32 into an u64. This is the actual size which was copied into the output buffer.<br />
<br />
This allows using a raw NFC command. The input buffer contains the command data (id + params), and the output buffer contains the response.<br />
<br />
=== KeepPassThroughSession ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== ReleasePassThroughSession ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
= nfc:sys =<br />
This is "nn::nfc::detail::ISystemManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateSystemInterface<br />
|}<br />
<br />
== ISystem ==<br />
This is "nn::nfc::detail::ISystem".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize]]<br />
|-<br />
| 1 || [[#Finalize]]<br />
|-<br />
| 2 || [[#GetStateOld]]<br />
|-<br />
| 3 || [[#IsNfcEnabledOld]]<br />
|-<br />
| 100 || [[#SetNfcEnabledOld]]<br />
|-<br />
| 400 || [4.0.0+] [[#Initialize|InitializeSystem]]<br />
|-<br />
| 401 || [4.0.0+] [[#Finalize|FinalizeSystem]]<br />
|-<br />
| 402 || [4.0.0+] [[#GetState]]<br />
|-<br />
| 403 || [4.0.0+] [[#IsNfcEnabled]]<br />
|-<br />
| 404 || [4.0.0+] [[#ListDevices]]<br />
|-<br />
| 405 || [4.0.0+] [[#GetDeviceState]]<br />
|-<br />
| 406 || [4.0.0+] [[#GetNpadId]]<br />
|-<br />
| 407 || [4.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 408 || [4.0.0+] [[#StartDetection]]<br />
|-<br />
| 409 || [4.0.0+] [[#StopDetection]]<br />
|-<br />
| 410 || [4.0.0+] [[#GetTagInfo]]<br />
|-<br />
| 411 || [4.0.0+] [[#AttachActivateEvent]]<br />
|-<br />
| 412 || [4.0.0+] [[#AttachDeactivateEvent]]<br />
|-<br />
| 500 || [4.0.0+] [[#SetNfcEnabled]]<br />
|-<br />
| 510 || [7.0.0+] [[#OutputTestWave]]<br />
|-<br />
| 1000 || [4.0.0+] [[#ReadMifare]]<br />
|-<br />
| 1001 || [4.0.0+] [[#WriteMifare]]<br />
|-<br />
| 1300 || [4.0.0+] [[#SendCommandByPassThrough]]<br />
|-<br />
| 1301 || [4.0.0+] [[#KeepPassThroughSession]]<br />
|-<br />
| 1302 || [4.0.0+] [[#ReleasePassThroughSession]]<br />
|}<br />
<br />
=== SetNfcEnabledOld ===<br />
Takes an input bool, no output.<br />
<br />
This runs the same code as [[#SetNfcEnabled]].<br />
<br />
=== SetNfcEnabled ===<br />
Takes an input bool, no output.<br />
<br />
This replaces [[#SetNfcEnabledOld]].<br />
<br />
=== OutputTestWave ===<br />
Takes an input bool and a [[#TestWaveType]], no output.<br />
<br />
= nfp services =<br />
<br />
These are used for amiibo support (nfp = Nintendo Figurine Protocol, internal name for amiibo protocol)<br />
<br />
== nfp:user ==<br />
This is "nn::nfp::detail::IUserManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Create*Interface|CreateUserInterface]]<br />
|}<br />
<br />
=== IUser ===<br />
This is "nn::nfp::detail::IUser".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize*|Initialize]]<br />
|-<br />
| 1 || [[#Finalize*|Finalize]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#Mount]]<br />
|-<br />
| 6 || [[#Unmount]]<br />
|-<br />
| 7 || [[#OpenApplicationArea]]<br />
|-<br />
| 8 || [[#GetApplicationArea]]<br />
|-<br />
| 9 || [[#SetApplicationArea]]<br />
|-<br />
| 10 || [[#Flush]]<br />
|-<br />
| 11 || [[#Restore]]<br />
|-<br />
| 12 || [[#CreateApplicationArea]]<br />
|-<br />
| 13 || [[#GetTagInfo]]<br />
|-<br />
| 14 || [[#GetRegisterInfo]]<br />
|-<br />
| 15 || [[#GetCommonInfo]]<br />
|-<br />
| 16 || [[#GetModelInfo]]<br />
|-<br />
| 17 || [[#AttachActivateEvent]]<br />
|-<br />
| 18 || [[#AttachDeactivateEvent]]<br />
|-<br />
| 19 || [[#GetState]]<br />
|-<br />
| 20 || [[#GetDeviceState]]<br />
|-<br />
| 21 || [[#GetNpadId]]<br />
|-<br />
| 22 || [[#GetApplicationAreaSize]]<br />
|-<br />
| 23 || [3.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 24 || [3.0.0+] [[#RecreateApplicationArea]]<br />
|}<br />
<br />
== nfp:sys ==<br />
This is "nn::nfp::detail::ISystemManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Create*Interface|CreateSystemInterface]]<br />
|}<br />
<br />
=== ISystem ===<br />
This is "nn::nfp::detail::ISystem".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize*|InitializeSystem]]<br />
|-<br />
| 1 || [[#Finalize*|FinalizeSystem]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#Mount]]<br />
|-<br />
| 6 || [[#Unmount]]<br />
|-<br />
| 10 || [[#Flush]]<br />
|-<br />
| 11 || [[#Restore]]<br />
|-<br />
| 13 || [[#GetTagInfo]]<br />
|-<br />
| 14 || [[#GetRegisterInfo]]<br />
|-<br />
| 15 || [[#GetCommonInfo]]<br />
|-<br />
| 16 || [[#GetModelInfo]]<br />
|-<br />
| 17 || [[#AttachActivateEvent]]<br />
|-<br />
| 18 || [[#AttachDeactivateEvent]]<br />
|-<br />
| 19 || [[#GetState]]<br />
|-<br />
| 20 || [[#GetDeviceState]]<br />
|-<br />
| 21 || [[#GetNpadId]]<br />
|-<br />
| 23 || [3.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 100 || [[#Format]]<br />
|-<br />
| 101 || [[#GetAdminInfo]]<br />
|-<br />
| 102 || [[#GetRegisterInfoPrivate]]<br />
|-<br />
| 103 || [[#SetRegisterInfoPrivate]]<br />
|-<br />
| 104 || [[#DeleteRegisterInfo]]<br />
|-<br />
| 105 || [[#DeleteApplicationArea]]<br />
|-<br />
| 106 || [[#ExistsApplicationArea]]<br />
|}<br />
<br />
== nfp:dbg ==<br />
This is "nn::nfp::detail::IDebugManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Create*Interface|CreateDebugInterface]]<br />
|}<br />
<br />
=== IDebug ===<br />
This is "nn::nfp::detail::IDebug".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize*|InitializeDebug]]<br />
|-<br />
| 1 || [[#Finalize*|FinalizeDebug]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#Mount]]<br />
|-<br />
| 6 || [[#Unmount]]<br />
|-<br />
| 7 || [[#OpenApplicationArea]]<br />
|-<br />
| 8 || [[#GetApplicationArea]]<br />
|-<br />
| 9 || [[#SetApplicationArea]]<br />
|-<br />
| 10 || [[#Flush]]<br />
|-<br />
| 11 || [[#Restore]]<br />
|-<br />
| 12 || [[#CreateApplicationArea]]<br />
|-<br />
| 13 || [[#GetTagInfo]]<br />
|-<br />
| 14 || [[#GetRegisterInfo]]<br />
|-<br />
| 15 || [[#GetCommonInfo]]<br />
|-<br />
| 16 || [[#GetModelInfo]]<br />
|-<br />
| 17 || [[#AttachActivateEvent]]<br />
|-<br />
| 18 || [[#AttachDeactivateEvent]]<br />
|-<br />
| 19 || [[#GetState]]<br />
|-<br />
| 20 || [[#GetDeviceState]]<br />
|-<br />
| 21 || [[#GetNpadId]]<br />
|-<br />
| 22 || [[#GetApplicationAreaSize]]<br />
|-<br />
| 23 || [3.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 24 || [3.0.0+] [[#RecreateApplicationArea]]<br />
|-<br />
| 100 || [[#Format]]<br />
|-<br />
| 101 || [[#GetAdminInfo]]<br />
|-<br />
| 102 || [[#GetRegisterInfoPrivate]]<br />
|-<br />
| 103 || [[#SetRegisterInfoPrivate]]<br />
|-<br />
| 104 || [[#DeleteRegisterInfo]]<br />
|-<br />
| 105 || [[#DeleteApplicationArea]]<br />
|-<br />
| 106 || [[#ExistsApplicationArea]]<br />
|-<br />
| 200 || [[#GetAll]]<br />
|-<br />
| 201 || [[#SetAll]]<br />
|-<br />
| 202 || [[#FlushDebug]]<br />
|-<br />
| 203 || [[#BreakTag]]<br />
|-<br />
| 204 || [[#ReadBackupData]]<br />
|-<br />
| 205 || [[#WriteBackupData]]<br />
|-<br />
| 206 || [[#WriteNtf]]<br />
|-<br />
| 300 || [3.0.0-3.0.2]<br />
|-<br />
| 301 || [3.0.0-3.0.2]<br />
|-<br />
| 302 || [3.0.0-3.0.2]<br />
|-<br />
| 303 || [3.0.0-3.0.2]<br />
|-<br />
| 304 || [3.0.0-3.0.2]<br />
|-<br />
| 305 || [3.0.0-3.0.2]<br />
|-<br />
| 306 || [3.0.0-3.0.2]<br />
|-<br />
| 307 || [3.0.0-3.0.2]<br />
|-<br />
| 308 || [3.0.0-3.0.2]<br />
|-<br />
| 309 || [3.0.0-3.0.2]<br />
|-<br />
| 310 || [3.0.0-3.0.2]<br />
|-<br />
| 311 || [3.0.0-3.0.2]<br />
|-<br />
| 312 || [3.0.0-3.0.2]<br />
|-<br />
| 313 || [3.0.0-3.0.2]<br />
|-<br />
| 314 || [3.0.0-3.0.2]<br />
|}<br />
<br />
==== GetAll ====<br />
Takes an input [[#DeviceHandle]], a type-0x1A output buffer containing [[#NfpData]], no output.<br />
<br />
==== SetAll ====<br />
Takes an input [[#DeviceHandle]], a type-0x19 input buffer containing [[#NfpData]], no output.<br />
<br />
==== FlushDebug ====<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
==== BreakTag ====<br />
Takes an input [[#DeviceHandle]], an input u32 [[#BreakType]], no output.<br />
<br />
==== ReadBackupData ====<br />
Takes an input [[#DeviceHandle]], a type-0x6 output buffer, and an output u32 (read_size).<br />
<br />
==== WriteBackupData ====<br />
Takes an input [[#DeviceHandle]], a type-0x5 input buffer, no output.<br />
<br />
The buffer size must be less or equal than 0x1FBD20.<br />
<br />
==== WriteNtf ====<br />
Takes an input [[#DeviceHandle]], an input u32 [[#WriteType]], a type-0x5 input buffer, no output.<br />
<br />
The input buffer size must match 0x2A0. This handles Amiibo crypto, etc.<br />
<br />
== Common ==<br />
<br />
=== Create*Interface ===<br />
Returns an output interface ([[#IUser]], [[#ISystem]] or [[#IDebug]] depending on the service).<br />
<br />
=== Initialize* ===<br />
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.<br />
<br />
Internally this is mostly the same for each service, this differs depending on the service/cmd however.<br />
<br />
=== Finalize* ===<br />
No input/output.<br />
<br />
Internally this is mostly the same for each service, this differs depending on the service/cmd however.<br />
<br />
=== ListDevices ===<br />
Takes a type-0xA output buffer containing an array of [[#DeviceHandle]], returns an output s32 total_out.<br />
<br />
This can return a maximum of 0xA entries.<br />
<br />
=== StartDetection ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
This runs the same code as nfc [[#StartDetection]] with [[#NfcProtocol]] = -1.<br />
<br />
=== StopDetection ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== Mount ===<br />
Takes an input [[#DeviceHandle]], an input u32 [[#ModelType]] and an input u32 [[#MountTarget]], no output.<br />
<br />
=== Unmount ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== OpenApplicationArea ===<br />
Takes an input [[#DeviceHandle]] and an input u32 [[#Access ID]], no output.<br />
<br />
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.<br />
<br />
=== GetApplicationArea ===<br />
Takes an input [[#DeviceHandle]] and a type-0x6 output buffer, returns an output u32 size.<br />
<br />
Reads the buffer data in the application area and returns the size read from the application area.<br />
<br />
<br />
The application area needs to be opened first.<br />
<br />
=== SetApplicationArea ===<br />
Takes an input [[#DeviceHandle]] and a type-0x5 input buffer, no output.<br />
<br />
Writes the buffer data in the application area.<br />
<br />
The application area needs to be opened first.<br />
<br />
=== Flush ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== Restore ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== CreateApplicationArea ===<br />
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output.<br />
<br />
Creates the application area with the input access ID, and writes the buffer data there.<br />
<br />
=== GetTagInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#TagInfo]].<br />
<br />
=== GetRegisterInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfo]].<br />
<br />
=== GetCommonInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#CommonInfo]].<br />
<br />
=== GetModelInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#ModelInfo]].<br />
<br />
=== AttachActivateEvent ===<br />
Takes an input [[#DeviceHandle]], returns an output Event handle.<br />
<br />
sdknso uses EventClearMode=1.<br />
<br />
=== AttachDeactivateEvent ===<br />
Takes an input [[#DeviceHandle]], returns an output Event handle.<br />
<br />
sdknso uses EventClearMode=1.<br />
<br />
=== GetState ===<br />
Returns an output u32 [[#State]].<br />
<br />
=== GetDeviceState ===<br />
Takes an input [[#DeviceHandle]], returns an output u32 [[#DeviceState]].<br />
<br />
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.<br />
<br />
=== GetNpadId ===<br />
Takes an input [[#DeviceHandle]], returns an output u32 NpadId.<br />
<br />
=== GetApplicationAreaSize ===<br />
Takes an input [[#DeviceHandle]], returns an output u32 size.<br />
<br />
Actually returns a hardcoded value of 0xD8.<br />
<br />
=== AttachAvailabilityChangeEvent ===<br />
No input, returns an output Event handle.<br />
<br />
sdknso uses EventClearMode=1.<br />
<br />
=== RecreateApplicationArea ===<br />
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output.<br />
<br />
Recreates the application area with the input access ID, and writes the buffer data there.<br />
<br />
=== Format ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== GetAdminInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#AdminInfo]].<br />
<br />
=== GetRegisterInfoPrivate ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfoPrivate]].<br />
<br />
=== SetRegisterInfoPrivate ===<br />
Takes an input [[#DeviceHandle]] and a type-0x19 input buffer containing a [[#RegisterInfoPrivate]].<br />
<br />
=== DeleteRegisterInfo ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== DeleteApplicationArea ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== ExistsApplicationArea ===<br />
Takes an input [[#DeviceHandle]], returns an output u8/bool.<br />
<br />
= RequiredMcuVersionData =<br />
In sdknso, the global data containing the array data for this is "nn::nfc::client::RequiredMcuVersionData". The array entry is 0x20-bytes.<br />
<br />
= DeviceHandle =<br />
This is "nn::nfc::DeviceHandle". This is a 8-byte struct with 4-byte alignment.<br />
<br />
= NfcProtocol =<br />
This is s32 enum "nn::nfc::NfcProtocol". Value -1 can be used as a default.<br />
<br />
= TestWaveType =<br />
This is u32 enum "nn::nfc::TestWaveType".<br />
<br />
= MifareReadBlockData =<br />
This is "nn::nfc::MifareReadBlockData". This is a 0x18-byte struct.<br />
<br />
= MifareReadBlockParameter =<br />
This is "nn::nfc::MifareReadBlockParameter". This is a 0x18-byte struct.<br />
<br />
= MifareWriteBlockParameter =<br />
This is "nn::nfc::MifareWriteBlockParameter". This is a 0x28-byte struct.<br />
<br />
= State =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || NonInitialized<br />
|-<br />
| 1 || Initialized<br />
|}<br />
<br />
= DeviceState =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || Initialized<br />
|-<br />
| 1 || Searching for tag<br />
|-<br />
| 2 || Tag found<br />
|-<br />
| 3 || Tag removed<br />
|-<br />
| 4 || Tag mounted<br />
|-<br />
| 5 || Unavailable<br />
|-<br />
| 6 || Finalized<br />
|}<br />
<br />
= ModelType =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || Amiibo<br />
|}<br />
<br />
= MountTarget =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || ROM<br />
|-<br />
| 2 || RAM<br />
|-<br />
| 3 || All<br />
|}<br />
<br />
= Date =<br />
<br />
This is "nn::nfp::Date":<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x2 || Year<br />
|-<br />
| 0x2 || 0x1 || Month<br />
|-<br />
| 0x3 || 0x1 || Day<br />
|}<br />
<br />
= TagInfo =<br />
This is "nn::nfp::TagInfo". This is a 0x58-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0xA || UUID<br />
|-<br />
| 0xA || 0x1 || UUID length<br />
|-<br />
| 0xB || 0x15 || Reserved<br />
|-<br />
| 0x20 || 0x4 || Protocol<br />
|-<br />
| 0x24 || 0x4 || Tag type<br />
|-<br />
| 0x28 || 0x30 || Reserved<br />
|}<br />
<br />
= RegisterInfo =<br />
This is "nn::nfp::RegisterInfo". This is a 0x100-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x58 || Mii CharInfo (see mii services)<br />
|-<br />
| 0x58 || 0x4 || First write date (see [[#Date]])<br />
|-<br />
| 0x5C || 0x29 || Amiibo name (NUL-terminated string)<br />
|-<br />
| 0x85 || 0x1 || Unknown<br />
|-<br />
| 0x86 || 0x7A || Reserved<br />
|}<br />
<br />
= CommonInfo =<br />
This is ""nn::nfp::CommonInfo". This is a 0x40-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Last write date (see [[#Date]])<br />
|-<br />
| 0x4 || 0x2 || Write counter<br />
|-<br />
| 0x6 || 0x1 || Version<br />
|-<br />
| 0x7 || 0x1 || Padding<br />
|-<br />
| 0x8 || 0x4 || Application area size (hardcoded to be 0xD8, like in [[#GetApplicationAreaSize]])<br />
|-<br />
| 0xC || 0x34 || Reserved<br />
|}<br />
<br />
= ModelInfo =<br />
This is "nn::nfp::ModelInfo". This is a 0x40-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x2 || Game and character ID<br />
|-<br />
| 0x2 || 0x1 || Character variant<br />
|-<br />
| 0x3 || 0x1 || Figure type<br />
|-<br />
| 0x4 || 0x2 || Model number<br />
|-<br />
| 0x6 || 0x1 || Series<br />
|-<br />
| 0x7 || 0x39 || Reserved<br />
|}<br />
<br />
= AdminInfo =<br />
This is "nn::nfp::AdminInfo". This is a 0x40-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Program ID (From the Wii U, 3DS or Switch title who created the application area)<br />
|-<br />
| 0x8 || 0x4 || [[#Access ID]]<br />
|-<br />
| 0xC || 0x2 || CRC32 change counter<br />
|-<br />
| 0xE || 0x1 || Flags (bit0 = amiibo was initialized in console settings, bit1 = has application area, bit2/bit3 unknown)<br />
|-<br />
| 0xF || 0x1 || Unknown, hardcoded to 0x2<br />
|-<br />
| 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)<br />
|-<br />
| 0x11 || 0x7 || Padding<br />
|-<br />
| 0x18 || 0x28 || Reserved<br />
|}<br />
<br />
= RegisterInfoPrivate =<br />
This is "nn::nfp::RegisterInfoPrivate". This is a 0x100-byte struct.<br />
<br />
This is almost identical to [[#RegisterInfo]], but containing mii data as a StoreData instead of a CharInfo and more reserved bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x44 || Mii StoreData (see mii services)<br />
|-<br />
| 0x44 || 0x4 || First write date (see [[#Date]])<br />
|-<br />
| 0x48 || 0x29 || Amiibo name (NUL-terminated string)<br />
|-<br />
| 0x71 || 0x1 || Unknown<br />
|-<br />
| 0x72 || 0x8E || Reserved<br />
|}<br />
<br />
= NfpData =<br />
This is "nn::nfp::NfpData". This is a 0x298-byte struct.<br />
<br />
= BreakType =<br />
This is "nn::nfp::BreakType".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || ?<br />
|-<br />
| 1 || ?<br />
|-<br />
| 2 || ?<br />
|}<br />
<br />
Value 0 is internally used in some places, aside for [[#BreakTag]] commands called externally.<br />
<br />
= WriteType =<br />
This is "nn::nfp::WriteType".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || ?<br />
|-<br />
| 1 || ?<br />
|}<br />
<br />
= Access ID =<br />
Access IDs are game-unique u32s used to access the amiibo application area.<br />
<br />
For a list of Nintendo 3DS access IDs, see https://www.3dbrew.org/wiki/Amiibo#Games_using_Amiibo_AppData.<br />
<br />
== Nintendo Switch titles ==<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Game || Access ID<br />
|-<br />
| Super Smash Bros. Ultimate || 0x34F80200<br />
|-<br />
| Splatoon 2 || 0x10162B00<br />
|-<br />
| The Legend of Zelda: Breath of the Wild || 0x1019C800<br />
|-<br />
| The Legend of Zelda: Link's Awakening || 0x3B440400<br />
|}<br />
<br />
[[Category:Services]]<br />
<br />
= RomFS =<br />
[9.0.0+] The nfc-sysmodule RomFS contains:<br />
ST21NFCD_01_05_6811.bin<br />
<br />
These are firmware files for the NFC IC inside Switch Lite units.</div>XorTrollhttps://switchbrew.org/w/index.php?title=NFC_services&diff=11465NFC services2022-01-31T01:07:45Z<p>XorTroll: Document some nfp stuff</p>
<hr />
<div>= nfc:am =<br />
This is "nn::nfc::am::detail::IAmManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateAmInterface<br />
|}<br />
<br />
== IAm ==<br />
This is "nn::nfc::am::detail::IAm".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || Initialize<br />
|-<br />
| 1 || Finalize<br />
|-<br />
| 2 || NotifyForegroundApplet<br />
|}<br />
<br />
= nfc:mf:u =<br />
This is "nn::nfc::mifare::detail::IUserManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateUserInterface<br />
|}<br />
<br />
== IUser ==<br />
This is "nn::nfc::mifare::detail::IUser".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize]]<br />
|-<br />
| 1 || [[#Finalize]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection_2|StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#ReadMifare|Read]]<br />
|-<br />
| 6 || [[#WriteMifare|Write]]<br />
|-<br />
| 7 || [[#GetTagInfo]]<br />
|-<br />
| 8 || [[#AttachActivateEvent|GetActivateEventHandle]]<br />
|-<br />
| 9 || [[#AttachDeactivateEvent|GetDeactivateEventHandle]]<br />
|-<br />
| 10 || [[#GetState]]<br />
|-<br />
| 11 || [[#GetDeviceState]]<br />
|-<br />
| 12 || [[#GetNpadId]]<br />
|-<br />
| 13 || [3.0.0+] [[#AttachAvailabilityChangeEvent|GetAvailabilityChangeEventHandle]]<br />
|}<br />
<br />
= nfc:user =<br />
This is "nn::nfc::detail::IUserManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateUserInterface<br />
|}<br />
<br />
== IUser ==<br />
This is "nn::nfc::detail::IUser".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize|InitializeOld]]<br />
|-<br />
| 1 || [[#Finalize|FinalizeOld]]<br />
|-<br />
| 2 || [[#GetStateOld]]<br />
|-<br />
| 3 || [[#IsNfcEnabledOld]]<br />
|-<br />
| 400 || [4.0.0+] [[#Initialize]]<br />
|-<br />
| 401 || [4.0.0+] [[#Finalize]]<br />
|-<br />
| 402 || [4.0.0+] [[#GetState]]<br />
|-<br />
| 403 || [4.0.0+] [[#IsNfcEnabled]]<br />
|-<br />
| 404 || [4.0.0+] [[#ListDevices]]<br />
|-<br />
| 405 || [4.0.0+] [[#GetDeviceState]]<br />
|-<br />
| 406 || [4.0.0+] [[#GetNpadId]]<br />
|-<br />
| 407 || [4.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 408 || [4.0.0+] [[#StartDetection]]<br />
|-<br />
| 409 || [4.0.0+] [[#StopDetection]]<br />
|-<br />
| 410 || [4.0.0+] [[#GetTagInfo]]<br />
|-<br />
| 411 || [4.0.0+] [[#AttachActivateEvent]]<br />
|-<br />
| 412 || [4.0.0+] [[#AttachDeactivateEvent]]<br />
|-<br />
| 1000 || [4.0.0+] [[#ReadMifare]]<br />
|-<br />
| 1001 || [4.0.0+] [[#WriteMifare]]<br />
|-<br />
| 1300 || [4.0.0+] [[#SendCommandByPassThrough]]<br />
|-<br />
| 1301 || [4.0.0+] [[#KeepPassThroughSession]]<br />
|-<br />
| 1302 || [4.0.0+] [[#ReleasePassThroughSession]]<br />
|}<br />
<br />
=== GetStateOld ===<br />
No input, returns an output u32.<br />
<br />
=== IsNfcEnabledOld ===<br />
No input, returns an output bool.<br />
<br />
This runs the same code as [[#IsNfcEnabled]].<br />
<br />
=== GetState ===<br />
No input, returns an output u32.<br />
<br />
This replaces [[#GetStateOld]].<br />
<br />
=== IsNfcEnabled ===<br />
No input, returns an output bool.<br />
<br />
This replaces [[#IsNfcEnabledOld]].<br />
<br />
=== StartDetection ===<br />
Takes an input [[#DeviceHandle]] and a [[#NfcProtocol]], no output.<br />
<br />
=== StopDetection ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== ReadMifare ===<br />
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.<br />
<br />
sdknso passes the same user-specified array-count for both buffers.<br />
<br />
=== WriteMifare ===<br />
Takes an input [[#DeviceHandle]], a type-0x5 input buffer containing an array of [[#MifareWriteBlockParameter]], no output.<br />
<br />
=== SendCommandByPassThrough ===<br />
Takes an input [[#DeviceHandle]], a nn::TimeSpan timeout, a type-0x6 output buffer, a type-0x5 input buffer, returns an output u32 out_size.<br />
<br />
sdknso copies the output u32 into an u64. This is the actual size which was copied into the output buffer.<br />
<br />
This allows using a raw NFC command. The input buffer contains the command data (id + params), and the output buffer contains the response.<br />
<br />
=== KeepPassThroughSession ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== ReleasePassThroughSession ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
= nfc:sys =<br />
This is "nn::nfc::detail::ISystemManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || CreateSystemInterface<br />
|}<br />
<br />
== ISystem ==<br />
This is "nn::nfc::detail::ISystem".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize]]<br />
|-<br />
| 1 || [[#Finalize]]<br />
|-<br />
| 2 || [[#GetStateOld]]<br />
|-<br />
| 3 || [[#IsNfcEnabledOld]]<br />
|-<br />
| 100 || [[#SetNfcEnabledOld]]<br />
|-<br />
| 400 || [4.0.0+] [[#Initialize|InitializeSystem]]<br />
|-<br />
| 401 || [4.0.0+] [[#Finalize|FinalizeSystem]]<br />
|-<br />
| 402 || [4.0.0+] [[#GetState]]<br />
|-<br />
| 403 || [4.0.0+] [[#IsNfcEnabled]]<br />
|-<br />
| 404 || [4.0.0+] [[#ListDevices]]<br />
|-<br />
| 405 || [4.0.0+] [[#GetDeviceState]]<br />
|-<br />
| 406 || [4.0.0+] [[#GetNpadId]]<br />
|-<br />
| 407 || [4.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 408 || [4.0.0+] [[#StartDetection]]<br />
|-<br />
| 409 || [4.0.0+] [[#StopDetection]]<br />
|-<br />
| 410 || [4.0.0+] [[#GetTagInfo]]<br />
|-<br />
| 411 || [4.0.0+] [[#AttachActivateEvent]]<br />
|-<br />
| 412 || [4.0.0+] [[#AttachDeactivateEvent]]<br />
|-<br />
| 500 || [4.0.0+] [[#SetNfcEnabled]]<br />
|-<br />
| 510 || [7.0.0+] [[#OutputTestWave]]<br />
|-<br />
| 1000 || [4.0.0+] [[#ReadMifare]]<br />
|-<br />
| 1001 || [4.0.0+] [[#WriteMifare]]<br />
|-<br />
| 1300 || [4.0.0+] [[#SendCommandByPassThrough]]<br />
|-<br />
| 1301 || [4.0.0+] [[#KeepPassThroughSession]]<br />
|-<br />
| 1302 || [4.0.0+] [[#ReleasePassThroughSession]]<br />
|}<br />
<br />
=== SetNfcEnabledOld ===<br />
Takes an input bool, no output.<br />
<br />
This runs the same code as [[#SetNfcEnabled]].<br />
<br />
=== SetNfcEnabled ===<br />
Takes an input bool, no output.<br />
<br />
This replaces [[#SetNfcEnabledOld]].<br />
<br />
=== OutputTestWave ===<br />
Takes an input bool and a [[#TestWaveType]], no output.<br />
<br />
= nfp services =<br />
<br />
These are used for amiibo support (nfp = Nintendo Figurine Protocol, internal name for amiibo protocol)<br />
<br />
== nfp:user ==<br />
This is "nn::nfp::detail::IUserManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Create*Interface|CreateUserInterface]]<br />
|}<br />
<br />
=== IUser ===<br />
This is "nn::nfp::detail::IUser".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize*|Initialize]]<br />
|-<br />
| 1 || [[#Finalize*|Finalize]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#Mount]]<br />
|-<br />
| 6 || [[#Unmount]]<br />
|-<br />
| 7 || [[#OpenApplicationArea]]<br />
|-<br />
| 8 || [[#GetApplicationArea]]<br />
|-<br />
| 9 || [[#SetApplicationArea]]<br />
|-<br />
| 10 || [[#Flush]]<br />
|-<br />
| 11 || [[#Restore]]<br />
|-<br />
| 12 || [[#CreateApplicationArea]]<br />
|-<br />
| 13 || [[#GetTagInfo]]<br />
|-<br />
| 14 || [[#GetRegisterInfo]]<br />
|-<br />
| 15 || [[#GetCommonInfo]]<br />
|-<br />
| 16 || [[#GetModelInfo]]<br />
|-<br />
| 17 || [[#AttachActivateEvent]]<br />
|-<br />
| 18 || [[#AttachDeactivateEvent]]<br />
|-<br />
| 19 || [[#GetState]]<br />
|-<br />
| 20 || [[#GetDeviceState]]<br />
|-<br />
| 21 || [[#GetNpadId]]<br />
|-<br />
| 22 || [[#GetApplicationAreaSize]]<br />
|-<br />
| 23 || [3.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 24 || [3.0.0+] [[#RecreateApplicationArea]]<br />
|}<br />
<br />
== nfp:sys ==<br />
This is "nn::nfp::detail::ISystemManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Create*Interface|CreateSystemInterface]]<br />
|}<br />
<br />
=== ISystem ===<br />
This is "nn::nfp::detail::ISystem".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize*|InitializeSystem]]<br />
|-<br />
| 1 || [[#Finalize*|FinalizeSystem]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#Mount]]<br />
|-<br />
| 6 || [[#Unmount]]<br />
|-<br />
| 10 || [[#Flush]]<br />
|-<br />
| 11 || [[#Restore]]<br />
|-<br />
| 13 || [[#GetTagInfo]]<br />
|-<br />
| 14 || [[#GetRegisterInfo]]<br />
|-<br />
| 15 || [[#GetCommonInfo]]<br />
|-<br />
| 16 || [[#GetModelInfo]]<br />
|-<br />
| 17 || [[#AttachActivateEvent]]<br />
|-<br />
| 18 || [[#AttachDeactivateEvent]]<br />
|-<br />
| 19 || [[#GetState]]<br />
|-<br />
| 20 || [[#GetDeviceState]]<br />
|-<br />
| 21 || [[#GetNpadId]]<br />
|-<br />
| 23 || [3.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 100 || [[#Format]]<br />
|-<br />
| 101 || [[#GetAdminInfo]]<br />
|-<br />
| 102 || [[#GetRegisterInfoPrivate]]<br />
|-<br />
| 103 || [[#SetRegisterInfoPrivate]]<br />
|-<br />
| 104 || [[#DeleteRegisterInfo]]<br />
|-<br />
| 105 || [[#DeleteApplicationArea]]<br />
|-<br />
| 106 || [[#ExistsApplicationArea]]<br />
|}<br />
<br />
== nfp:dbg ==<br />
This is "nn::nfp::detail::IDebugManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Create*Interface|CreateDebugInterface]]<br />
|}<br />
<br />
=== IDebug ===<br />
This is "nn::nfp::detail::IDebug".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Initialize*|InitializeDebug]]<br />
|-<br />
| 1 || [[#Finalize*|FinalizeDebug]]<br />
|-<br />
| 2 || [[#ListDevices]]<br />
|-<br />
| 3 || [[#StartDetection]]<br />
|-<br />
| 4 || [[#StopDetection]]<br />
|-<br />
| 5 || [[#Mount]]<br />
|-<br />
| 6 || [[#Unmount]]<br />
|-<br />
| 7 || [[#OpenApplicationArea]]<br />
|-<br />
| 8 || [[#GetApplicationArea]]<br />
|-<br />
| 9 || [[#SetApplicationArea]]<br />
|-<br />
| 10 || [[#Flush]]<br />
|-<br />
| 11 || [[#Restore]]<br />
|-<br />
| 12 || [[#CreateApplicationArea]]<br />
|-<br />
| 13 || [[#GetTagInfo]]<br />
|-<br />
| 14 || [[#GetRegisterInfo]]<br />
|-<br />
| 15 || [[#GetCommonInfo]]<br />
|-<br />
| 16 || [[#GetModelInfo]]<br />
|-<br />
| 17 || [[#AttachActivateEvent]]<br />
|-<br />
| 18 || [[#AttachDeactivateEvent]]<br />
|-<br />
| 19 || [[#GetState]]<br />
|-<br />
| 20 || [[#GetDeviceState]]<br />
|-<br />
| 21 || [[#GetNpadId]]<br />
|-<br />
| 22 || [[#GetApplicationAreaSize]]<br />
|-<br />
| 23 || [3.0.0+] [[#AttachAvailabilityChangeEvent]]<br />
|-<br />
| 24 || [3.0.0+] [[#RecreateApplicationArea]]<br />
|-<br />
| 100 || [[#Format]]<br />
|-<br />
| 101 || [[#GetAdminInfo]]<br />
|-<br />
| 102 || [[#GetRegisterInfoPrivate]]<br />
|-<br />
| 103 || [[#SetRegisterInfoPrivate]]<br />
|-<br />
| 104 || [[#DeleteRegisterInfo]]<br />
|-<br />
| 105 || [[#DeleteApplicationArea]]<br />
|-<br />
| 106 || [[#ExistsApplicationArea]]<br />
|-<br />
| 200 || GetAll<br />
|-<br />
| 201 || SetAll<br />
|-<br />
| 202 || FlushDebug<br />
|-<br />
| 203 || BreakTag<br />
|-<br />
| 204 || ReadBackupData<br />
|-<br />
| 205 || WriteBackupData<br />
|-<br />
| 206 || [[#WriteNtf]]<br />
|-<br />
| 300 || [3.0.0-3.0.2]<br />
|-<br />
| 301 || [3.0.0-3.0.2]<br />
|-<br />
| 302 || [3.0.0-3.0.2]<br />
|-<br />
| 303 || [3.0.0-3.0.2]<br />
|-<br />
| 304 || [3.0.0-3.0.2]<br />
|-<br />
| 305 || [3.0.0-3.0.2]<br />
|-<br />
| 306 || [3.0.0-3.0.2]<br />
|-<br />
| 307 || [3.0.0-3.0.2]<br />
|-<br />
| 308 || [3.0.0-3.0.2]<br />
|-<br />
| 309 || [3.0.0-3.0.2]<br />
|-<br />
| 310 || [3.0.0-3.0.2]<br />
|-<br />
| 311 || [3.0.0-3.0.2]<br />
|-<br />
| 312 || [3.0.0-3.0.2]<br />
|-<br />
| 313 || [3.0.0-3.0.2]<br />
|-<br />
| 314 || [3.0.0-3.0.2]<br />
|}<br />
<br />
==== WriteNtf ====<br />
Takes an input [[#DeviceHandle]], an u32, a type-0x5 input buffer, no output.<br />
<br />
The input buffer size must match 0x2A0.<br />
<br />
This handles Amiibo crypto etc.<br />
<br />
== Common ==<br />
<br />
=== Create*Interface ===<br />
Returns an output interface ([[#IUser]], [[#ISystem]] or [[#IDebug]] depending on the service).<br />
<br />
=== Initialize* ===<br />
Takes a PID, an [[AM_services|AppletResourceUserId]], an u64, a type-0x5 input buffer containing an array of [[#RequiredMcuVersionData]], no output.<br />
<br />
sdknso passes value 0 for the u64.<br />
<br />
Internally this is mostly the same for each service, this differs depending on the service/cmd however.<br />
<br />
=== Finalize* ===<br />
No input/output.<br />
<br />
Internally this is mostly the same for each service, this differs depending on the service/cmd however.<br />
<br />
=== ListDevices ===<br />
Takes a type-0xA output buffer containing an array of [[#DeviceHandle]], returns an output s32 total_out.<br />
<br />
This can return a maximum of 0xA entries.<br />
<br />
=== StartDetection ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
This runs the same code as nfc [[#StartDetection]] with [[#NfcProtocol]] = -1.<br />
<br />
=== StopDetection ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== Mount ===<br />
Takes an input [[#DeviceHandle]], an input [[#ModelType]] and an input [[#MountTarget]], no output.<br />
<br />
=== Unmount ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== OpenApplicationArea ===<br />
Takes an input [[#DeviceHandle]] and an input u32 [[#Access ID]], no output.<br />
<br />
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.<br />
<br />
=== GetApplicationArea ===<br />
Takes an input [[#DeviceHandle]] and a type-0x6 output buffer, returns an output u32 size.<br />
<br />
Reads the buffer data in the application area and returns the size read from the application area.<br />
<br />
<br />
The application area needs to be opened first.<br />
<br />
=== SetApplicationArea ===<br />
Takes an input [[#DeviceHandle]] and a type-0x5 input buffer, no output.<br />
<br />
Writes the buffer data in the application area.<br />
<br />
The application area needs to be opened first.<br />
<br />
=== Flush ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== Restore ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== CreateApplicationArea ===<br />
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output.<br />
<br />
Creates the application area with the input access ID, and writes the buffer data there.<br />
<br />
=== GetTagInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#TagInfo]].<br />
<br />
=== GetRegisterInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfo]].<br />
<br />
=== GetCommonInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#CommonInfo]].<br />
<br />
=== GetModelInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#ModelInfo]].<br />
<br />
=== AttachActivateEvent ===<br />
Takes an input [[#DeviceHandle]], returns an output Event handle.<br />
<br />
sdknso uses EventClearMode=1.<br />
<br />
=== AttachDeactivateEvent ===<br />
Takes an input [[#DeviceHandle]], returns an output Event handle.<br />
<br />
sdknso uses EventClearMode=1.<br />
<br />
=== GetState ===<br />
Returns an output u32 [[#State]].<br />
<br />
=== GetDeviceState ===<br />
Takes an input [[#DeviceHandle]], returns an output u32 [[#DeviceState]].<br />
<br />
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.<br />
<br />
=== GetNpadId ===<br />
Takes an input [[#DeviceHandle]], returns an output u32 NpadId.<br />
<br />
=== GetApplicationAreaSize ===<br />
Takes an input [[#DeviceHandle]], returns an output u32 size.<br />
<br />
Actually returns a hardcoded value of 0xD8.<br />
<br />
=== AttachAvailabilityChangeEvent ===<br />
No input, returns an output Event handle.<br />
<br />
sdknso uses EventClearMode=1.<br />
<br />
=== RecreateApplicationArea ===<br />
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output.<br />
<br />
Recreates the application area with the input access ID, and writes the buffer data there.<br />
<br />
=== Format ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== GetAdminInfo ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#AdminInfo]].<br />
<br />
=== GetRegisterInfoPrivate ===<br />
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfoPrivate]].<br />
<br />
=== SetRegisterInfoPrivate ===<br />
Takes an input [[#DeviceHandle]] and a type-0x19 input buffer containing a [[#RegisterInfoPrivate]].<br />
<br />
=== DeleteRegisterInfo ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== DeleteApplicationArea ===<br />
Takes an input [[#DeviceHandle]], no output.<br />
<br />
=== ExistsApplicationArea ===<br />
Takes an input [[#DeviceHandle]], returns an output u8/bool.<br />
<br />
= RequiredMcuVersionData =<br />
In sdknso, the global data containing the array data for this is "nn::nfc::client::RequiredMcuVersionData". The array entry is 0x20-bytes.<br />
<br />
= DeviceHandle =<br />
This is "nn::nfc::DeviceHandle". This is a 8-byte struct with 4-byte alignment.<br />
<br />
= NfcProtocol =<br />
This is s32 enum "nn::nfc::NfcProtocol". Value -1 can be used as a default.<br />
<br />
= TestWaveType =<br />
This is u32 enum "nn::nfc::TestWaveType".<br />
<br />
= MifareReadBlockData =<br />
This is "nn::nfc::MifareReadBlockData". This is a 0x18-byte struct.<br />
<br />
= MifareReadBlockParameter =<br />
This is "nn::nfc::MifareReadBlockParameter". This is a 0x18-byte struct.<br />
<br />
= MifareWriteBlockParameter =<br />
This is "nn::nfc::MifareWriteBlockParameter". This is a 0x28-byte struct.<br />
<br />
= State =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || NonInitialized<br />
|-<br />
| 1 || Initialized<br />
|}<br />
<br />
= DeviceState =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || Initialized<br />
|-<br />
| 1 || Searching for tag<br />
|-<br />
| 2 || Tag found<br />
|-<br />
| 3 || Tag removed<br />
|-<br />
| 4 || Tag mounted<br />
|-<br />
| 5 || Unavailable<br />
|-<br />
| 6 || Finalized<br />
|}<br />
<br />
= ModelType =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 0 || Amiibo<br />
|}<br />
<br />
= MountTarget =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || ROM<br />
|-<br />
| 2 || RAM<br />
|-<br />
| 3 || All<br />
|}<br />
<br />
= Date =<br />
<br />
This is "nn::nfp::Date":<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x2 || Year<br />
|-<br />
| 0x2 || 0x1 || Month<br />
|-<br />
| 0x3 || 0x1 || Day<br />
|}<br />
<br />
= TagInfo =<br />
This is "nn::nfp::TagInfo". This is a 0x58-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0xA || UUID<br />
|-<br />
| 0xA || 0x1 || UUID length<br />
|-<br />
| 0xB || 0x15 || Reserved<br />
|-<br />
| 0x20 || 0x4 || Protocol<br />
|-<br />
| 0x24 || 0x4 || Tag type<br />
|-<br />
| 0x28 || 0x30 || Reserved<br />
|}<br />
<br />
= RegisterInfo =<br />
This is "nn::nfp::RegisterInfo". This is a 0x100-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x58 || Mii CharInfo (see mii services)<br />
|-<br />
| 0x58 || 0x4 || First write date (see [[#Date]])<br />
|-<br />
| 0x5C || 0x29 || Amiibo name (NUL-terminated string)<br />
|-<br />
| 0x85 || 0x1 || Unknown<br />
|-<br />
| 0x86 || 0x7A || Reserved<br />
|}<br />
<br />
= CommonInfo =<br />
This is ""nn::nfp::CommonInfo". This is a 0x40-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Last write date (see [[#Date]])<br />
|-<br />
| 0x4 || 0x2 || Write counter<br />
|-<br />
| 0x6 || 0x1 || Version<br />
|-<br />
| 0x7 || 0x1 || Padding<br />
|-<br />
| 0x8 || 0x4 || Application area size (hardcoded to be 0xD8, like in [[#GetApplicationAreaSize]])<br />
|-<br />
| 0xC || 0x34 || Reserved<br />
|}<br />
<br />
= ModelInfo =<br />
This is "nn::nfp::ModelInfo". This is a 0x40-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x2 || Game and character ID<br />
|-<br />
| 0x2 || 0x1 || Character variant<br />
|-<br />
| 0x3 || 0x1 || Figure type<br />
|-<br />
| 0x4 || 0x2 || Model number<br />
|-<br />
| 0x6 || 0x1 || Series<br />
|-<br />
| 0x7 || 0x39 || Reserved<br />
|}<br />
<br />
= AdminInfo =<br />
This is "nn::nfp::AdminInfo". This is a 0x40-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Program ID (From the Wii U, 3DS or Switch title who created the application area)<br />
|-<br />
| 0x8 || 0x4 || [[#Access ID]]<br />
|-<br />
| 0xC || 0x2 || CRC32 change counter<br />
|-<br />
| 0xE || 0x1 || Flags (bit0 = amiibo was initialized in console settings, bit1 = has application area, bit2/bit3 unknown)<br />
|-<br />
| 0xF || 0x1 || Unknown, hardcoded to 0x2<br />
|-<br />
| 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)<br />
|-<br />
| 0x11 || 0x7 || Padding<br />
|-<br />
| 0x18 || 0x28 || Reserved<br />
|}<br />
<br />
= RegisterInfoPrivate =<br />
This is "nn::nfp::RegisterInfoPrivate". This is a 0x100-byte struct.<br />
<br />
This is almost identical to [[#RegisterInfo]], but containing mii data as a StoreData instead of a CharInfo and more reserved bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x44 || Mii StoreData (see mii services)<br />
|-<br />
| 0x44 || 0x4 || First write date (see [[#Date]])<br />
|-<br />
| 0x48 || 0x29 || Amiibo name (NUL-terminated string)<br />
|-<br />
| 0x71 || 0x1 || Unknown<br />
|-<br />
| 0x72 || 0x8E || Reserved<br />
|}<br />
<br />
= Access ID =<br />
Access IDs are game-unique u32s used to access the amiibo application area.<br />
<br />
For a list of Nintendo 3DS access IDs, see https://www.3dbrew.org/wiki/Amiibo#Games_using_Amiibo_AppData.<br />
<br />
== Nintendo Switch titles ==<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Game || Access ID<br />
|-<br />
| Super Smash Bros. Ultimate || 0x34F80200<br />
|-<br />
| Splatoon 2 || 0x10162B00<br />
|-<br />
| The Legend of Zelda: Breath of the Wild || 0x1019C800<br />
|-<br />
| The Legend of Zelda: Link's Awakening || 0x3B440400<br />
|}<br />
<br />
[[Category:Services]]<br />
<br />
= RomFS =<br />
[9.0.0+] The nfc-sysmodule RomFS contains:<br />
ST21NFCD_01_05_6811.bin<br />
<br />
These are firmware files for the NFC IC inside Switch Lite units.</div>XorTrollhttps://switchbrew.org/w/index.php?title=NCM_services&diff=11409NCM services2022-01-09T10:42:19Z<p>XorTroll: Some cmd corrections</p>
<hr />
<div>NCM contains services for internal file path and content management.<br />
<br />
= Location Resolver services =<br />
== lr ==<br />
This is "nn::lr::ILocationResolverManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name || Arguments || Notes<br />
|-<br />
| 0 || OpenLocationResolver || [[#StorageId]] ||<br />
|-<br />
| 1 || OpenRegisteredLocationResolver || None || <br />
|-<br />
| 2 || RefreshLocationResolver || [[#StorageId]] ||<br />
|-<br />
| 3 || [2.0.0+] OpenAddOnContentLocationResolver || None ||<br />
|}<br />
<br />
The only sysmodules which use this service are [[Filesystem_services|FS]], [[Loader_services|Loader]], and [[NS_Services|NS]]. [[boot2]] has access but doesn't use it.<br />
<br />
=== ILocationResolver ===<br />
This is "nn::lr::ILocationResolver".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name || Notes<br />
|-<br />
| 0 || [[#ResolveProgramPath]] ||<br />
|-<br />
| 1 || [[#RedirectProgramPath]] ||<br />
|-<br />
| 2 || [[#ResolveApplicationControlPath]] ||<br />
|-<br />
| 3 || [[#ResolveApplicationHtmlDocumentPath]] ||<br />
|-<br />
| 4 || [[#ResolveDataPath]] ||<br />
|-<br />
| 5 || [[#RedirectApplicationControlPath]] ||<br />
|-<br />
| 6 || [[#RedirectApplicationHtmlDocumentPath]] ||<br />
|-<br />
| 7 || [[#ResolveApplicationLegalInformationPath]] ||<br />
|-<br />
| 8 || [[#RedirectApplicationLegalInformationPath]] ||<br />
|-<br />
| 9 || [[#Refresh]] ||<br />
|-<br />
| 10 || [5.0.0+] [[#RedirectApplicationProgramPath]] ||<br />
|-<br />
| 11 || [5.0.0+] [[#ClearApplicationRedirection]] ||<br />
|-<br />
| 12 || [5.0.0+] [[#EraseProgramRedirection]] ||<br />
|-<br />
| 13 || [5.0.0+] [[#EraseApplicationControlRedirection]] ||<br />
|-<br />
| 14 || [5.0.0+] [[#EraseApplicationHtmlDocumentRedirection]] ||<br />
|-<br />
| 15 || [5.0.0+] [[#EraseApplicationLegalInformationRedirection]] ||<br />
|-<br />
| 16 || [7.0.0+] [[#ResolveProgramPathForDebug]] || Unofficial name<br />
|-<br />
| 17 || [7.0.0+] [[#RedirectProgramPathForDebug]] || Unofficial name<br />
|-<br />
| 18 || [7.0.0+] [[#RedirectApplicationProgramPathForDebug]] || Unofficial name<br />
|-<br />
| 19 || [7.0.0+] [[#EraseProgramRedirectionForDebug]] || Unofficial name<br />
|}<br />
<br />
If the supplied [[#StorageId]] is 1 (Host), a different set of internal functions is used to handle these commands. In this more restricted set of functions, [[#ResolveApplicationControlPath]] is stubbed and only returns error 0x608.<br />
<br />
The Get* commands load the [[Filesystem_services#ContentPath|ContentPath]] from linked-lists' [[#Location_List_Entry|entries]] in memory using the input [[#ProgramId]]. When the command fails to find an entry for the specified [[#ProgramId]], 0x408 is returned for [[#ResolveProgramPath]] and 0xA08 is returned for the rest.<br />
<br />
The Set* commands always return 0 and add a new entry to the list. If a matching entry is found, it's removed first.<br />
<br />
==== ResolveProgramPath ====<br />
Takes an [[#ProgramId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].<br />
<br />
==== RedirectProgramPath ====<br />
Takes an [[#ProgramId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].<br />
<br />
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 0.<br />
<br />
==== ResolveApplicationControlPath ====<br />
Takes an [[#ApplicationId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].<br />
<br />
==== ResolveApplicationHtmlDocumentPath====<br />
Takes an [[#ApplicationId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].<br />
<br />
==== ResolveDataPath ====<br />
Takes an [[#DataId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].<br />
<br />
==== RedirectApplicationControlPath ====<br />
Takes an [[#ApplicationId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].<br />
<br />
[9.0.0+] Now takes an additional 8-bytes of input.<br />
<br />
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.<br />
<br />
==== RedirectApplicationHtmlDocumentPath ====<br />
Takes an [[#ApplicationId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].<br />
<br />
[9.0.0+] Now takes an additional 8-bytes of input.<br />
<br />
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.<br />
<br />
==== ResolveApplicationLegalInformationPath ====<br />
Takes an [[#ApplicationId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].<br />
<br />
==== RedirectApplicationLegalInformationPath ====<br />
Takes an [[#ApplicationId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].<br />
<br />
[9.0.0+] Now takes an additional 8-bytes of input.<br />
<br />
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.<br />
<br />
==== Refresh ====<br />
Takes no input. Frees all linked-lists' entries that have '''flag''' set to 0.<br />
<br />
==== RedirectApplicationProgramPath ====<br />
Same as [[#RedirectProgramPath|RedirectProgramPath]], but inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.<br />
<br />
[9.0.0+] Now takes an additional 8-bytes of input.<br />
<br />
==== ClearApplicationRedirection ====<br />
Takes no input. Frees all linked-lists' entries that have '''flag''' set to 1.<br />
<br />
[9.0.0+] Now takes a type-0x5 input buffer, no output.<br />
<br />
==== EraseProgramRedirection ====<br />
Takes an [[#ProgramnId]]. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].<br />
<br />
Removes the [[#Location_List_Entry|entry]] that matches the input ProgramId.<br />
<br />
==== EraseApplicationControlRedirection ====<br />
Takes an [[#ApplicationId]]. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].<br />
<br />
Removes the [[#Location_List_Entry|entry]] that matches the input ApplicationId.<br />
<br />
==== EraseApplicationHtmlDocumentRedirection ====<br />
Takes an [[#ApplicationId]]. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].<br />
<br />
Removes the [[#Location_List_Entry|entry]] that matches the input ApplicationId.<br />
<br />
==== EraseApplicationLegalInformationRedirection ====<br />
Takes an [[#ApplicationId]]. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].<br />
<br />
Removes the [[#Location_List_Entry|entry]] that matches the input ApplicationId.<br />
<br />
==== ResolveProgramPathForDebug ====<br />
Same as [[#ResolveProgramPath|ResolveProgramPath]], but uses a redirection shim on top of the real program path.<br />
<br />
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.<br />
<br />
==== RedirectProgramPathForDebug ====<br />
Same as [[#RedirectProgramPath|RedirectProgramPath]], but uses a redirection shim on top of the real program path.<br />
<br />
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.<br />
<br />
==== RedirectApplicationProgramPathForDebug ====<br />
Same as [[#RedirectApplicationProgramPath |RedirectApplicationProgramPath ]], but uses a redirection shim on top of the real program path.<br />
<br />
[9.0.0+] Like [[#RedirectApplicationProgramPath]] this now takes an additional 8-bytes of input.<br />
<br />
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.<br />
<br />
==== EraseProgramRedirectionForDebug ====<br />
Same as [[#EraseProgramRedirection |EraseProgramRedirection ]], but uses a redirection shim on top of the real program path.<br />
<br />
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.<br />
<br />
=== IRegisteredLocationResolver ===<br />
This is "nn::lr::IRegisteredLocationResolver".<br />
<br />
This works like [[#ILocationResolver]], but only two types of NCA paths can be gotten/set. In addition, each type has a fallback path that can be set for a single [[#ProgramId]] at a time.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name || Arguments || Notes<br />
|-<br />
| 0 || ResolveProgramPath || [[#ProgramId]] + C descriptor || Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].<br />
|-<br />
| 1 || RegisterProgramPath || [[#ProgramId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. || Sets the Type 0 fallback TID and path to the provided arguments.<br />
|-<br />
| 2 || UnregisterProgramPath || [[#ProgramId]] || If the Type 0 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.<br />
|-<br />
| 3 || RedirectProgramPath || [[#ProgramId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. ||<br />
|-<br />
| 4 || [2.0.0+] ResolveHtmlDocumentPath || [[#ApplicationId]] + C descriptor ||<br />
|-<br />
| 5 || [2.0.0+] RegisterHtmlDocumentPath || [[#ApplicationId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. || Sets the Type 1 fallback TID and path to the provided arguments.<br />
|-<br />
| 6 || [2.0.0+] UnregisterHtmlDocumentPath || [[#ApplicationId]] || If the Type 1 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.<br />
|-<br />
| 7 || [2.0.0+] RedirectHtmlDocumentPath || [[#ApplicationId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. ||<br />
|-<br />
| 8 || [7.0.0+] Refresh || No input/output. || <br />
|-<br />
| 9 || [9.0.0+] RefreshExcluding || Type-5 buffer || Unofficial name. Refreshes entries excluding those with application ProgramIds contained in the buffer.<br />
|}<br />
<br />
=== IAddOnContentLocationResolver ===<br />
This is "nn::lr::IAddOnContentLocationResolver".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name || Arguments || Notes<br />
|-<br />
| 0 || ResolveAddOnContentPath || [[#ApplicationId]] + C descriptor || <br />
|-<br />
| 1 || RegisterAddOnContentStorage || [[#StorageId]] + [[#ApplicationId]] [9.0.0+] Now takes an additional [[#ApplicationId]] for the owner application. || <br />
|-<br />
| 2 || UnregisterAllAddOnContentPath || None || Clears all registered titles here.<br />
|-<br />
| 3 || [9.0.0+] [[#RefreshApplicationAddOnContent]] || Type-5 buffer || Unofficial name<br />
|-<br />
| 4 || [9.0.0+] [[#UnregisterApplicationAddOnContent]] || [[#ApplicationId]] || Unofficial name<br />
|}<br />
<br />
==== RefreshApplicationAddOnContent ====<br />
Takes an type-5 buffer containing an array of [[#ApplicationId]]. Unregisters entries with IDs absent from the input buffer.<br />
<br />
==== UnregisterApplicationAddOnContent====<br />
Takes an [[#ApplicationId]] for the application to unregister add on content entries for.<br />
<br />
=== Location List Entry ===<br />
Total size is 0x320 bytes. <br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8|| Pointer to previous entry<br />
|-<br />
| 0x8 || 0x8|| Pointer to next entry<br />
|-<br />
| 0x10 || 0x8|| [[#ProgramId]]<br />
|-<br />
| 0x18 || 0x300 || [[Filesystem_services#ContentPath|ContentPath]]<br />
|-<br />
| 0x318 || 0x4 || Flag<br />
|-<br />
| 0x31C || 0x4 || Padding<br />
|}<br />
<br />
= Content Manager services =<br />
== ncm ==<br />
This is "nn::ncm::IContentManager".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name || Notes<br />
|-<br />
| 0 || CreateContentStorage || Takes a [[#StorageId]].<br />
|-<br />
| 1 || CreateContentMetaDatabase || Takes a [[#StorageId]].<br />
|-<br />
| 2 || VerifyContentStorage || Takes a [[#StorageId]].<br />
|-<br />
| 3 || VerifyContentMetaDatabase || Takes a [[#StorageId]].<br />
|-<br />
| 4 || OpenContentStorage || Takes a [[#StorageId]], [2.0.0+] Only returns a storage if one has previously been opened globally via CreateContentStorage.<br />
|-<br />
| 5 || OpenContentMetaDatabase || Takes a [[#StorageId]], [2.0.0+] Only returns a storage if one has previously been opened globally via CreateContentStorage.<br />
|-<br />
| 6 || [1.0.0] CloseContentStorageForcibly || Takes a [[#StorageId]]. Calls IContentStorage->DisableForcibly().<br />
|-<br />
| 7 || [1.0.0] CloseContentMetaDatabaseForcibly || Takes a [[#StorageId]]. Calls IContentMetaDatabase->DisableForcibly().<br />
|-<br />
| 8 || CleanupContentMetaDatabase || Takes a [[#StorageId]], and deletes the associated savedata.<br />
|-<br />
| 9 || [2.0.0+] ActivateContentStorage || Takes a [[#StorageId]], and opens an IContentStorage for the StorageID to be gotten with GetIContentStorage. Note: Name is not official.<br />
|-<br />
| 10 || [2.0.0+] InactivateContentStorage || Takes a [[#StorageId]], and closes the associated IContentStorage.<br />
|-<br />
| 11 || [2.0.0+] ActivateContentMetaDatabase || Takes a [[#StorageId]], and opens an IContentMetaDatabase for the StorageID to be gotten with CreateContentMetaDatabase.<br />
|-<br />
| 12 || [2.0.0+] InactivateContentMetaDatabase || Takes a [[#StorageId]], and closes the associated IContentMetaDatabase.<br />
|-<br />
| 13 || [9.0.0+] InvalidateRightsIdCache ||<br />
|-<br />
| 14 || [10.0.0+] GetMemoryReport ||<br />
|}<br />
<br />
=== IContentStorage ===<br />
This is "nn::ncm::IContentStorage".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name || Notes<br />
|-<br />
| 0 || [[#GeneratePlaceHolderId]] || Returns a random UUID for the Content Storage.<br />
|-<br />
| 1 || CreatePlaceHolder || Takes a [[#ContentId]], a [[#PlaceHolderId]], and a s64 filesize.<br />
|-<br />
| 2 || DeletePlaceHolder || Takes a [[#PlaceHolderId]].<br />
|-<br />
| 3 || HasPlaceHolder || Takes a [[#PlaceHolderId]] and returns an output u8 bool.<br />
|-<br />
| 4 || WritePlaceHolder || Takes a [[#PlaceHolderId]], a u64-offset, and type-0x5 input buffer. Writes the buffer to the file for the placeholder path at the specified offset.<br />
|-<br />
| 5 || Register || Takes a [[#ContentId]] and a [[#PlaceHolderId]], no output. Moves the Placeholder NCA content to the registered NCA path.<br />
|-<br />
| 6 || Delete || Takes a [[#ContentId]].<br />
|-<br />
| 7 || Has || Takes a [[#ContentId]].<br />
|-<br />
| 8 || GetPath || Takes a [[#ContentId]] and a type-0x1A output buffer containing a [[Filesystem_services#ContentPath|ContentPath]].<br />
|-<br />
| 9 || GetPlaceHolderPath || Takes a [[#PlaceHolderId]] and a type-0x1A output buffer containing a [[Filesystem_services#ContentPath|ContentPath]].<br />
|-<br />
| 10 || CleanupAllPlaceHolder || No input/output. Deletes and re-creates the Placeholder directory.<br />
|-<br />
| 11 || ListPlaceHolder || This is like [[#GetNumberOfRegisteredEntries]], but for the Placeholder directory.<br />
|-<br />
| 12 || [[#GetContentCount]] ||<br />
|-<br />
| 13 || [[#ListContentId]] ||<br />
|-<br />
| 14 || [[#GetSizeFromContentId]] || <br />
|-<br />
| 15 || DisableForcibly || No input/output. Closes/Flushes all resources for the storage, and causes all future IPC commands to the current session to return error 0xC805.<br />
|-<br />
| 16 || [2.0.0+] RevertToPlaceHolder || Takes two [[#ContentId]] and a [[#PlaceHolderId]], no output. Creates the registered directory NCA path, and renames the placeholder path to the registered NCA path.<br />
|-<br />
| 17 || [2.0.0+] SetPlaceHolderSize || Takes a [[#PlaceHolderId]], and a s64 size, no output.<br />
|-<br />
| 18 || [2.0.0+] [[#ReadContentIdFile]] ||<br />
|-<br />
| 19 || [2.0.0+] [[#GetRightsIdFromPlaceHolderId]] || <br />
|-<br />
| 20 || [2.0.0+] [[#GetRightsIdFromContentId]] || <br />
|-<br />
| 21 || [2.0.0+] WriteContentForDebug || Takes a [[#ContentId]], a u64 offset, and a type-0x5 input buffer. On debug units, writes the buffer to the NCA's registered path. On retail units, this just aborts.<br />
|-<br />
| 22 || [2.0.0+] GetFreeSpaceSize || Gets free space for the storage.<br />
|-<br />
| 23 || [2.0.0+] GetTotalSpaceSize || Gets total space for the storage.<br />
|-<br />
| 24 || [3.0.0+] FlushPlaceHolder || Flushes resources for the storage without closing it.<br />
|-<br />
| 25 || [4.0.0+] GetSizeFromPlaceHolderId || <br />
|-<br />
| 26 || [4.0.0+] RepairInvalidFileAttribute || <br />
|-<br />
| 27 || [8.0.0+] GetRightsIdFromPlaceHolderIdWithCache || <br />
|-<br />
| 28 || [13.0.0+] RegisterPath || <br />
|-<br />
| 29 || [13.0.0+] ClearRegisteredPath || <br />
|}<br />
<br />
==== GeneratePlaceHolderId ====<br />
Generates a random [[#PlaceHolderId]] for use as a placeholder.<br />
<br />
Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16);<br />
<br />
==== GetContentCount ====<br />
Writes the total number of entries which can be read by GetEntries, to cmdreply <SFCO_offset>+0x10.<br />
<br />
==== ListContentId====<br />
Takes an output buffer, s32 offset and gets all entries starting at that offset.<br />
Returns number of entries read.<br />
<br />
Each entry is a [[#ContentId]].<br />
<br />
The total read entries is exactly the same as the number of "<hex>.nca" directories in the storage FS(or at least under the "registered" directory?).<br />
<br />
==== GetSizeFromContentId ====<br />
Takes a [[#ContentId]] as input.<br />
<br />
Returns the total size readable by [[#ReadContentIdFile]]. This is the same as the size-field in the [[NAX0]] "<ContentId>.nca/00" file.<br />
<br />
==== ReadContentIdFile ====<br />
Takes a type-0x6 output buffer, a [[#ContentId]] as input, and a s64 file offset.<br />
<br />
Reads plaintext NCA file contents from the Registered path for the ContentId.<br />
<br />
==== GetRightsIdFromPlaceHolderId ====<br />
Takes a [[#PlaceHolderId]], returns a [[#RightsId]].<br />
<br />
Gets the Rights ID for the [[#PlaceHolderId]]'s placeholder path.<br />
<br />
==== GetRightsIdFromContentId ====<br />
Takes a [[#ContentId]], returns a [[#RightsId]].<br />
<br />
Gets the Rights ID for the [[#ContentId]]'s registered path<br />
<br />
=== IContentMetaDatabase ===<br />
This is "nn::ncm::IContentMetaDatabase".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name || Notes<br />
|-<br />
| 0 || Set || Takes a [[#ContentMetaKey]], a type-5 [[CNMT#Content_Records|Content Records]] buffer and a u64 size.<br />
|-<br />
| 1 || Get || Takes a [[#ContentMetaKey]], a type-6 buffer to write [[CNMT#Content_Records|Content Records]] to and a u64 size. Returns the actual number of bytes read into the buffer. First 8 bytes of the data is header (u16 numExtraDataBytes, numContentRecords, numMetaRecords, padding). After the header is numExtraDataBytes of additional data, after which follow content records and content meta keys. Set takes this same data as input.<br />
|-<br />
| 2 || Remove || Takes a [[#ContentMetaKey]], and removes the associated record.<br />
|-<br />
| 3 || GetContentIdByType || Takes a [[#ContentMetaKey]] and a u8 [[#ContentType]]. Returns a [[#ContentId]].<br />
|-<br />
| 4 || ListContentInfo || Takes a type-6 buffer to write [[CNMT#Content_Records|Content Record]] entries to, a [[#ContentMetaKey]], and a s32 index into the Content Record entries to start copying from. Returns a s32 entries_read.<br />
|-<br />
| 5 || List || Takes a type-6 buffer to write [[#ContentMetaKey]]s to, a u32 [[#ContentMetaType]], a [[#ProgramId]], a u64 ProgramId_Low, and u64 ProgramId_High. Writes into the buffer all Content Meta Keys with low <= record->title_id <= high, and record->type == type. Returns s32 numEntriesTotal, numEntriesWritten. Additionally requires record->title_id == TID, if record->type is Application, Patch, Add-On, or Delta, otherwise, you can pass 0 for type to ignore the type and list them all in the range.<br />
|-<br />
| 6 || GetLatestContentMetaKey || Takes a [[#ProgramId]], and returns the [[#ContentMetaKey]] with the highest version field for that ProgramId.<br />
|-<br />
| 7 || [[#ListApplication]] ||<br />
|-<br />
| 8 || Has || Takes a [[#ContentMetaKey]] and returns an output u8 bool indicating whether that record is present in the database.<br />
|-<br />
| 9 || HasAll || Takes a type-0x5 input buffer containing an array of [[#ContentMetaKey]], and returns whether all of those records are present in the database.<br />
|-<br />
| 10 || GetSize || Takes a [[#ContentMetaKey]], and returns the size of the associated [[CNMT#Content_Records|Content Records]].<br />
|-<br />
| 11 || GetRequiredSystemVersion || Takes a [[#ContentMetaKey]], and returns u32 from ContentRecords + 16 (only if the content meta key has type Application or Patch).<br />
|-<br />
| 12 || GetPatchId || Takes a [[#ContentMetaKey]], and returns the update [[#ProgramId]] for that record.<br />
|-<br />
| 13 || DisableForcibly || Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05.<br />
|-<br />
| 14 || [[#LookupOrphanContent]] || Takes a type-6 byte buffer, and a type-5 buffer of [[#ContentId]]s.<br />
|-<br />
| 15 || Commit || Flushes the in-memory database to savedata.<br />
|-<br />
| 16 || HasContent || Takes a [[#ContentMetaKey]] and an [[#ContentId]]. Returns whether the content records for that content meta key contain the ContentId.<br />
|-<br />
| 17 || ListContentMetaInfo || Takes a type-6 [[#ContentMetaKey]] output buffer, a s32 offset into that buffer, and an input [[#ContentMetaKey]].<br />
|-<br />
| 18 || GetAttributes || Takes a [[#ContentMetaKey]], and returns u8 from ContentRecords + 6.<br />
|-<br />
| 19 || [2.0.0+] GetRequiredApplicationVersion || Does the same thing as GetRequiredSystemVersion, but for AddOnContents.<br />
|-<br />
| 20 || [5.0.0+] GetContentIdByTypeAndIdOffset || Takes a [[#ContentMetaKey]], a u8 [[#ContentType]] and a u8 id_offset. Returns a [[#ContentId]].<br />
|-<br />
| 21 || [10.0.0+] GetCount || Returns a u32 count.<br />
|-<br />
| 22 || [10.0.0+] GetOwnerApplicationId || Takes a [[#ContentMetaKey]]. Returns a [[#ApplicationId]].<br />
|}<br />
<br />
==== ListApplication ====<br />
Each 24-byte entry (officially "ApplicationContentMetaKey") is as follows:<br />
[[CNMT#Meta_records|meta_record]] meta_record;<br />
u64 base_title_id;<br />
<br />
This function takes in a type 6 buffer to write entries to, and a u8 "filter" [[#Title_Types|type]]. If filter is zero, all update records will be copied to to the output buffer (space permitting). Otherwise, only titles with type == filter_type will be copied to the output buffer.<br />
<br />
This func returns a s32 num_entries_total, and a s32 num_entries_written.<br />
<br />
==== ReadEntryMetaRecords ====<br />
Takes a type-6 [[#ContentMetaKey]] output buffer, a s32 offset into that buffer, and an input [[#ContentMetaKey]] entry. Returns a s32 for total_read_entries.<br />
<br />
Reads the content meta keys stored in the entry's content records into the output buffer.<br />
<br />
This is used, for example, with System Update title 0100000000000816, which contains content meta keys for all other systitles in its Content Records.<br />
<br />
==== LookupOrphanContent ====<br />
Takes a type-6 byte buffer, and a type-0x5 buffer containing an array of [[#ContentId]].<br />
<br />
This function was stubbed to return 0xDC05 in [[2.0.0]].<br />
<br />
On 1.0.0: Initialized the output buffer to all 1s. Then, for each [[#ContentId]] in the input buffer, it checks if that ContentId is present anywhere in the database, and if so writes 0 to the corresponding output byte.<br />
<br />
In pseudocode, the function basically does the following:<br />
<br />
for i in range(len(out_buf)):<br />
out_buf[i] = 1<br />
<br />
for i, ContentId in ContentId:<br />
if is_present_in_database(ContentId):<br />
out_buf[i] = 0<br />
<br />
=== ContentId ===<br />
This is "nn::ncm::ContentId".<br />
<br />
This is a 0x10-byte entry. This is originally from the hex portion of "<hex>.nca" directory-names from this storage FS(like [[SD_Filesystem|SD]]).<br />
<br />
The ContentId is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from [[#ReadContentIdFile]].<br />
<br />
=== PlaceHolderId ===<br />
This is "nn::ncm::PlaceHolderId".<br />
<br />
This is the same as [[#ContentId]], except this is for placeholder content and originates from [[#GeneratePlaceHolderId]].<br />
<br />
== ProgramId ==<br />
This is "nn::ncm::ProgramId" or "nn::ncm::SystemProgramId".<br />
<br />
This is an u64 ID bound to a [[Title_list#System_Modules|program]].<br />
<br />
== DataId ==<br />
This is "nn::ncm::DataId" or "nn::ncm::SystemDataId".<br />
<br />
This is an u64 ID bound to a [[Title_list#System_Data_Archives|data archive]].<br />
<br />
== ApplicationId ==<br />
This is "nn::ncm::ApplicationId" or "nn::ncm::SystemApplicationId".<br />
<br />
This is an u64 ID bound to an [[Title_list#System_Applications|application]].<br />
<br />
Value 0 is invalid.<br />
<br />
== PatchId ==<br />
This is "nn::ncm::PatchId".<br />
<br />
This is an u64 ID bound to a program patch.<br />
<br />
== DeltaId ==<br />
This is "nn::ncm::DeltaId".<br />
<br />
This is an u64 ID bound to a program delta fragment.<br />
<br />
== AddOnContentId ==<br />
This is "nn::ncm::AddOnContentId".<br />
<br />
This is an u64 ID bound to add-on content data.<br />
<br />
== SystemUpdateId ==<br />
This is "nn::ncm::SystemUpdateId".<br />
<br />
This is an u64 ID bound to system update data.<br />
<br />
== StorageId ==<br />
This is "nn::ncm::StorageId".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 0 || None<br />
|-<br />
| 1 || Host<br />
|-<br />
| 2 || GameCard<br />
|-<br />
| 3 || BuiltInSystem<br />
|-<br />
| 4 || BuiltInUser<br />
|-<br />
| 5 || SdCard<br />
|-<br />
| 6 || Any<br />
|}<br />
<br />
"None" and "Any" are meta storages.<br />
<br />
nn::ncm::IsInstallableStorage returns true for BuiltInSystem, BuiltInUser, SdCard, and Any.<br />
<br />
nn::ncm::IsUniqueStorage returns true for != None && != Any.<br />
<br />
== RightsId ==<br />
This is "nn::ncm::RightsId".<br />
<br />
This is a 0x10-byte struct. [3.0.0+] This is a 0x18-byte struct.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0 || 0x10 || FS Rights ID<br />
|-<br />
| 0x10 || 0x1 || [3.0.0+] KeyGeneration<br />
|-<br />
| 0x11 || 0x7 || [3.0.0+] Padding<br />
|}<br />
<br />
== ProgramLocation ==<br />
This is "nn::ncm::ProgramLocation".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0 || 0x8 || [[#ProgramId]]<br />
|-<br />
| 0x8 || 0x1 || [[#StorageId]]<br />
|-<br />
| 0x9 || 0x7 || Padding<br />
|}<br />
<br />
== Path ==<br />
This is "nn::ncm::Path".<br />
<br />
This is a 0x300-byte structure, which contains a [[Filesystem_services#ContentPath|ContentPath]].<br />
<br />
== ContentInstallType ==<br />
This is "nn::ncm::ContentInstallType"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value<br />
! Description<br />
|-<br />
| 0x0<br />
| Full<br />
|-<br />
| 0x1<br />
| FragmentOnly<br />
|-<br />
| 0x7<br />
| Unknown (Invalid Content Install Type)<br />
|}<br />
<br />
== ContentMetaType ==<br />
This is "nn::ncm::ContentMetaType"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value<br />
! Description<br />
|-<br />
| 0x00<br />
| Unknown (Invalid Content Meta Type)<br />
|-<br />
| 0x01<br />
| SystemProgram ([[Title_list#System_Modules|System Modules]] or [[Title_list#System_Applets|System Applets]])<br />
|-<br />
| 0x02<br />
| SystemData ([[Title_list#System_Data_Archives|System Data Archives]])<br />
|-<br />
| 0x03<br />
| SystemUpdate<br />
|-<br />
| 0x04<br />
| BootImagePackage ([[Title_list|Firmware package A or C]])<br />
|-<br />
| 0x05<br />
| BootImagePackageSafe ([[Title_list|Firmware package B or D]])<br />
|-<br />
| 0x80<br />
| Application<br />
|-<br />
| 0x81<br />
| Patch<br />
|-<br />
| 0x82<br />
| AddOnContent<br />
|-<br />
| 0x83<br />
| Delta<br />
|}<br />
<br />
== ContentType ==<br />
This is "nn::ncm::ContentType"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value<br />
! Description<br />
|-<br />
| 0<br />
| Meta<br />
|-<br />
| 1<br />
| Program<br />
|-<br />
| 2<br />
| Data<br />
|-<br />
| 3<br />
| Control<br />
|-<br />
| 4<br />
| HtmlDocument<br />
|-<br />
| 5<br />
| LegalInformation<br />
|-<br />
| 6<br />
| DeltaFragment<br />
|}<br />
<br />
== ContentMetaKey ==<br />
This is "nn::ncm::ContentMetaKey"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0 <br />
| 0x8 <br />
| [[#ProgramId]]<br />
|-<br />
| 0x8 <br />
| 0x4 <br />
| Version<br />
|-<br />
| 0xC <br />
| 0x1 <br />
| [[#ContentMetaType]]<br />
|-<br />
| 0xD <br />
| 0x1 <br />
| [[#ContentInstallType]]<br />
|-<br />
| 0xE <br />
| 0x2 <br />
| Padding<br />
|}<br />
<br />
== ncm:v ==<br />
This service doesn't normally exist on retail.<br />
<br />
[[Category:Services]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Log_services&diff=10359Log services2020-12-01T23:44:10Z<p>XorTroll: </p>
<hr />
<div>= lm =<br />
This is "nn::lm::ILogService".<br />
<br />
This service is stubbed on retail, with all the commands/interfaces being present but returning success and doing nothing.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#OpenLogger]]<br />
|}<br />
<br />
== OpenLogger ==<br />
<br />
Takes an input u64 value representing a process ID and returns an [[#ILogger]] instance.<br />
<br />
= lm:get =<br />
This is "nn::lm::ILogGetter". This service doesn't exist on retail.<br />
<br />
This service can be used to retrieve log messages (only the TextLog field, see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#StartLogging]]<br />
|-<br />
| 1 || [[#StopLogging]]<br />
|-<br />
| 2 || [[#GetLog]]<br />
|}<br />
<br />
== StartLogging ==<br />
Takes no input and no output, and just sets a global flag to true.<br />
<br />
== StopLogging ==<br />
Same as above, but the flag is set to false.<br />
<br />
== GetLog ==<br />
Takes an output type-0x22 buffer, returns two output u64s (read size and packet drop count)<br />
The flag mentioned above is not checked here, as it is used in a different place (see [[#Logging]])<br />
<br />
= ILogger =<br />
This is "nn::lm::ILogger".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Log]]<br />
|-<br />
| 1 || [3.0.0+] [[#SetDestination]]<br />
|}<br />
<br />
== Log ==<br />
<br />
Takes a type-0x21 input buffer containing the message to log.<br />
Will always return successfully.<br />
<br />
== SetDestination ==<br />
<br />
Takes an input u32 mask value indicating the logging destinations to send incoming log messages to. This is stored as a global value. The mask entries are as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || TMA<br />
|-<br />
| 2 || UART<br />
|-<br />
| 4 || UART when sleeping<br />
|-<br />
| 0xFFFF || Log to all destinations<br />
|}<br />
<br />
= LogPacketHeader =<br />
This is "nn::lm::detail::LogPacketHeader"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Process ID<br />
|-<br />
| 0x8 || 0x8 || Thread ID<br />
|-<br />
| 0x10 || 0x1 || [[#LogPacketFlags]]<br />
|-<br />
| 0x11 || 0x1 || Padding/reserved<br />
|-<br />
| 0x12 || 0x1 || [[#LogSeverity]]<br />
|-<br />
| 0x13 || 0x1 || Verbosity<br />
|-<br />
| 0x14 || 0x4 || Payload size<br />
|}<br />
<br />
= LogPacketFlags =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 1 || Head<br />
|-<br />
| 2 || Tail<br />
|-<br />
| 4 || LittleEndian<br />
|}<br />
<br />
= Binary header =<br />
Binary log files saved in SD card have this extra header (see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Magic ("hphp")<br />
|-<br />
| 0x4 || 0x1 || Version (1)<br />
|-<br />
| 0x5 || 0x3 || Padding/reserved<br />
|}<br />
<br />
= LogSeverity =<br />
This is "nn::diag::LogSeverity"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 0 || Trace<br />
|-<br />
| 1 || Info<br />
|-<br />
| 2 || Warn<br />
|-<br />
| 3 || Error<br />
|-<br />
| 4 || Fatal<br />
|}<br />
<br />
= LogDataChunkKey =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name || Description<br />
|-<br />
| 0 || LogSessionBegin || Special field sent when a process starts logging (see [[#Logging]])<br />
|-<br />
| 1 || LogSessionEnd || Special field sent when a process finishes logging (see [[#Logging]])<br />
|-<br />
| 2 || TextLog || Actual log text.<br />
|-<br />
| 3 || LineNumber || Line number.<br />
|-<br />
| 4 || FileName || File name.<br />
|-<br />
| 5 || FunctionName || Function name.<br />
|-<br />
| 6 || ModuleName || Module name.<br />
|-<br />
| 7 || ThreadName || Thread name.<br />
|-<br />
| 8 || LogPacketDropCount || Special field containing the amount of packets missed (failed to log/flush, see [[#Logging]])<br />
|-<br />
| 9 || UserSystemClock || Time value.<br />
|-<br />
| 10 || ProcessName || Process name.<br />
|}<br />
<br />
= Data chunks =<br />
Data chunks (log packet data fields) follow this format:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || Variable (normally 0x1) || [[#LogDataChunkKey]] in LEB128 format<br />
|-<br />
| Variable || Variable (normally 0x1) || Chunk size in LEB128 format<br />
|-<br />
| Variable || Chunk size || Chunk data<br />
|}<br />
<br />
= Log packet =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x18 || [[#LogPacketHeader]]<br />
|-<br />
| 0x18 || Variable || Data chunks<br />
|}<br />
<br />
= Logging =<br />
<br />
LogManager uses two separate threads: a flushing thread and a htcs thread (main thread is handling both IPC and PM module requests):<br />
<br />
* The flushing calls Flush() on the "LogBuffer" object, which is the object responsible for flushing logged data though the other objects, and sends a LogPacketDropCount packet via the EventLogTransmitter object (see below) if there any dropped packets and the flushing succeeds - this is done in a loop, waiting until the process starts finalization.<br />
<br />
* The htcs thread continously reads from the server connection, and will close and reopen the client socket if the connection happened to be lost - this is done in a loop, waiting until the process starts finalization.<br />
<br />
Different global objects are used for different purposes:<br />
<br />
* SdCardLogging object - saves logs on the SD card, if both <code>lm!sd_card_log_output_directory</code> and <code>lm!enable_sd_card_logging</code> are present and the last one is true:<br />
** The file name format used is <code>sd:/<log_output_directory>/<serial_no>_<year><month><day><hour><min><sec>[_<extra_index>].nxbinlog</code>, where the extra index is added if the file is already present (several logs being saved at the same time), with a maximum value of 100 (otherwise the saving fails).<br />
** These binary files contain multiple log packets, always preceded by a binary header (see above).<br />
** A single file is used for all the log packets, if the SD card gets ejected or something similar happens the code will re-mount it when it's ready and create a new file.<br />
<br />
* LogServerProxy object - sends log data via HTCS (see [[TMA_services]])<br />
<br />
* CustomSinkBuffer object - retains log data which can be later retrieved by [[#lm:get]]:<br />
** When processes log via [[#lm]] service, some code analyzes the log packet, locates the TextLog ([[#LogDataChunkKey]]) chunk (if present) and saves it's contents in a global buffer (therefore, only the actual log message gets retained).<br />
** Log packets are only analyzed/retained after enabling it (by calling [[#StartLogging]]), and the [[#GetLog]] command just reads data from the global buffer.<br />
** The analyzing code also keeps track of which packets are "missed" (skipped/not properly logged), and that missed packet count can be also retrieved on the [[#GetLog]] command.<br />
** When the global buffer is full, nothing will get logged until a process reads the logged data, cleaning the buffer.<br />
<br />
* EventLogTransmitter object - sends special log packets (event logs):<br />
** When an [[#ILogger]] gets created, this object will send a packet containing the logger's process ID and a LogSessionBegin chunk, telling the remote connection that a new process has started logging. Analogously, when the logger gets destroyed, a simple packet with the process ID and a LogSessionEnd chunk gets sent, telling the remote connection that the process has stopped logging.<br />
** As mentioned above, the flush thread will tell this object to send a simple packet with a LogPacketDropCount chunk after flushing succeeds (and if there any dropped packets).<br />
** These event log packets are logged via the LogBuffer object, like process logs, but they are not analized by the CustomSinkBuffer object since they have no text to be saved.<br />
<br />
* LogBuffer object - responsible for flushing log packets:<br />
** It internally calls the SdCardLogging and LogServerProxy objects when flushing, so that log packets get flushed to both SD card (if enabled) and HTCS.<br />
** It uses a secondary object to flush, alternating between itself and that secondary object when flushing.<br />
<br />
[[Category:Services]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Log_services&diff=10352Log services2020-12-01T19:57:49Z<p>XorTroll: </p>
<hr />
<div>= lm =<br />
This is "nn::lm::ILogService".<br />
<br />
This service is stubbed on retail, with all the commands/interfaces being present but returning success and doing nothing.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#OpenLogger]]<br />
|}<br />
<br />
== OpenLogger ==<br />
<br />
Takes an input u64 value representing a process ID and returns an [[#ILogger]] instance.<br />
<br />
= lm:get =<br />
This is "nn::lm::ILogGetter". This service doesn't exist on retail.<br />
<br />
This service can be used to retrieve log messages (only the TextLog field, see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#StartLogging]]<br />
|-<br />
| 1 || [[#StopLogging]]<br />
|-<br />
| 2 || [[#GetLog]]<br />
|}<br />
<br />
== StartLogging ==<br />
Takes no input and no output, and just sets a global flag to true.<br />
<br />
== StopLogging ==<br />
Same as above, but the flag is set to false.<br />
<br />
== GetLog ==<br />
Takes an output type-0x22 buffer, returns two output u64s (read size and packet drop count)<br />
The flag mentioned above is not checked here, as it is used in a different place (see [[#Logging]])<br />
<br />
= ILogger =<br />
This is "nn::lm::ILogger".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Log]]<br />
|-<br />
| 1 || [3.0.0+] [[#SetDestination]]<br />
|}<br />
<br />
== Log ==<br />
<br />
Takes a type-0x21 input buffer containing the message to log.<br />
Will always return successfully.<br />
<br />
== SetDestination ==<br />
<br />
Takes an input u32 mask value indicating the logging destinations to send incoming log messages to. This is stored as a global value. The mask entries are as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || Log to SD card / HTCS<br />
|-<br />
| 2 || (?)<br />
|}<br />
<br />
= LogPacketHeader =<br />
This is "nn::lm::detail::LogPacketHeader"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Process ID<br />
|-<br />
| 0x8 || 0x8 || Thread ID<br />
|-<br />
| 0x10 || 0x1 || [[#LogPacketFlags]]<br />
|-<br />
| 0x11 || 0x1 || Padding/reserved<br />
|-<br />
| 0x12 || 0x1 || [[#LogSeverity]]<br />
|-<br />
| 0x13 || 0x1 || Verbosity<br />
|-<br />
| 0x14 || 0x4 || Payload size<br />
|}<br />
<br />
= LogPacketFlags =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 1 || Head<br />
|-<br />
| 2 || Tail<br />
|-<br />
| 4 || LittleEndian<br />
|}<br />
<br />
= Binary header =<br />
Binary log files saved in SD card have this extra header (see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Magic ("hphp")<br />
|-<br />
| 0x4 || 0x1 || Version (1)<br />
|-<br />
| 0x5 || 0x3 || Padding/reserved<br />
|}<br />
<br />
= LogSeverity =<br />
This is "nn::diag::LogSeverity"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 0 || Trace<br />
|-<br />
| 1 || Info<br />
|-<br />
| 2 || Warn<br />
|-<br />
| 3 || Error<br />
|-<br />
| 4 || Fatal<br />
|}<br />
<br />
= LogDataChunkKey =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name || Description<br />
|-<br />
| 0 || LogSessionBegin || Special field sent when a process starts logging (see [[#Logging]])<br />
|-<br />
| 1 || LogSessionEnd || Special field sent when a process finishes logging (see [[#Logging]])<br />
|-<br />
| 2 || TextLog || Actual log text.<br />
|-<br />
| 3 || LineNumber || Line number.<br />
|-<br />
| 4 || FileName || File name.<br />
|-<br />
| 5 || FunctionName || Function name.<br />
|-<br />
| 6 || ModuleName || Module name.<br />
|-<br />
| 7 || ThreadName || Thread name.<br />
|-<br />
| 8 || LogPacketDropCount || Special field containing the amount of packets missed (failed to log/flush, see [[#Logging]])<br />
|-<br />
| 9 || UserSystemClock || Time value.<br />
|-<br />
| 10 || ProcessName || Process name.<br />
|}<br />
<br />
= Data chunks =<br />
Data chunks (log packet data fields) follow this format:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || Variable (normally 0x1) || [[#LogDataChunkKey]] in LEB128 format<br />
|-<br />
| Variable || Variable (normally 0x1) || Chunk size in LEB128 format<br />
|-<br />
| Variable || Chunk size || Chunk data<br />
|}<br />
<br />
= Log packet =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x18 || [[#LogPacketHeader]]<br />
|-<br />
| 0x18 || Variable || Data chunks<br />
|}<br />
<br />
= Logging =<br />
<br />
LogManager uses two separate threads: a flushing thread and a htcs thread (main thread is handling both IPC and PM module requests):<br />
<br />
* The flushing calls Flush() on the "LogBuffer" object, which is the object responsible for flushing logged data though the other objects, and sends a LogPacketDropCount packet via the EventLogTransmitter object (see below) if there any dropped packets and the flushing succeeds - this is done in a loop, waiting until the process starts finalization.<br />
<br />
* The htcs thread continously reads from the server connection, and will close and reopen the client socket if the connection happened to be lost - this is done in a loop, waiting until the process starts finalization.<br />
<br />
Different global objects are used for different purposes:<br />
<br />
* SdCardLogging object - saves logs on the SD card, if both <code>lm!sd_card_log_output_directory</code> and <code>lm!enable_sd_card_logging</code> are present and the last one is true:<br />
** The file name format used is <code>sd:/<log_output_directory>/<serial_no>_<year><month><day><hour><min><sec>[_<extra_index>].nxbinlog</code>, where the extra index is added if the file is already present (several logs being saved at the same time), with a maximum value of 100 (otherwise the saving fails).<br />
** These binary files contain multiple log packets, always preceded by a binary header (see above).<br />
** A single file is used for all the log packets, if the SD card gets ejected or something similar happens the code will re-mount it when it's ready and create a new file.<br />
<br />
* LogServerProxy object - sends log data via HTCS (see [[TMA_services]])<br />
<br />
* LogGetterLogger object - retains log data which can be later retrieved by [[#lm:get]]:<br />
** When processes log via [[#lm]] service, some code analyzes the log packet, locates the TextLog ([[#LogDataChunkKey]]) chunk (if present) and saves it's contents in a global buffer (therefore, only the actual log message gets retained).<br />
** Log packets are only analyzed/retained after enabling it (by calling [[#StartLogging]]), and the [[#GetLog]] command just reads data from the global buffer.<br />
** The analyzing code also keeps track of which packets are "missed" (skipped/not properly logged), and that missed packet count can be also retrieved on the [[#GetLog]] command.<br />
** When the global buffer is full, nothing will get logged until a process reads the logged data, cleaning the buffer.<br />
<br />
* EventLogTransmitter object - sends special log packets (event logs):<br />
** When an [[#ILogger]] gets created, this object will send a packet containing the logger's process ID and a LogSessionBegin chunk, telling the remote connection that a new process has started logging. Analogously, when the logger gets destroyed, a simple packet with the process ID and a LogSessionEnd chunk gets sent, telling the remote connection that the process has stopped logging.<br />
** As mentioned above, the flush thread will tell this object to send a simple packet with a LogPacketDropCount chunk after flushing succeeds (and if there any dropped packets).<br />
** These event log packets are logged via the LogBuffer object, like process logs, but they are not analized by the LogGetterLogger object since they have no text to be saved.<br />
<br />
* LogBuffer object - responsible for flushing log packets:<br />
** It internally calls the SdCardLogging and LogServerProxy objects when flushing, so that log packets get flushed to both SD card (if enabled) and HTCS.<br />
** It uses a secondary object to flush, alternating between itself and that secondary object when flushing.<br />
<br />
[[Category:Services]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Log_services&diff=10351Log services2020-12-01T19:56:51Z<p>XorTroll: </p>
<hr />
<div>= lm =<br />
This is "nn::lm::ILogService".<br />
<br />
This service is stubbed on retail, with all the commands/interfaces being present but returning success and doing nothing.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#OpenLogger]]<br />
|}<br />
<br />
== OpenLogger ==<br />
<br />
Takes an input u64 value representing a process ID and returns an [[#ILogger]] instance.<br />
<br />
= lm:get =<br />
This is "nn::lm::ILogGetter". This service doesn't exist on retail.<br />
<br />
This service can be used to retrieve log messages (only the TextLog field, see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#StartLogging]]<br />
|-<br />
| 1 || [[#StopLogging]]<br />
|-<br />
| 2 || [[#GetLog]]<br />
|}<br />
<br />
== StartLogging ==<br />
Takes no input and no output, and just sets a global flag to true.<br />
<br />
== StopLogging ==<br />
Same as above, but the flag is set to false.<br />
<br />
== GetLog ==<br />
Takes an output type-0x22 buffer, returns two output u64s (read size and packet drop count)<br />
The flag mentioned above is not checked here, as it is used in a different place (see [[#Logging]])<br />
<br />
= ILogger =<br />
This is "nn::lm::ILogger".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Log]]<br />
|-<br />
| 1 || [3.0.0+] [[#SetDestination]]<br />
|}<br />
<br />
== Log ==<br />
<br />
Takes a type-0x21 input buffer containing the message to log.<br />
Will always return successfully.<br />
<br />
== SetDestination ==<br />
<br />
Takes an input u32 mask value indicating the logging destinations to send incoming log messages to. The mask entries are as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || Log to SD card / HTCS<br />
|-<br />
| 2 || (?)<br />
|}<br />
<br />
= LogPacketHeader =<br />
This is "nn::lm::detail::LogPacketHeader"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Process ID<br />
|-<br />
| 0x8 || 0x8 || Thread ID<br />
|-<br />
| 0x10 || 0x1 || [[#LogPacketFlags]]<br />
|-<br />
| 0x11 || 0x1 || Padding/reserved<br />
|-<br />
| 0x12 || 0x1 || [[#LogSeverity]]<br />
|-<br />
| 0x13 || 0x1 || Verbosity<br />
|-<br />
| 0x14 || 0x4 || Payload size<br />
|}<br />
<br />
= LogPacketFlags =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 1 || Head<br />
|-<br />
| 2 || Tail<br />
|-<br />
| 4 || LittleEndian<br />
|}<br />
<br />
= Binary header =<br />
Binary log files saved in SD card have this extra header (see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Magic ("hphp")<br />
|-<br />
| 0x4 || 0x1 || Version (1)<br />
|-<br />
| 0x5 || 0x3 || Padding/reserved<br />
|}<br />
<br />
= LogSeverity =<br />
This is "nn::diag::LogSeverity"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 0 || Trace<br />
|-<br />
| 1 || Info<br />
|-<br />
| 2 || Warn<br />
|-<br />
| 3 || Error<br />
|-<br />
| 4 || Fatal<br />
|}<br />
<br />
= LogDataChunkKey =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name || Description<br />
|-<br />
| 0 || LogSessionBegin || Special field sent when a process starts logging (see [[#Logging]])<br />
|-<br />
| 1 || LogSessionEnd || Special field sent when a process finishes logging (see [[#Logging]])<br />
|-<br />
| 2 || TextLog || Actual log text.<br />
|-<br />
| 3 || LineNumber || Line number.<br />
|-<br />
| 4 || FileName || File name.<br />
|-<br />
| 5 || FunctionName || Function name.<br />
|-<br />
| 6 || ModuleName || Module name.<br />
|-<br />
| 7 || ThreadName || Thread name.<br />
|-<br />
| 8 || LogPacketDropCount || Special field containing the amount of packets missed (failed to log/flush, see [[#Logging]])<br />
|-<br />
| 9 || UserSystemClock || Time value.<br />
|-<br />
| 10 || ProcessName || Process name.<br />
|}<br />
<br />
= Data chunks =<br />
Data chunks (log packet data fields) follow this format:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || Variable (normally 0x1) || [[#LogDataChunkKey]] in LEB128 format<br />
|-<br />
| Variable || Variable (normally 0x1) || Chunk size in LEB128 format<br />
|-<br />
| Variable || Chunk size || Chunk data<br />
|}<br />
<br />
= Log packet =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x18 || [[#LogPacketHeader]]<br />
|-<br />
| 0x18 || Variable || Data chunks<br />
|}<br />
<br />
= Logging =<br />
<br />
LogManager uses two separate threads: a flushing thread and a htcs thread (main thread is handling both IPC and PM module requests):<br />
<br />
* The flushing calls Flush() on the "LogBuffer" object, which is the object responsible for flushing logged data though the other objects, and sends a LogPacketDropCount packet via the EventLogTransmitter object (see below) if there any dropped packets and the flushing succeeds - this is done in a loop, waiting until the process starts finalization.<br />
<br />
* The htcs thread continously reads from the server connection, and will close and reopen the client socket if the connection happened to be lost - this is done in a loop, waiting until the process starts finalization.<br />
<br />
Different global objects are used for different purposes:<br />
<br />
* SdCardLogging object - saves logs on the SD card, if both <code>lm!sd_card_log_output_directory</code> and <code>lm!enable_sd_card_logging</code> are present and the last one is true:<br />
** The file name format used is <code>sd:/<log_output_directory>/<serial_no>_<year><month><day><hour><min><sec>[_<extra_index>].nxbinlog</code>, where the extra index is added if the file is already present (several logs being saved at the same time), with a maximum value of 100 (otherwise the saving fails).<br />
** These binary files contain multiple log packets, always preceded by a binary header (see above).<br />
** A single file is used for all the log packets, if the SD card gets ejected or something similar happens the code will re-mount it when it's ready and create a new file.<br />
<br />
* LogServerProxy object - sends log data via HTCS (see [[TMA_services]])<br />
<br />
* LogGetterLogger object - retains log data which can be later retrieved by [[#lm:get]]:<br />
** When processes log via [[#lm]] service, some code analyzes the log packet, locates the TextLog ([[#LogDataChunkKey]]) chunk (if present) and saves it's contents in a global buffer (therefore, only the actual log message gets retained).<br />
** Log packets are only analyzed/retained after enabling it (by calling [[#StartLogging]]), and the [[#GetLog]] command just reads data from the global buffer.<br />
** The analyzing code also keeps track of which packets are "missed" (skipped/not properly logged), and that missed packet count can be also retrieved on the [[#GetLog]] command.<br />
** When the global buffer is full, nothing will get logged until a process reads the logged data, cleaning the buffer.<br />
<br />
* EventLogTransmitter object - sends special log packets (event logs):<br />
** When an [[#ILogger]] gets created, this object will send a packet containing the logger's process ID and a LogSessionBegin chunk, telling the remote connection that a new process has started logging. Analogously, when the logger gets destroyed, a simple packet with the process ID and a LogSessionEnd chunk gets sent, telling the remote connection that the process has stopped logging.<br />
** As mentioned above, the flush thread will tell this object to send a simple packet with a LogPacketDropCount chunk after flushing succeeds (and if there any dropped packets).<br />
** These event log packets are logged via the LogBuffer object, like process logs, but they are not analized by the LogGetterLogger object since they have no text to be saved.<br />
<br />
* LogBuffer object - responsible for flushing log packets:<br />
** It internally calls the SdCardLogging and LogServerProxy objects when flushing, so that log packets get flushed to both SD card (if enabled) and HTCS.<br />
** It uses a secondary object to flush, alternating between itself and that secondary object when flushing.<br />
<br />
[[Category:Services]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Log_services&diff=10350Log services2020-12-01T19:47:47Z<p>XorTroll: </p>
<hr />
<div>= lm =<br />
This is "nn::lm::ILogService".<br />
<br />
This service is stubbed on retail, with all the commands/interfaces being present but returning success and doing nothing.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#OpenLogger]]<br />
|}<br />
<br />
== OpenLogger ==<br />
<br />
Takes an input u64 value representing a process ID and returns an [[#ILogger]] instance.<br />
<br />
= lm:get =<br />
This is "nn::lm::ILogGetter". This service doesn't exist on retail.<br />
<br />
This service can be used to retrieve log messages (only the TextLog field, see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#StartLogging]]<br />
|-<br />
| 1 || [[#StopLogging]]<br />
|-<br />
| 2 || [[#GetLog]]<br />
|}<br />
<br />
== StartLogging ==<br />
Takes no input and no output, and just sets a global flag to true.<br />
<br />
== StopLogging ==<br />
Same as above, but the flag is set to false.<br />
<br />
== GetLog ==<br />
Takes an output type-0x22 buffer, returns two output u64s (read size and packet drop count)<br />
The flag mentioned above is not checked here, as it is used in a different place (see [[#Logging]])<br />
<br />
= ILogger =<br />
This is "nn::lm::ILogger".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Log]]<br />
|-<br />
| 1 || [3.0.0+] [[#SetDestination]]<br />
|}<br />
<br />
== Log ==<br />
<br />
Takes a type-0x21 input buffer containing the message to log.<br />
Will always return successfully.<br />
<br />
== SetDestination ==<br />
<br />
Takes an input u32 mask value indicating the logging destinations to send incoming log messages to. The mask entries are as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || Log to SD card / HTCS<br />
|-<br />
| 2 || Disable something (?)<br />
|}<br />
<br />
= LogPacketHeader =<br />
This is "nn::lm::detail::LogPacketHeader"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Process ID<br />
|-<br />
| 0x8 || 0x8 || Thread ID<br />
|-<br />
| 0x10 || 0x1 || [[#LogPacketFlags]]<br />
|-<br />
| 0x11 || 0x1 || Padding/reserved<br />
|-<br />
| 0x12 || 0x1 || [[#LogSeverity]]<br />
|-<br />
| 0x13 || 0x1 || Verbosity<br />
|-<br />
| 0x14 || 0x4 || Payload size<br />
|}<br />
<br />
= LogPacketFlags =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 1 || Head<br />
|-<br />
| 2 || Tail<br />
|-<br />
| 4 || LittleEndian<br />
|}<br />
<br />
= Binary header =<br />
Binary log files saved in SD card have this extra header (see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Magic ("hphp")<br />
|-<br />
| 0x4 || 0x1 || Version (1)<br />
|-<br />
| 0x5 || 0x3 || Padding/reserved<br />
|}<br />
<br />
= LogSeverity =<br />
This is "nn::diag::LogSeverity"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 0 || Trace<br />
|-<br />
| 1 || Info<br />
|-<br />
| 2 || Warn<br />
|-<br />
| 3 || Error<br />
|-<br />
| 4 || Fatal<br />
|}<br />
<br />
= LogDataChunkKey =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name || Description<br />
|-<br />
| 0 || LogSessionBegin || Special field sent when a process starts logging (see [[#Logging]])<br />
|-<br />
| 1 || LogSessionEnd || Special field sent when a process finishes logging (see [[#Logging]])<br />
|-<br />
| 2 || TextLog || Actual log text.<br />
|-<br />
| 3 || LineNumber || Line number.<br />
|-<br />
| 4 || FileName || File name.<br />
|-<br />
| 5 || FunctionName || Function name.<br />
|-<br />
| 6 || ModuleName || Module name.<br />
|-<br />
| 7 || ThreadName || Thread name.<br />
|-<br />
| 8 || LogPacketDropCount || Special field containing the amount of packets missed (failed to log/flush, see [[#Logging]])<br />
|-<br />
| 9 || UserSystemClock || Time value.<br />
|-<br />
| 10 || ProcessName || Process name.<br />
|}<br />
<br />
= Data chunks =<br />
Data chunks (log packet data fields) follow this format:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || Variable (normally 0x1) || [[#LogDataChunkKey]] in LEB128 format<br />
|-<br />
| Variable || Variable (normally 0x1) || Chunk size in LEB128 format<br />
|-<br />
| Variable || Chunk size || Chunk data<br />
|}<br />
<br />
= Log packet =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x18 || [[#LogPacketHeader]]<br />
|-<br />
| 0x18 || Variable || Data chunks<br />
|}<br />
<br />
= Logging =<br />
<br />
LogManager uses two separate threads: a flushing thread and a htcs thread (main thread is handling both IPC and PM module requests):<br />
<br />
* The flushing calls Flush() on the "LogBuffer" object, which is the object responsible for flushing logged data though the other objects, and sends a LogPacketDropCount packet via the EventLogTransmitter object (see below) if there any dropped packets and the flushing succeeds - this is done in a loop, waiting until the process starts finalization.<br />
<br />
* The htcs thread continously reads from the server connection, and will close and reopen the client socket if the connection happened to be lost - this is done in a loop, waiting until the process starts finalization.<br />
<br />
Different global objects are used for different purposes:<br />
<br />
* SdCardLogging object - saves logs on the SD card, if both <code>lm!sd_card_log_output_directory</code> and <code>lm!enable_sd_card_logging</code> are present and the last one is true:<br />
** The file name format used is <code>sd:/<log_output_directory>/<serial_no>_<year><month><day><hour><min><sec>[_<extra_index>].nxbinlog</code>, where the extra index is added if the file is already present (several logs being saved at the same time), with a maximum value of 100 (otherwise the saving fails).<br />
** These binary files contain multiple log packets, always preceded by a binary header (see above).<br />
** A single file is used for all the log packets, if the SD card gets ejected or something similar happens the code will re-mount it when it's ready and create a new file.<br />
<br />
* LogServerProxy object - sends log data via HTCS (see [[TMA_services]])<br />
<br />
* LogGetterLogger object - retains log data which can be later retrieved by [[#lm:get]]:<br />
** When processes log via [[#lm]] service, some code analyzes the log packet, locates the TextLog ([[#LogDataChunkKey]]) chunk (if present) and saves it's contents in a global buffer (therefore, only the actual log message gets retained).<br />
** Log packets are only analyzed/retained after enabling it (by calling [[#StartLogging]]), and the [[#GetLog]] command just reads data from the global buffer.<br />
** The analyzing code also keeps track of which packets are "missed" (skipped/not properly logged), and that missed packet count can be also retrieved on the [[#GetLog]] command.<br />
** When the global buffer is full, nothing will get logged until a process reads the logged data, cleaning the buffer.<br />
<br />
* EventLogTransmitter object - sends special log packets (event logs):<br />
** When an [[#ILogger]] gets created, this object will send a packet containing the logger's process ID and a LogSessionBegin chunk, telling the remote connection that a new process has started logging. Analogously, when the logger gets destroyed, a simple packet with the process ID and a LogSessionEnd chunk gets sent, telling the remote connection that the process has stopped logging.<br />
** As mentioned above, the flush thread will tell this object to send a simple packet with a LogPacketDropCount chunk after flushing succeeds (and if there any dropped packets).<br />
** These event log packets are logged via the LogBuffer object, like process logs, but they are not analized by the LogGetterLogger object since they have no text to be saved.<br />
<br />
* LogBuffer object - responsible for flushing log packets:<br />
** It internally calls the SdCardLogging and LogServerProxy objects when flushing, so that log packets get flushed to both SD card (if enabled) and HTCS.<br />
** It uses a secondary object to flush, alternating between itself and that secondary object when flushing.<br />
<br />
[[Category:Services]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Log_services&diff=10349Log services2020-12-01T19:47:03Z<p>XorTroll: </p>
<hr />
<div>= lm =<br />
This is "nn::lm::ILogService".<br />
<br />
This service is stubbed on retail, with all the commands/interfaces being present but returning success and doing anything.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#OpenLogger]]<br />
|}<br />
<br />
== OpenLogger ==<br />
<br />
Takes an input u64 value representing a process ID and returns an [[#ILogger]] instance.<br />
<br />
= lm:get =<br />
This is "nn::lm::ILogGetter". This service doesn't exist on retail.<br />
<br />
This service can be used to retrieve log messages (only the TextLog field, see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#StartLogging]]<br />
|-<br />
| 1 || [[#StopLogging]]<br />
|-<br />
| 2 || [[#GetLog]]<br />
|}<br />
<br />
== StartLogging ==<br />
Takes no input and no output, and just sets a global flag to true.<br />
<br />
== StopLogging ==<br />
Same as above, but the flag is set to false.<br />
<br />
== GetLog ==<br />
Takes an output type-0x22 buffer, returns two output u64s (read size and packet drop count)<br />
The flag mentioned above is not checked here, as it is used in a different place (see [[#Logging]])<br />
<br />
= ILogger =<br />
This is "nn::lm::ILogger".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Log]]<br />
|-<br />
| 1 || [3.0.0+] [[#SetDestination]]<br />
|}<br />
<br />
== Log ==<br />
<br />
Takes a type-0x21 input buffer containing the message to log.<br />
Will always return successfully.<br />
<br />
== SetDestination ==<br />
<br />
Takes an input u32 mask value indicating the logging destinations to send incoming log messages to. The mask entries are as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || Log to SD card / HTCS<br />
|-<br />
| 2 || Disable something (?)<br />
|}<br />
<br />
= LogPacketHeader =<br />
This is "nn::lm::detail::LogPacketHeader"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Process ID<br />
|-<br />
| 0x8 || 0x8 || Thread ID<br />
|-<br />
| 0x10 || 0x1 || [[#LogPacketFlags]]<br />
|-<br />
| 0x11 || 0x1 || Padding/reserved<br />
|-<br />
| 0x12 || 0x1 || [[#LogSeverity]]<br />
|-<br />
| 0x13 || 0x1 || Verbosity<br />
|-<br />
| 0x14 || 0x4 || Payload size<br />
|}<br />
<br />
= LogPacketFlags =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 1 || Head<br />
|-<br />
| 2 || Tail<br />
|-<br />
| 4 || LittleEndian<br />
|}<br />
<br />
= Binary header =<br />
Binary log files saved in SD card have this extra header (see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Magic ("hphp")<br />
|-<br />
| 0x4 || 0x1 || Version (1)<br />
|-<br />
| 0x5 || 0x3 || Padding/reserved<br />
|}<br />
<br />
= LogSeverity =<br />
This is "nn::diag::LogSeverity"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 0 || Trace<br />
|-<br />
| 1 || Info<br />
|-<br />
| 2 || Warn<br />
|-<br />
| 3 || Error<br />
|-<br />
| 4 || Fatal<br />
|}<br />
<br />
= LogDataChunkKey =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name || Description<br />
|-<br />
| 0 || LogSessionBegin || Special field sent when a process starts logging (see [[#Logging]])<br />
|-<br />
| 1 || LogSessionEnd || Special field sent when a process finishes logging (see [[#Logging]])<br />
|-<br />
| 2 || TextLog || Actual log text.<br />
|-<br />
| 3 || LineNumber || Line number.<br />
|-<br />
| 4 || FileName || File name.<br />
|-<br />
| 5 || FunctionName || Function name.<br />
|-<br />
| 6 || ModuleName || Module name.<br />
|-<br />
| 7 || ThreadName || Thread name.<br />
|-<br />
| 8 || LogPacketDropCount || Special field containing the amount of packets missed (failed to log/flush, see [[#Logging]])<br />
|-<br />
| 9 || UserSystemClock || Time value.<br />
|-<br />
| 10 || ProcessName || Process name.<br />
|}<br />
<br />
= Data chunks =<br />
Data chunks (log packet data fields) follow this format:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || Variable (normally 0x1) || [[#LogDataChunkKey]] in LEB128 format<br />
|-<br />
| Variable || Variable (normally 0x1) || Chunk size in LEB128 format<br />
|-<br />
| Variable || Chunk size || Chunk data<br />
|}<br />
<br />
= Log packet =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x18 || [[#LogPacketHeader]]<br />
|-<br />
| 0x18 || Variable || Data chunks<br />
|}<br />
<br />
= Logging =<br />
<br />
LogManager uses two separate threads: a flushing thread and a htcs thread (main thread is handling both IPC and PM module requests):<br />
<br />
* The flushing calls Flush() on the "LogBuffer" object, which is the object responsible for flushing logged data though the other objects, and sends a LogPacketDropCount packet via the EventLogTransmitter object (see below) if there any dropped packets and the flushing succeeds - this is done in a loop, waiting until the process starts finalization.<br />
<br />
* The htcs thread continously reads from the server connection, and will close and reopen the client socket if the connection happened to be lost - this is done in a loop, waiting until the process starts finalization.<br />
<br />
Different global objects are used for different purposes:<br />
<br />
* SdCardLogging object - saves logs on the SD card, if both <code>lm!sd_card_log_output_directory</code> and <code>lm!enable_sd_card_logging</code> are present and the last one is true:<br />
** The file name format used is <code>sd:/<log_output_directory>/<serial_no>_<year><month><day><hour><min><sec>[_<extra_index>].nxbinlog</code>, where the extra index is added if the file is already present (several logs being saved at the same time), with a maximum value of 100 (otherwise the saving fails).<br />
** These binary files contain multiple log packets, always preceded by a binary header (see above).<br />
** A single file is used for all the log packets, if the SD card gets ejected or something similar happens the code will re-mount it when it's ready and create a new file.<br />
<br />
* LogServerProxy object - sends log data via HTCS (see [[TMA_services]])<br />
<br />
* LogGetterLogger object - retains log data which can be later retrieved by [[#lm:get]]:<br />
** When processes log via [[#lm]] service, some code analyzes the log packet, locates the TextLog ([[#LogDataChunkKey]]) chunk (if present) and saves it's contents in a global buffer (therefore, only the actual log message gets retained).<br />
** Log packets are only analyzed/retained after enabling it (by calling [[#StartLogging]]), and the [[#GetLog]] command just reads data from the global buffer.<br />
** The analyzing code also keeps track of which packets are "missed" (skipped/not properly logged), and that missed packet count can be also retrieved on the [[#GetLog]] command.<br />
** When the global buffer is full, nothing will get logged until a process reads the logged data, cleaning the buffer.<br />
<br />
* EventLogTransmitter object - sends special log packets (event logs):<br />
** When an [[#ILogger]] gets created, this object will send a packet containing the logger's process ID and a LogSessionBegin chunk, telling the remote connection that a new process has started logging. Analogously, when the logger gets destroyed, a simple packet with the process ID and a LogSessionEnd chunk gets sent, telling the remote connection that the process has stopped logging.<br />
** As mentioned above, the flush thread will tell this object to send a simple packet with a LogPacketDropCount chunk after flushing succeeds (and if there any dropped packets).<br />
** These event log packets are logged via the LogBuffer object, like process logs, but they are not analized by the LogGetterLogger object since they have no text to be saved.<br />
<br />
* LogBuffer object - responsible for flushing log packets:<br />
** It internally calls the SdCardLogging and LogServerProxy objects when flushing, so that log packets get flushed to both SD card (if enabled) and HTCS.<br />
** It uses a secondary object to flush, alternating between itself and that secondary object when flushing.<br />
<br />
[[Category:Services]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Log_services&diff=10348Log services2020-12-01T19:45:52Z<p>XorTroll: </p>
<hr />
<div>= lm =<br />
This is "nn::lm::ILogService".<br />
<br />
This service is stubbed on retail, with all the commands/interfaces being present but returning success and doing anything.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#OpenLogger]]<br />
|}<br />
<br />
== OpenLogger ==<br />
<br />
Takes an input u64 value representing a process ID and returns an [[#ILogger]] instance.<br />
<br />
= lm:get =<br />
This is "nn::lm::ILogGetter". This service doesn't exist on retail.<br />
<br />
This service can be used to retrieve log messages (only the TextLog field, see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#StartLogging]]<br />
|-<br />
| 1 || [[#StopLogging]]<br />
|-<br />
| 2 || [[#GetLog]]<br />
|}<br />
<br />
== StartLogging ==<br />
Takes no input and no output, and just sets a global flag to true.<br />
<br />
== StopLogging ==<br />
Same as above, but the flag is set to false.<br />
<br />
== GetLog ==<br />
Takes an output type-0x22 buffer, returns two output u64s (read size and packet drop count)<br />
The flag mentioned above is not checked here, as it is used in a different place (see [[#Logging]])<br />
<br />
= ILogger =<br />
This is "nn::lm::ILogger".<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Cmd || Name<br />
|-<br />
| 0 || [[#Log]]<br />
|-<br />
| 1 || [3.0.0+] [[#SetDestination]]<br />
|}<br />
<br />
== Log ==<br />
<br />
Takes a type-0x21 input buffer containing the message to log.<br />
Will always return successfully.<br />
<br />
== SetDestination ==<br />
<br />
Takes an input u32 mask value indicating the logging destinations to send incoming log messages to. The mask entries are as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Description<br />
|-<br />
| 1 || Log to SD card / HTCS<br />
|-<br />
| 2 || Disable something (?)<br />
|}<br />
<br />
= LogPacketHeader =<br />
This is "nn::lm::detail::LogPacketHeader"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x8 || Process ID<br />
|-<br />
| 0x8 || 0x8 || Thread ID<br />
|-<br />
| 0x10 || 0x1 || [[#LogPacketFlags]]<br />
|-<br />
| 0x11 || 0x1 || Padding/reserved<br />
|-<br />
| 0x12 || 0x1 || [[#LogSeverity]]<br />
|-<br />
| 0x13 || 0x1 || Verbosity<br />
|-<br />
| 0x14 || 0x4 || Payload size<br />
|}<br />
<br />
= LogPacketFlags =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 1 || Head<br />
|-<br />
| 2 || Tail<br />
|-<br />
| 4 || LittleEndian<br />
|}<br />
<br />
= Binary header =<br />
Binary log files saved in SD card have this extra header (see [[#Logging]])<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x4 || Magic ("hphp")<br />
|-<br />
| 0x4 || 0x1 || Version (1)<br />
|-<br />
| 0x5 || 0x3 || Padding/reserved<br />
|}<br />
<br />
= LogSeverity =<br />
This is "nn::diag::LogSeverity"<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name<br />
|-<br />
| 0 || Trace<br />
|-<br />
| 1 || Info<br />
|-<br />
| 2 || Warn<br />
|-<br />
| 3 || Error<br />
|-<br />
| 4 || Fatal<br />
|}<br />
<br />
= LogDataChunkKey =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Value || Name || Description<br />
|-<br />
| 0 || LogSessionBegin || Special field sent when a process starts logging (see [[#Logging]])<br />
|-<br />
| 1 || LogSessionEnd || Special field sent when a process finishes logging (see [[#Logging]])<br />
|-<br />
| 2 || TextLog || Actual log text.<br />
|-<br />
| 3 || LineNumber || Line number.<br />
|-<br />
| 4 || FileName || File name.<br />
|-<br />
| 5 || FunctionName || Function name.<br />
|-<br />
| 6 || ModuleName || Module name.<br />
|-<br />
| 7 || ThreadName || Thread name.<br />
|-<br />
| 8 || LogPacketDropCount || Special field containing the amount of packets missed (failed to log/flush, see [[#Logging]])<br />
|-<br />
| 9 || UserSystemClock || Time value.<br />
|-<br />
| 10 || ProcessName || Process name.<br />
|}<br />
<br />
= Data chunks =<br />
Data chunks (log packet data fields) follow this format:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || Variable (normally 0x1) || [[#LogDataChunkKey]] in LEB128 format<br />
|-<br />
| Variable || Variable (normally 0x1) || Chunk size in LEB128 format<br />
|-<br />
| Variable || Chunk size || Chunk data<br />
|}<br />
<br />
= Log packet =<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Description<br />
|-<br />
| 0x0 || 0x18 || [[#LogPacketHeader]]<br />
|-<br />
| 0x18 || Variable || Data chunks<br />
|}<br />
<br />
= Logging =<br />
<br />
LogManager uses two separate threads: a flushing thread and a htcs thread (main thread is handling both IPC and PM module requests):<br />
<br />
* The flushing calls Flush() on the "LogBuffer" object, which is the object responsible for flushing logged data though the other objects, and sends a LogPacketDropCount packet via the "EventLogTransmitter" object (see below) if there any dropped packets and the flushing succeeds - this is done in a loop, waiting until the process starts finalization.<br />
<br />
* The htcs thread continously reads from the server connection, and will close and reopen the client socket if the connection happened to be lost - this is done in a loop, waiting until the process starts finalization.<br />
<br />
Different global objects are used for different purposes:<br />
<br />
* SdCardLogging object - saves logs on the SD card, if both <code>lm!sd_card_log_output_directory</code> and <code>lm!enable_sd_card_logging</code> are present and the last one is true:<br />
** The file name format used is <code>sd:/<log_output_directory>/<serial_no>_<year><month><day><hour><min><sec>[_<extra_index>].nxbinlog</code>, where the extra index is added if the file is already present (several logs being saved at the same time), with a maximum value of 100 (otherwise the saving fails).<br />
** These binary files contain multiple log packets, always preceded by a binary header (see above).<br />
** A single file is used for all the log packets, if the SD card gets ejected or something similar happens the code will re-mount it when it's ready and create a new file.<br />
<br />
* LogServerProxy object - sends log data via HTCS (see [[TMA_services]])<br />
<br />
* LogGetterLogger object - retains log data which can be later retrieved by [[#lm:get]]:<br />
** When processes log via [[#lm]] service, some code analyzes the log packet, locates the TextLog ([[#LogDataChunkKey]]) chunk (if present) and saves it's contents in a global buffer (therefore, only the actual log message gets retained).<br />
** Log packets are only analyzed/retained after enabling it (by calling [[#StartLogging]]), and the [[#GetLog]] command just reads data from the global buffer.<br />
** The analyzing code also keeps track of which packets are "missed" (skipped/not properly logged), and that missed packet count can be also retrieved on the [[#GetLog]] command.<br />
** When the global buffer is full, nothing will get logged until a process reads the logged data, cleaning the buffer.<br />
<br />
* EventLogTransmitter object - sends special log packets (event logs):<br />
** When an [[#ILogger]] gets created, this object will send a packet containing the logger's process ID and a LogSessionBegin chunk, telling the remote connection that a new process has started logging. Analogously, when the logger gets destroyed, a simple packet with the process ID and a LogSessionEnd chunk gets sent, telling the remote connection that the process has stopped logging.<br />
** As mentioned above, the flush thread will tell this object to send a simple packet with a LogPacketDropCount chunk after flushing succeeds (and if there any dropped packets).<br />
** These event log packets are logged via the LogBuffer object, like process logs, but they are not analized by the LogGetterLogger object since they have no text to be saved.<br />
<br />
* LogBuffer object - responsible for flushing log packets:<br />
** It internally calls the SdCardLogging and LogServerProxy objects when flushing, so that log packets get flushed to both SD card (if enabled) and HTCS.<br />
** It uses a secondary object to flush, alternating between itself and that secondary object when flushing.<br />
<br />
[[Category:Services]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Profile_Selector&diff=7411Profile Selector2019-08-15T15:09:18Z<p>XorTroll: </p>
<hr />
<div>This is the applet presented when launching a game that allows the user to select a user.<br />
<br />
See [[AM_services#Library_Applets]]. The profile selector expects a two [[AM_services#IStorage|IStorage]] inputs and a single [[AM_services#IStorage|IStorage]] output.<br />
<br />
== UserSelectionConfig ==<br />
<br />
This has size 0xA0 and seems to only affect the UI display. Typical value is all zero with byte 0x96 equal to 0x01.<br />
Setting the first byte to 1 will make the applet display in order to create a new user.<br />
"starter" sets the first byte to 5 in order to display initial user setup.<br />
<br />
== Result == <br />
This is 0x18-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Notes<br />
|-<br />
| 0x0 || 0x8 || Result (0 = Success, 2 = Failure)<br />
|-<br />
| 0x8 || 0x10 || UUID of selected user<br />
|-<br />
|}<br />
<br />
== Usage == <br />
User-processes should push a common arguments struct and the typical UserSelectionConfig struct as well. After pushing in the data and calling start, user-processes should wait upon the PopOutDataEvent and then pop a single IStorage to obtain the result structure described above.<br />
<br />
[[Category:Library Applets]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Glossary&diff=6238Glossary2019-02-17T12:21:58Z<p>XorTroll: </p>
<hr />
<div>=== (In Alphabetical Order, Descending) ===<br />
{| class="wikitable" border="1"<br />
! Acronyms<br />
! Full Name<br />
! Notes<br />
|-<br />
| [[AM_services|AM]]<br />
| Applet Manager<br />
|<br />
|-<br />
| [[APM_services|APM]]<br />
| Applet Profile Manager<br />
|<br />
|-<br />
| [[BCAT_services|BCAT]]<br />
| Background Content Asymmetric synchronized delivery and Transmission<br />
|<br />
|-<br />
| [[BCT|BCT]]<br />
| Boot Configuration Table<br />
|<br />
|-<br />
| [[BNVIB|BNVIB]]<br />
| Binary NX Vibration<br />
|<br />
|-<br />
| [[BPC_services|BPC]]<br />
| Board Power Control Manager<br />
| This is related to the [[PCV_services#bpc|PCV Services]].<br />
|-<br />
| DMA<br />
| Direct Memory Access<br />
|<br />
|-<br />
| [[EMMC_pinout|EMMC pinout]]<br />
| Embedded Multi-Media Controller pinout<br />
|<br />
|-<br />
| [[Eupld_services|Eupld]]<br />
| Error upload services<br />
|<br />
|-<br />
| [[ExeFS|ExeFS]]<br />
| Executable File System<br />
|<br />
|-<br />
| [[Falcon|Falcon]]<br />
| A microprocessor used in various Tegra specific engines like TSEC, NVDEC, VIC, etc.<br />
| See [http://envytools.readthedocs.io/en/latest/hw/falcon/intro.html the manual] for more information.<br />
|-<br />
| [[Flog|Flog]]<br />
| NES Golf, spelled backwards<br />
|<br />
|-<br />
| GMMU<br />
| Graphics Memory Management Unit<br />
|<br />
|-<br />
| [[GRC_services|GRC]]<br />
| Game Recording services<br />
|<br />
|-<br />
| [[HID_services|HID]]<br />
| Human Interface Device services<br />
|<br />
|-<br />
| [[Homebrew_ABI|Homebrew ABI]]<br />
| Homebrew Application Binary Interface<br />
|<br />
|-<br />
| [[IMKV|IMKV]]<br />
| IM Key Value databases found in FS and NCM savedata archives<br />
|<br />
|-<br />
| [[INI1|INI1]]<br />
| Part of the [[Package2|Package2]] section containing built-in system modules<br />
|<br />
|-<br />
| [[IPC_Marshalling|IPC Marshalling]]<br />
| Inter-Process Communication Marshalling<br />
|<br />
|-<br />
| [https://en.wikipedia.org/wiki/Interrupt_request_(PC_architecture) IRQ]<br />
| Interrupt Request<br />
|<br />
|-<br />
| [[Jpegdec_services|Jpegdec]]<br />
| Refactored sysmodule for handling all JPEG decoding associated with capture services<br />
|<br />
|-<br />
| [[LAN_Adapter|LAN Adapter]]<br />
| Local area network adapter<br />
|<br />
|-<br />
| [[LDN_services|LDN]]<br />
| Local device network services<br />
|<br />
|-<br />
| [[Manu_Services|Manu]]<br />
| Manufacturing Services<br />
|<br />
|-<br />
| [[NAX0|NAX0]]<br />
| Nintendo AES XTS file system / file format<br />
| Long form name is known as the Advanced Encryption Standard XEX-based tweaked-codebook mode with ciphertext stealing file system / file format<br />
|-<br />
| [[NCA_Format|NCA]]<br />
| Nintendo Content Archive<br />
| <br />
|-<br />
| NSP<br />
| Nintendo Submission Package<br />
| <br />
|-<br />
| [[NCM_services|NCM]]<br />
| Nintendo Content Management services<br />
|<br />
|-<br />
| [[NIM_services|NIM]]<br />
| Network Install Manager services<br />
|<br />
|-<br />
| [[NPDM|NPDM]]<br />
| Nintendo Program Descriptor Metadata<br />
| <br />
|-<br />
| NRO<br />
| Nintendo Relocatable Object<br />
|<br />
|-<br />
| [[NSO|NSO]]<br />
| Main executable format<br />
|<br />
|-<br />
| [[NS_Services|NS]]<br />
| Nintendo Shell services<br />
|<br />
|-<br />
| [[NV_services|NV]]<br />
| Customized NVIDIA driver<br />
|<br />
|-<br />
| [[Nvnflinger_services|Nvnflinger]]<br />
| Responsible for mediating the communication between [[Display_services|vi]] and [[NV_services|nvservices]].<br />
|<br />
|-<br />
| [[AM_services#omm|OMM]]<br />
| Operation Mode Manager, responsible for arbitrating the operation changes between docked and handheld modes<br />
| See [[AM_services|AM Services]] for more information.<br />
|-<br />
| [[PCIe_services|PCIe]]<br />
| Peripheral Component Interconnect Express services<br />
|<br />
|-<br />
| [[PCV_services|PCV]]<br />
| Power Control / Voltage services<br />
|<br />
|-<br />
| [[Package1|PK11]]<br />
| Encrypted binary stored in [[Package1]].<br />
|<br />
|-<br />
| [[Package2|PK21]]<br />
| Contains the Switch kernel and the built-in system modules<br />
|<br />
|-<br />
| PMC<br />
| Power Management Controller<br />
|<br />
|-<br />
| [[SD_Filesystem|SD File System]]<br />
| Secure Digital File System<br />
|<br />
|-<br />
| Secmon<br />
| Secure Monitor<br />
|<br />
|-<br />
| [[Secure_RNG_services|Secure RNG]]<br />
| Also known as the [[SPL_services|SPL Services]]<br />
|<br />
|-<br />
| [[Services_API|Services API]]<br />
| Services application programming interface<br />
|<br />
|-<br />
| [[SMC|SMC]]<br />
| Secure Monitor Calls<br />
|<br />
|-<br />
| [[SPL_services|SPL]]<br />
| Secure Platform Services<br />
|<br />
|-<br />
| [[SSL_services|SSL]]<br />
| Secure Sockets Layer services<br />
|<br />
|-<br />
| [[SVC|SVC]]<br />
| Supervisor Call instruction<br />
|<br />
|-<br />
| [[TMA_services|TMA]]<br />
| Target Manager<br />
|<br />
|-<br />
| [[TSEC|TSEC]]<br />
| Tegra Security Co-processor<br />
|<br />
|-<br />
| [[Joy-Con_Firmware|Ukyo]]<br />
| Internal name for the Joy-Con firmware. <br />
|<br />
|-<br />
| [[XCI|XCI]]<br />
| Nintendo Switch Gamecard Format<br />
|<br />
|-<br />
|}</div>XorTrollhttps://switchbrew.org/w/index.php?title=Glossary&diff=6237Glossary2019-02-17T12:20:46Z<p>XorTroll: Add NSP</p>
<hr />
<div>=== (In Alphabetical Order, Descending) ===<br />
{| class="wikitable" border="1"<br />
! Acronyms<br />
! Full Name<br />
! Notes<br />
|-<br />
| [[AM_services|AM]]<br />
| Applet Manager<br />
|<br />
|-<br />
| [[APM_services|APM]]<br />
| Applet Profile Manager<br />
|<br />
|-<br />
| [[BCAT_services|BCAT]]<br />
| Background Content Asymmetric synchronized delivery and Transmission<br />
|<br />
|-<br />
| [[BCT|BCT]]<br />
| Boot Configuration Table<br />
|<br />
|-<br />
| [[BNVIB|BNVIB]]<br />
| Binary NX Vibration<br />
|<br />
|-<br />
| [[BPC_services|BPC]]<br />
| Board Power Control Manager<br />
| This is related to the [[PCV_services#bpc|PCV Services]].<br />
|-<br />
| DMA<br />
| Direct Memory Access<br />
|<br />
|-<br />
| [[EMMC_pinout|EMMC pinout]]<br />
| Embedded Multi-Media Controller pinout<br />
|<br />
|-<br />
| [[Eupld_services|Eupld]]<br />
| Error upload services<br />
|<br />
|-<br />
| [[ExeFS|ExeFS]]<br />
| Executable File System<br />
|<br />
|-<br />
| [[Falcon|Falcon]]<br />
| A microprocessor used in various Tegra specific engines like TSEC, NVDEC, VIC, etc.<br />
| See [http://envytools.readthedocs.io/en/latest/hw/falcon/intro.html the manual] for more information.<br />
|-<br />
| [[Flog|Flog]]<br />
| NES Golf, spelled backwards<br />
|<br />
|-<br />
| GMMU<br />
| Graphics Memory Management Unit<br />
|<br />
|-<br />
| [[GRC_services|GRC]]<br />
| Game Recording services<br />
|<br />
|-<br />
| [[HID_services|HID]]<br />
| Human Interface Device services<br />
|<br />
|-<br />
| [[Homebrew_ABI|Homebrew ABI]]<br />
| Homebrew Application Binary Interface<br />
|<br />
|-<br />
| [[IMKV|IMKV]]<br />
| IM Key Value databases found in FS and NCM savedata archives<br />
|<br />
|-<br />
| [[INI1|INI1]]<br />
| Part of the [[Package2|Package2]] section containing built-in system modules<br />
|<br />
|-<br />
| [[IPC_Marshalling|IPC Marshalling]]<br />
| Inter-Process Communication Marshalling<br />
|<br />
|-<br />
| [https://en.wikipedia.org/wiki/Interrupt_request_(PC_architecture) IRQ]<br />
| Interrupt Request<br />
|<br />
|-<br />
| [[Jpegdec_services|Jpegdec]]<br />
| Refactored sysmodule for handling all JPEG decoding associated with capture services<br />
|<br />
|-<br />
| [[LAN_Adapter|LAN Adapter]]<br />
| Local area network adapter<br />
|<br />
|-<br />
| [[LDN_services|LDN]]<br />
| Local device network services<br />
|<br />
|-<br />
| [[Manu_Services|Manu]]<br />
| Manufacturing Services<br />
|<br />
|-<br />
| [[NAX0|NAX0]]<br />
| Nintendo AES XTS file system / file format<br />
| Long form name is known as the Advanced Encryption Standard XEX-based tweaked-codebook mode with ciphertext stealing file system / file format<br />
|-<br />
| [[NCA_Format|NCA]]<br />
| Nintendo Content Archive<br />
| <br />
|-<br />
| [[NSP_Format|NSP]]<br />
| Nintendo Submission Package<br />
| <br />
|-<br />
| [[NCM_services|NCM]]<br />
| Nintendo Content Management services<br />
|<br />
|-<br />
| [[NIM_services|NIM]]<br />
| Network Install Manager services<br />
|<br />
|-<br />
| [[NPDM|NPDM]]<br />
| Nintendo Program Descriptor Metadata<br />
| <br />
|-<br />
| NRO<br />
| Nintendo Relocatable Object<br />
|<br />
|-<br />
| [[NSO|NSO]]<br />
| Main executable format<br />
|<br />
|-<br />
| [[NS_Services|NS]]<br />
| Nintendo Shell services<br />
|<br />
|-<br />
| [[NV_services|NV]]<br />
| Customized NVIDIA driver<br />
|<br />
|-<br />
| [[Nvnflinger_services|Nvnflinger]]<br />
| Responsible for mediating the communication between [[Display_services|vi]] and [[NV_services|nvservices]].<br />
|<br />
|-<br />
| [[AM_services#omm|OMM]]<br />
| Operation Mode Manager, responsible for arbitrating the operation changes between docked and handheld modes<br />
| See [[AM_services|AM Services]] for more information.<br />
|-<br />
| [[PCIe_services|PCIe]]<br />
| Peripheral Component Interconnect Express services<br />
|<br />
|-<br />
| [[PCV_services|PCV]]<br />
| Power Control / Voltage services<br />
|<br />
|-<br />
| [[Package1|PK11]]<br />
| Encrypted binary stored in [[Package1]].<br />
|<br />
|-<br />
| [[Package2|PK21]]<br />
| Contains the Switch kernel and the built-in system modules<br />
|<br />
|-<br />
| PMC<br />
| Power Management Controller<br />
|<br />
|-<br />
| [[SD_Filesystem|SD File System]]<br />
| Secure Digital File System<br />
|<br />
|-<br />
| Secmon<br />
| Secure Monitor<br />
|<br />
|-<br />
| [[Secure_RNG_services|Secure RNG]]<br />
| Also known as the [[SPL_services|SPL Services]]<br />
|<br />
|-<br />
| [[Services_API|Services API]]<br />
| Services application programming interface<br />
|<br />
|-<br />
| [[SMC|SMC]]<br />
| Secure Monitor Calls<br />
|<br />
|-<br />
| [[SPL_services|SPL]]<br />
| Secure Platform Services<br />
|<br />
|-<br />
| [[SSL_services|SSL]]<br />
| Secure Sockets Layer services<br />
|<br />
|-<br />
| [[SVC|SVC]]<br />
| Supervisor Call instruction<br />
|<br />
|-<br />
| [[TMA_services|TMA]]<br />
| Target Manager<br />
|<br />
|-<br />
| [[TSEC|TSEC]]<br />
| Tegra Security Co-processor<br />
|<br />
|-<br />
| [[Joy-Con_Firmware|Ukyo]]<br />
| Internal name for the Joy-Con firmware. <br />
|<br />
|-<br />
| [[XCI|XCI]]<br />
| Nintendo Switch Gamecard Format<br />
|<br />
|-<br />
|}</div>XorTrollhttps://switchbrew.org/w/index.php?title=Error_applet&diff=6019Error applet2019-01-10T21:16:59Z<p>XorTroll: /* Error applet types */</p>
<hr />
<div>The error applet is used to display an error result by several titles and applets. (AppletId 0xE)<br />
<br />
Depending on the type, the applet will display the error in several ways.<br />
<br />
It takes two input storages: common arguments and a custom storage.<br />
<br />
== Error applet types ==<br />
<br />
=== Error (common one) ===<br />
<br />
Takes a CommonArgs storage with version 0.<br />
<br />
==== Custom storage ====<br />
<br />
Unknown exact size, using size 20 seems to work fine.<br />
<br />
The type (byte 0 of this storage) is 0.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Typical Value || Notes <br />
|-<br />
| 0x10 || 4 (u32) || 0 (2000-0000) || Result code, same Result type used everywhere in HOS.<br />
|}<br />
<br />
The error will display error code 2000-0000 if the Result is not set. The text is the default one.<br />
<br />
=== SystemError ===<br />
<br />
Takes a CommonArgs storage with version 0.<br />
<br />
==== Custom storage ====<br />
<br />
SDK uses size 4120 for this storage.<br />
<br />
The type (byte 0 of this storage) is 1.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Typical Value || Notes<br />
|-<br />
| 0x8 || 8 (u64) || 0 (0000-0000) || ErrorCode (not Result like in normal errors) of the error to use.<br />
|-<br />
| 0x18 || 0x800 || - || String of the text to be shown as a short description of the error.<br />
|-<br />
| 0x818 || 0x800 || - || String of the text to be shown as a more detailed description of the error.<br />
|}<br />
<br />
If the first text is not specified but the second one is, the applet will directly load the "Details" display with the second error text.<br />
<br />
If both texts are set, the applet will load the dialog with "Close" and "Details" options, and will load the display mentiones above after selecting "Details".<br />
<br />
If no ErrorCode is supplied, the applet will use 0000-0000.<br />
<br />
=== ApplicationError ===<br />
<br />
Apparently similar to SystemError, has type (byte 0 of the second storage) 258, with almost same offsets.<br />
<br />
More info needs to be added about this type.</div>XorTrollhttps://switchbrew.org/w/index.php?title=Error_applet&diff=6018Error applet2019-01-10T21:16:02Z<p>XorTroll: Add new information</p>
<hr />
<div>The error applet is used to display an error result by several titles and applets. (AppletId 0xE)<br />
<br />
Depending on the type, the applet will display the error in several ways.<br />
<br />
It takes two input storages: common arguments and a custom storage.<br />
<br />
== Error applet types ==<br />
<br />
=== Error (common one) ===<br />
<br />
Takes a CommonArgs storage with version 0.<br />
<br />
==== Custom storage ====<br />
<br />
Unknown exact size, using size 20 seems to work fine.<br />
<br />
The type (byte 0 of this storage) is 0.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Typical Value || Notes <br />
|-<br />
| 0x10 || 4 (u32) || 0 (2000-0000) || Result code, same Result used everywhere in HOS.<br />
|}<br />
<br />
The error will display error code 2000-0000 if the Result is not set. The text is the default one.<br />
<br />
=== SystemError ===<br />
<br />
Takes a CommonArgs storage with version 0.<br />
<br />
==== Custom storage ====<br />
<br />
SDK uses size 4120 for this storage.<br />
<br />
The type (byte 0 of this storage) is 1.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Typical Value || Notes<br />
|-<br />
| 0x8 || 8 (u64) || 0 (0000-0000) || ErrorCode (not Result like in normal errors) of the error to use.<br />
|-<br />
| 0x18 || 0x800 || - || String of the text to be shown as a short description of the error.<br />
|-<br />
| 0x818 || 0x800 || - || String of the text to be shown as a more detailed description of the error.<br />
|}<br />
<br />
If the first text is not specified but the second one is, the applet will directly load the "Details" display with the second error text.<br />
<br />
If both texts are set, the applet will load the dialog with "Close" and "Details" options, and will load the display mentiones above after selecting "Details".<br />
<br />
If no ErrorCode is supplied, the applet will use 0000-0000.<br />
<br />
=== ApplicationError ===<br />
<br />
Apparently similar to SystemError, has type (byte 0 of the second storage) 258, with almost same offsets.<br />
<br />
More info needs to be added about this type.</div>XorTrollhttps://switchbrew.org/w/index.php?title=Error_applet&diff=5965Error applet2019-01-06T00:32:02Z<p>XorTroll: Created page with "The error applet is used to display an error result by several titles and applets. (AppletId 0xE) A dialog is displayed with the error code at the top, and with support text..."</p>
<hr />
<div>The error applet is used to display an error result by several titles and applets. (AppletId 0xE)<br />
<br />
A dialog is displayed with the error code at the top, and with support text plus a support page link in the dialog.<br />
<br />
It takes two input storages: common arguments and a custom storage.<br />
<br />
== Common arguments ==<br />
<br />
Version 0 according to official usage.<br />
<br />
<br />
== Error storage ==<br />
<br />
Has size 20.<br />
<br />
Apparently, the layout is changed by setting different values to the first byte.<br />
<br />
The error code is an u32/Result located at offset 16.</div>XorTrollhttps://switchbrew.org/w/index.php?title=Profile_Selector&diff=5964Profile Selector2019-01-05T22:43:14Z<p>XorTroll: </p>
<hr />
<div>This is the applet presented when launching a game that allows the user to select a user.<br />
<br />
See [[AM_services#Library_Applets]]. The profile selector expects a two [[AM_services#IStorage|IStorage]] inputs and a single [[AM_services#IStorage|IStorage]] output.<br />
<br />
== UserSelectionConfig ==<br />
<br />
This has size 0xA0 and seems to only affect the UI display. Typical value is all zero with byte 0x96 equal to 0x01.<br />
Setting the first byte to 1 will make the applet display in order to create a new user.<br />
<br />
== Result == <br />
This is 0x18-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Notes<br />
|-<br />
| 0x0 || 0x8 || Result (0 = Success, 2 = Failure)<br />
|-<br />
| 0x8 || 0x10 || UUID of selected user<br />
|-<br />
|}<br />
<br />
== Usage == <br />
User-processes should push a common arguments struct and the typical UserSelectionConfig struct as well. After pushing in the data and calling start, user-processes should wait upon the PopOutDataEvent and then pop a single IStorage to obtain the result structure described above.<br />
<br />
[[Category:Library Applets]]</div>XorTrollhttps://switchbrew.org/w/index.php?title=Profile_Selector&diff=5963Profile Selector2019-01-05T22:42:45Z<p>XorTroll: Add a bit of information</p>
<hr />
<div>This is the applet presented when launching a game that allows the user to select a user.<br />
<br />
See [[AM_services#Library_Applets]]. The profile selector expects a two [[AM_services#IStorage|IStorage]] inputs and a single [[AM_services#IStorage|IStorage]] output.<br />
<br />
== UserSelectionConfig ==<br />
<br />
This has size 0xA0 and seems to only affect the UI display. Typical value is all zero with byte 0x96 equal to 0x01.<br />
Setting the first byte to 1 display the applet in order to create a new user.<br />
<br />
== Result == <br />
This is 0x18-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset || Size || Notes<br />
|-<br />
| 0x0 || 0x8 || Result (0 = Success, 2 = Failure)<br />
|-<br />
| 0x8 || 0x10 || UUID of selected user<br />
|-<br />
|}<br />
<br />
== Usage == <br />
User-processes should push a common arguments struct and the typical UserSelectionConfig struct as well. After pushing in the data and calling start, user-processes should wait upon the PopOutDataEvent and then pop a single IStorage to obtain the result structure described above.<br />
<br />
[[Category:Library Applets]]</div>XorTroll