Changes

9,439 bytes added ,  18:22, 22 March 2022
Line 34: Line 34:  
| [[6.1.0]]
 
| [[6.1.0]]
 
| Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.10.14 NintendoBrowser/5.1.0.17806
 
| Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.10.14 NintendoBrowser/5.1.0.17806
 +
|-
 +
| [[10.0.0]]
 +
| Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20389
 
|}
 
|}
   Line 86: Line 89:  
| Just displays an error-code.
 
| Just displays an error-code.
 
| Yes
 
| Yes
 +
| 0100000000001010
 +
|
 +
|-
 +
| NsoApplet
 +
| Nintendo Switch Online menu
 +
|
 +
|
 
| 0100000000001010
 
| 0100000000001010
 
|  
 
|  
Line 120: Line 130:     
Prior to version [[3.0.0]], this applet was launched when attempting a system update from recovery mode if needed. This was changed to display a "This feature is not available." popup instead.
 
Prior to version [[3.0.0]], this applet was launched when attempting a system update from recovery mode if needed. This was changed to display a "This feature is not available." popup instead.
 +
 +
The conntest URL from [[#WebWifiPageArg]] is used to poll whether the connection is usable, with the SDK [[libcurl]].
    
==Whitelisted Applets==
 
==Whitelisted Applets==
Line 155: Line 167:  
   You can invite friends to the room via
 
   You can invite friends to the room via
 
   the Nintendo Switch Online Lounge app.
 
   the Nintendo Switch Online Lounge app.
 +
 +
=== NsoApplet ===
 +
[11.0.0+] This applet handles the new Nintendo Switch Online menu, which is launched from qlaunch.
 +
 +
The initial page loaded by this applet is: <nowiki>"https://%.nso.nintendo.net/</nowiki>{string from [[#TLVs|TLV]] 0x2}"
    
== ShopN ==
 
== ShopN ==
Line 201: Line 218:     
== Heap ==
 
== Heap ==
 +
The size used for [[SVC|svcSetHeapSize]] by the web-applets is 0x15600000. Under ShopN, the largest size that can be passed to this without an error being returned, is 0x1B400000.
   −
The size used for [[SVC|svcSetHeapSize]] by the web-applets is 0x15600000. Under ShopN, the largest size that can be passed to this without an error being returned, is 0x1B400000.
+
The size used by title 010000000000100A (on 10.0.0 at least) is 0x14200000.
 +
 
 +
The heap for the main-codebin (<code>malloc</code>/<code>operator new</code>) uses nn::lmem::*ExpHeap. [8.0.0+] <code>malloc</code>/<code>operator new</code> now checks the return-addr (addr located in a relevant NRO), with wkc_malloc_crashonfailure being called for the allocation if the check passes, otherwise a normal allocation is done (the code which runs for this will Abort if allocation fails).
 +
 
 +
<code>malloc</code> passes the input size directly to the called func. <code>operator new</code> when handling normal non-wkc allocations passes the following to the called func: <code>sxtw x1, {inw0}</code> (for wkc allocations the size is passed directly). [12.1.0+] The size is now passed directly (64bit) without using sxtw.
 +
 
 +
[11.0.0+] There's now optional code for using [[SVC|svcMapPhysicalMemoryUnsafe]] etc, however it's unknown what sets the flag for this. An Abort string used this is: "{path}/TransferredMemoryManager.cpp"
    
== Applet Launching ==
 
== Applet Launching ==
The web-applets are launched using a storage containing the input arg data, on exit the output storage contains the "*ReturnValue" reply data struct. The output struct is specific to each applet.
+
The web-applets are launched using a storage containing the input arg data, on exit the output storage contains the "*ReturnValue" reply data.
 +
 
 +
Input/output storage size for TLV data is 0x2000-bytes.
    
=== Library Applet Versions ===
 
=== Library Applet Versions ===
Line 217: Line 243:  
|-
 
|-
 
| [5.0.0+] || 0x50000
 
| [5.0.0+] || 0x50000
 +
|-
 +
| [6.0.0+] || 0x60000
 +
|-
 +
| [8.0.0+] || 0x80000
 
|}
 
|}
   Line 236: Line 266:  
| 2
 
| 2
 
| Login
 
| Login
 +
|-
 +
| 3
 +
| Offline
 
|-
 
|-
 
| 4
 
| 4
Line 248: Line 281:  
| 7
 
| 7
 
| Lobby
 
| Lobby
 +
|-
 +
| 8
 +
| [[#NsoApplet|Lhub]]
 +
|}
 +
 +
=== WebSession ===
 +
With [5.0.0+] sdk-nso added <code>nn::web::Session::</code>. With [6.0.0+] this was removed, however it was reintroduced with [7.0.0+] as <code>nn::web::*WebSession</code> (for ShimKind Offline and Web).
 +
 +
This is for sending/receiving [[#SessionMessage]]s via applet Interactive storage.
 +
 +
During state init, max_messages is set to 0xA ([7.0.0+] 0x10), with message_count=0 and cur_size=0. [5.0.0-5.1.0] max_size is set to 0x5000. [7.0.0+] Two queues are used for message_count/cur_size: first one is for BrowserEngineContent (max_size 0x8000 is used), the second one is for non-BrowserEngineContent (max_size 0x1000 is used).
 +
 +
When sending messages, there has to be an available message slot available (<code>max_messages!=message_count</code>), and there has to be enough space available (<code>msghdr_contentsize+0x10 + cur_size <= max_size</code>). After pushing the storage, message_count is incremented and cur_size is increased by <code>msghdr_contentsize+0x10</code>.
 +
 +
When receiving messages, it will repeatedly pop Interactive output storage until no more are available. Non-Ack messages are Acked.
 +
* Ack: Verifies that message_count is not already 0, then decrements it. Then cur_size is decreased by the u32 loaded from msgcontent+0.
 +
* 0x0: Does some validation. Reads the message content into the user buffer, when contentsize is non-zero. The original contentsize is written to an user output param. The last byte in the user buffer (contentsize clamped to the user max-buf-size, -1) is set to 0 for NUL-termination.
 +
 +
Next info was tested in 9.0.0
 +
 +
In the js side (which is only available when enabled via the JsExtensionEnabled TLV), there is a method called <code>window.nx.sendMessage(arg)</code> that sends data to the native side, this method returns a boolean indicating if sending was successful and accepts a string as an argument. The string is encoded like a C null terminated string in the message content. For receive messages from native part, there is a dom event called <code>message</code> which is dispatched when a message arrives. The event can be listened using <code>window.nx.addEventListener("message", callback)</code> being callback a function which first parameter is like a dom event arg and contains a member called <code>data</code> which contains the string decoded from the arrived message.
 +
 +
If messages aren't acked by the native part, js side will not longer receive messages. Ack to web applet '''must''' have 4 bytes after the message content or the applet will Abort.
 +
 +
==== SessionMessage ====
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x10
 +
| [[#SessionMessageHeader]]
 +
|-
 +
| 0x10
 +
| Size from header
 +
| Message content
 +
|-
 +
| After message content
 +
| 0x4 if message is ack, 0x0 otherwise
 +
| Padding
 +
|}
 +
 +
==== SessionMessageHeader ====
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| Message Kind ([[#WebSessionSendMessageKind]] / [[#WebSessionReceiveMessageKind]])
 +
|-
 +
| 0x4
 +
| 0x4
 +
| Data size following the header.
 +
|-
 +
| 0x8
 +
| 0x8
 +
| Unused
 +
|}
 +
 +
==== WebSessionSendMessageKind ====
 +
This is "nn::web::detail::WebSessionSendMessageKind".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  ID
 +
!  Content size
 +
!  Description
 +
|-
 +
| 0x0
 +
| Arbitrary
 +
| BrowserEngine Content, NUL-terminated string. Used to communicate with the applet via JsExtensions used by the Js being run by the applet on the current page.
 +
|-
 +
| 0x100
 +
| 0x0
 +
| SystemMessage Appear. Requests the applet to Appear, this is only needed with [[#WebSessionBootMode]] AllForegroundInitiallyHidden.
 +
|-
 +
| 0x1000
 +
| 0xC
 +
| Ack. Content: first u32 is the entire storage size of the message being acked, the rest is not used.
 +
|}
 +
 +
==== WebSessionReceiveMessageKind ====
 +
This is "nn::web::detail::WebSessionReceiveMessageKind".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  ID
 +
!  Content size
 +
!  Description
 +
|-
 +
| 0x0
 +
| Arbitrary
 +
| BrowserEngine Content, see [[#WebSessionSendMessageKind]].
 +
|-
 +
| 0x1000
 +
| 0xC
 +
| Ack BrowserEngine
 +
|-
 +
| 0x1001
 +
| 0xC
 +
| Ack SystemMessage
 
|}
 
|}
   Line 263: Line 402:  
| 0x104 || 0x400 || Initial URL navigated to by the applet.
 
| 0x104 || 0x400 || Initial URL navigated to by the applet.
 
|-
 
|-
| 0x504 || 0x10 || Account userID, 0 for common.
+
| 0x504 || 0x10 || NIFM Network UUID. Can be value zero. Only used by the applet when conntest_url is set.
 
|-
 
|-
| 0x514 || 0x4 || Unknown, this can be 0.
+
| 0x514 || 0x4 || Input value for nifm cmd SetRequirementByRevision. Can be value zero. Only used by the applet when conntest_url is set.
 
|}
 
|}
    
This is the input struct for WifiWebAuthApplet. This is a total of 0x518-bytes.
 
This is the input struct for WifiWebAuthApplet. This is a total of 0x518-bytes.
 +
 +
When the conntest_url is empty, the applet will test the connection with nifm and throw an error on failure.
    
=== WebWifiReturnValue ===
 
=== WebWifiReturnValue ===
Line 300: Line 441:  
|}
 
|}
   −
This is the 0x1010-byte output storage used by all non-WebWifi applets - except for Share which returns a TLV storage on [3.0.0+].
+
This is the 0x1010-byte output storage used by all non-WebWifi applets - except for Share which returns a TLV storage on [3.0.0+], and Web on [8.0.0+].
    
=== WebArgHeader ===
 
=== WebArgHeader ===
Line 334: Line 475:  
Web TLV used in the input web Arg storage, after [[#WebArgHeader]]. This is a total of 0x8-bytes.
 
Web TLV used in the input web Arg storage, after [[#WebArgHeader]]. This is a total of 0x8-bytes.
    +
=== WebBootFooterButtonEntry ===
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0 || 0x4 || [[#FooterButtonId]]
 +
|-
 +
| 0x4 || 0x1 || u8 bool visible flag
 +
|-
 +
| 0x5 || 0x2 || ?
 +
|-
 +
| 0x7 || 0x1 || ?
 +
|}
    
=== TLVs ===
 
=== TLVs ===
Line 430: Line 586:  
| 0x20
 
| 0x20
 
| [[Capture_services|AlbumEntry]]
 
| [[Capture_services|AlbumEntry]]
| AlbumEntry
+
| AlbumEntry0
 
|-
 
|-
 
| [1.0.0+]
 
| [1.0.0+]
Line 506: Line 662:  
| 0x1B
 
| 0x1B
 
| 0x4
 
| 0x4
| u32 enum *LeftStickMode
+
| u32 enum [[#LeftStickMode]]
 
| LeftStickMode
 
| LeftStickMode
 
|-
 
|-
Line 556: Line 712:  
| 0x1
 
| 0x1
 
| u8 bool
 
| u8 bool
| MediaPlayerUserGestureRestrictionEnabled
+
| [6.0.0+] MediaAutoPlayEnabled ([2.0.0-5.1.0] MediaPlayerUserGestureRestrictionEnabled)
 
|-
 
|-
 
| [2.0.0+]
 
| [2.0.0+]
Line 605: Line 761:  
| 0x10
 
| 0x10
 
| u8 array
 
| u8 array
| AdditionalMediaData (If the user-input size is less than 0x10, the remaining tmp data used for the TLV is cleared)
+
| AdditionalMediaData0 (If the user-input size is less than 0x10, the remaining tmp data used for the TLV is cleared)
 
|-
 
|-
 
| [4.0.0+]
 
| [4.0.0+]
Line 676: Line 832:  
| u8 bool
 
| u8 bool
 
| PageScrollIndicatorEnabled
 
| PageScrollIndicatorEnabled
 +
|-
 +
| [6.0.0+]
 +
|
 +
| 0x37
 +
| 0x1
 +
| u8 bool
 +
| MediaPlayerSpeedControlEnabled
 +
|-
 +
| [6.0.0+]
 +
| Share
 +
| 0x38
 +
| 0x20
 +
| [[Capture_services|AlbumEntry]]
 +
| AlbumEntry1
 +
|-
 +
| [6.0.0+]
 +
| Share
 +
| 0x39
 +
| 0x20
 +
| [[Capture_services|AlbumEntry]]
 +
| AlbumEntry2
 +
|-
 +
| [6.0.0+]
 +
| Share
 +
| 0x3A
 +
| 0x20
 +
| [[Capture_services|AlbumEntry]]
 +
| AlbumEntry3
 +
|-
 +
| [6.0.0+]
 +
| Share
 +
| 0x3B
 +
| 0x10
 +
| u8 array
 +
| AdditionalMediaData1
 +
|-
 +
| [6.0.0+]
 +
| Share
 +
| 0x3C
 +
| 0x10
 +
| u8 array
 +
| AdditionalMediaData2
 +
|-
 +
| [6.0.0+]
 +
| Share
 +
| 0x3D
 +
| 0x10
 +
| u8 array
 +
| AdditionalMediaData3
 +
|-
 +
| [6.0.0+]
 +
| BootFooterButton
 +
| 0x3E
 +
| 0x80
 +
| Array of [[#WebBootFooterButtonEntry]] with 0x10 entries.
 +
| BootFooterButton
 +
|-
 +
| [6.0.0+]
 +
|
 +
| 0x3F
 +
| 0x4
 +
| float
 +
| OverrideWebAudioVolume
 +
|-
 +
| [6.0.0+]
 +
|
 +
| 0x40
 +
| 0x4
 +
| float
 +
| OverrideMediaAudioVolume
 +
|-
 +
| [7.0.0+]
 +
|
 +
| 0x41
 +
| 0x4
 +
| u32 enum [[#WebSessionBootMode]]
 +
| BootMode
 +
|-
 +
| [7.0.0+]
 +
|
 +
| 0x42
 +
| 0x1
 +
| u8 bool
 +
| Enables using [[#WebSession]] when set.
 +
|-
 +
| [8.0.0+]
 +
| Offline
 +
| 0x43
 +
| 0x1
 +
| u8 bool
 +
| MediaPlayerUiEnabled
 +
|-
 +
| [11.0.0+]
 +
|
 +
| 0x44
 +
| 0x1
 +
| bool
 +
| TransferMemoryEnabled
 
|}
 
|}
    
Offline: title to load the content from is controlled by ApplicationId/SystemDataId. With DocumentKind_OfflineHtmlPage, it will ignore this and only load from the user-process title.
 
Offline: title to load the content from is controlled by ApplicationId/SystemDataId. With DocumentKind_OfflineHtmlPage, it will ignore this and only load from the user-process title.
   −
Offline DocumentPath: Initial document path in RomFS, without the leading '/'. For DocumentKind_OfflineHtmlPage, this is relative to "html-document/" in RomFS. For the other DocumentKind values, this is relative to "/" in RomFS.
+
Offline DocumentPath: Initial document path in RomFS, without the leading '/'. For DocumentKind_OfflineHtmlPage, this is relative to "html-document/" in RomFS. For the other DocumentKind values, this is relative to "/" in RomFS. This path must contain ".htdocs/".
    
Share/Lobby: if a non-zero userID isn't set, the applet will launch the profile-selector applet to select an account.
 
Share/Lobby: if a non-zero userID isn't set, the applet will launch the profile-selector applet to select an account.
    
Share: An error will be displayed if neither AlbumEntry or ApplicationAlbumEntry are set, with [[#ShareStartPage|ShareStartPage_Default]].
 
Share: An error will be displayed if neither AlbumEntry or ApplicationAlbumEntry are set, with [[#ShareStartPage|ShareStartPage_Default]].
 +
 +
[6.0.0+] <code>AddAlbumEntryAndMediaData</code> was added:
 +
* Looks for AlbumEntry{N} TLVs, when a TLV is not found it is written, then the associated AdditionalMediaData{N} TLV is written the same way as AdditionalMediaData0. If all AlbumEntry{N} TLVs already exist, this returns without writing anything.
 +
 +
TransferMemoryEnabled: sdknso only exposes this for the Web applet. The sdknso func uses <code>nn::os::QueryMemoryInfo</code> at the start of the func, however the output is unused. The applet doesn't seem to parse this TLV.
    
==== Output TLVs ====
 
==== Output TLVs ====
Line 690: Line 949:  
|-
 
|-
 
!  System Version
 
!  System Version
 +
!  Applets
 
!  Type
 
!  Type
 
!  Size
 
!  Size
Line 696: Line 956:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share, Web
 
| 0x1
 
| 0x1
 
| 0x4
 
| 0x4
Line 702: Line 963:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share, Web
 
| 0x2
 
| 0x2
 
|  
 
|  
Line 708: Line 970:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share, Web
 
| 0x3
 
| 0x3
 
| 0x8
 
| 0x8
Line 714: Line 977:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share
 
| 0x4
 
| 0x4
 
| 0x4
 
| 0x4
Line 720: Line 984:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share
 
| 0x5
 
| 0x5
 
|  
 
|  
Line 726: Line 991:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share
 
| 0x6
 
| 0x6
 
| 0x8
 
| 0x8
Line 732: Line 998:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share
 
| 0x7
 
| 0x7
 
|  
 
|  
Line 738: Line 1,005:  
|-
 
|-
 
| [3.0.0+]
 
| [3.0.0+]
 +
| Share
 
| 0x8
 
| 0x8
 
| 0x8
 
| 0x8
 
| u64
 
| u64
 
| PostIdSize
 
| PostIdSize
 +
|-
 +
| [8.0.0+]
 +
| Web
 +
| 0x9
 +
| 0x1
 +
| u8 bool
 +
| MediaPlayerAutoClosedByCompletion
 
|}
 
|}
   −
These are used for Share-applet. Official user-processes doesn't check the TLV size for any of these.
+
These are used for Share-applet on [3.0.0+], and with Web on [8.0.0+]. Official user-processes doesn't check the TLV size for any of these.
    
==== DocumentKind ====
 
==== DocumentKind ====
Line 836: Line 1,111:  
| 1
 
| 1
 
|  
 
|  
| Unknown.
+
| Same as [[#BootDisplayKind]] value 3.
 
|-
 
|-
 
| 2
 
| 2
 
|  
 
|  
| Unknown. Used by Lobby default Arg initialization.
+
| Same as [[#BootDisplayKind]] value 4. Used by Lobby default Arg initialization.
 
|}
 
|}
    
Kind values for BackgroundKind. Only used when [[#BootDisplayKind]] is 0.
 
Kind values for BackgroundKind. Only used when [[#BootDisplayKind]] is 0.
 +
 +
==== LeftStickMode ====
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Value
 +
!  Name
 +
!  Description
 +
|-
 +
| 0
 +
| LeftStickMode_Pointer
 +
| The user can directly control the pointer via the left-stick.
 +
|-
 +
| 1
 +
| LeftStickMode_Cursor
 +
| The user can only select elements on the page via the left-stick.
 +
|}
 +
 +
Controls the initial mode, this can be toggled by the user via the pressing the left-stick button. If the Pointer flag is set to false, only LeftStickMode_Cursor will be used and mode toggle by the user is disabled (input value ignored).
 +
 +
==== FooterButtonId ====
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Value
 +
!  Name
 +
!  Description
 +
|-
 +
| 0
 +
| None
 +
| None, for empty [[#WebBootFooterButtonEntry]]. Invalid for use as an input Id.
 +
|-
 +
| 1
 +
|
 +
|
 +
|-
 +
| 2
 +
|
 +
|
 +
|-
 +
| 3
 +
|
 +
|
 +
|-
 +
| 4
 +
|
 +
|
 +
|-
 +
| 5
 +
|
 +
|
 +
|-
 +
| 6
 +
|
 +
|
 +
|-
 +
| 7
 +
|
 +
| Values starting with this are invalid.
 +
|-
 +
|}
 +
 +
==== WebSessionBootMode ====
 +
This is "nn::web::WebSessionBootMode".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Value
 +
!  Name
 +
!  Description
 +
|-
 +
| 0
 +
|
 +
| Normal/default (AllForeground)
 +
|-
 +
| 1
 +
|
 +
| AllForegroundInitiallyHidden
 +
|}
 +
 +
This controls which [[Applet_Manager_services|LibraryAppletMode]] the applet will be launched with, by the user-process. The TLV for this seems to be ignored by the applet.
    
==== LastUrl ====
 
==== LastUrl ====