Difference between revisions of "NIM services"

From Nintendo Switch Brew
Jump to navigation Jump to search
 
(105 intermediate revisions by 7 users not shown)
Line 1: Line 1:
=nim=
+
= nim =
 +
This is "nn::nim::detail::INetworkInstallManager".
  
=nim:shp=
+
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#CreateSystemUpdateTask]]
 +
|-
 +
| 1 || [[#DestroySystemUpdateTask]]
 +
|-
 +
| 2 || [[#ListSystemUpdateTask]]
 +
|-
 +
| 3 || RequestSystemUpdateTaskRun
 +
|-
 +
| 4 || [[#GetSystemUpdateTaskInfo]]
 +
|-
 +
| 5 || [[#CommitSystemUpdateTask]]
 +
|-
 +
| 6 || CreateNetworkInstallTaskDeprecated
 +
|-
 +
| 7 || DestroyNetworkInstallTask
 +
|-
 +
| 8 || ListNetworkInstallTask
 +
|-
 +
| 9 || [[#RequestNetworkInstallTaskRun]]
 +
|-
 +
| 10 || [[#GetNetworkInstallTaskInfo]]
 +
|-
 +
| 11 || CommitNetworkInstallTask
 +
|-
 +
| 12 || RequestLatestSystemUpdateMeta
 +
|-
 +
| 14 || ListApplicationNetworkInstallTask
 +
|-
 +
| 15 || ListNetworkInstallTaskContentMeta
 +
|-
 +
| 16 || RequestLatestVersion
 +
|-
 +
| 17 || SetNetworkInstallTaskAttribute
 +
|-
 +
| 18 || AddNetworkInstallTaskContentMeta
 +
|-
 +
| 19 || [[#GetDownloadedSystemDataPath]]
 +
|-
 +
| 20 || CalculateNetworkInstallTaskRequiredSize
 +
|-
 +
| 21 || [[#IsExFatDriverIncluded]]
 +
|-
 +
| 22 || GetBackgroundDownloadStressTaskInfo
 +
|-
 +
| 23 || [2.0.0+] RequestDeviceAuthenticationToken
 +
|-
 +
| 24 || [2.0.0+] RequestGameCardRegistrationStatus
 +
|-
 +
| 25 || [2.0.0+] RequestRegisterGameCard
 +
|-
 +
| 26 || [2.0.0+] RequestRegisterNotificationToken
 +
|-
 +
| 27 || [2.0.0+] RequestDownloadTaskList
 +
|-
 +
| 28 || [2.0.0+] RequestApplicationControl
 +
|-
 +
| 29 || [2.0.0+] RequestLatestApplicationControl
 +
|-
 +
| 30 || [2.0.0+] RequestVersionList
 +
|-
 +
| 31 || [2.0.0+] CreateApplyDeltaTask
 +
|-
 +
| 32 || [2.0.0+] DestroyApplyDeltaTask
 +
|-
 +
| 33 || [2.0.0+] ListApplicationApplyDeltaTask
 +
|-
 +
| 34 || [2.0.0+] RequestApplyDeltaTaskRun
 +
|-
 +
| 35 || [2.0.0+] [[#GetApplyDeltaTaskInfo]]
 +
|-
 +
| 36 || [2.0.0+] ListApplyDeltaTaskContentMeta
 +
|-
 +
| 37 || [2.0.0+] CommitApplyDeltaTask
 +
|-
 +
| 38 || [2.0.0+] CalculateApplyDeltaTaskRequiredSize
 +
|-
 +
| 39 || [2.0.0+] PrepareShutdown
 +
|-
 +
| 40 || [2.0.0+] ListApplyDeltaTask
 +
|-
 +
| 41 || [2.0.0+] ClearNotEnoughSpaceStateOfApplyDeltaTask
 +
|-
 +
| 42 || [3.0.0+] CreateApplyDeltaTaskFromDownloadTask
 +
|-
 +
| 43 || [3.0.0+] GetBackgroundApplyDeltaStressTaskInfo
 +
|-
 +
| 44 || [3.0.0+] GetApplyDeltaTaskRequiredStorage
 +
|-
 +
| 45 || [3.0.0+] CalculateNetworkInstallTaskContentsSize
 +
|-
 +
| 46 || [3.0.0+] PrepareShutdownForSystemUpdate
 +
|-
 +
| 47 || [4.0.0-9.2.0] FindMaxRequiredApplicationVersionOfTask
 +
|-
 +
| 48 || [4.0.0+] CommitNetworkInstallTaskPartially
 +
|-
 +
| 49 || [4.0.0+] ListNetworkInstallTaskCommittedContentMeta
 +
|-
 +
| 50 || [4.0.0+] ListNetworkInstallTaskNotCommittedContentMeta
 +
|-
 +
| 51 || [4.0.0+] FindMaxRequiredSystemVersionOfTask
 +
|-
 +
| 52 || [4.0.0+] GetNetworkInstallTaskErrorContext
 +
|-
 +
| 53 || [4.0.0+] [[#CreateLocalCommunicationReceiveApplicationTask]]
 +
|-
 +
| 54 || [4.0.0+] DestroyLocalCommunicationReceiveApplicationTask
 +
|-
 +
| 55 || [4.0.0+] ListLocalCommunicationReceiveApplicationTask
 +
|-
 +
| 56 || [4.0.0+] [[#RequestLocalCommunicationReceiveApplicationTaskRun]]
 +
|-
 +
| 57 || [4.0.0+] [[#GetLocalCommunicationReceiveApplicationTaskInfo]]
 +
|-
 +
| 58 || [4.0.0+] CommitLocalCommunicationReceiveApplicationTask
 +
|-
 +
| 59 || [4.0.0+] ListLocalCommunicationReceiveApplicationTaskContentMeta
 +
|-
 +
| 60 || [4.0.0+] [[#CreateLocalCommunicationSendApplicationTask]]
 +
|-
 +
| 61 || [4.0.0+] [[#RequestLocalCommunicationSendApplicationTaskRun]]
 +
|-
 +
| 62 || [4.0.0+] GetLocalCommunicationReceiveApplicationTaskErrorContext
 +
|-
 +
| 63 || [4.0.0+] [[#GetLocalCommunicationSendApplicationTaskInfo]]
 +
|-
 +
| 64 || [4.0.0+] DestroyLocalCommunicationSendApplicationTask
 +
|-
 +
| 65 || [4.0.0+] GetLocalCommunicationSendApplicationTaskErrorContext
 +
|-
 +
| 66 || [4.0.0+] CalculateLocalCommunicationReceiveApplicationTaskRequiredSize
 +
|-
 +
| 67 || [4.0.0+] [[#ListApplicationLocalCommunicationReceiveApplicationTask]]
 +
|-
 +
| 68 || [4.0.0+] [[#ListApplicationLocalCommunicationSendApplicationTask]]
 +
|-
 +
| 69 || [4.0.0+] [[#CreateLocalCommunicationReceiveSystemUpdateTask]]
 +
|-
 +
| 70 || [4.0.0+] DestroyLocalCommunicationReceiveSystemUpdateTask
 +
|-
 +
| 71 || [4.0.0+] [[#ListLocalCommunicationReceiveSystemUpdateTask]]
 +
|-
 +
| 72 || [4.0.0+] [[#RequestLocalCommunicationReceiveSystemUpdateTaskRun]]
 +
|-
 +
| 73 || [4.0.0+] [[#GetLocalCommunicationReceiveSystemUpdateTaskInfo]]
 +
|-
 +
| 74 || [4.0.0+] CommitLocalCommunicationReceiveSystemUpdateTask
 +
|-
 +
| 75 || [4.0.0+] GetLocalCommunicationReceiveSystemUpdateTaskErrorContext
 +
|-
 +
| 76 || [4.0.0+] [[#CreateLocalCommunicationSendSystemUpdateTask]]
 +
|-
 +
| 77 || [4.0.0+] [[#RequestLocalCommunicationSendSystemUpdateTaskRun]]
 +
|-
 +
| 78 || [4.0.0+] [[#GetLocalCommunicationSendSystemUpdateTaskInfo]]
 +
|-
 +
| 79 || [4.0.0+] DestroyLocalCommunicationSendSystemUpdateTask
 +
|-
 +
| 80 || [4.0.0+] GetLocalCommunicationSendSystemUpdateTaskErrorContext
 +
|-
 +
| 81 || [4.0.0+] [[#ListLocalCommunicationSendSystemUpdateTask]]
 +
|-
 +
| 82 || [4.0.0+] GetReceivedSystemDataPath
 +
|-
 +
| 83 || [4.0.0+] CalculateApplyDeltaTaskOccupiedSize
 +
|-
 +
| 84 || [5.0.0+] ReloadErrorSimulation
 +
|-
 +
| 85 || [5.0.0+] ListNetworkInstallTaskContentMetaFromInstallMeta
 +
|-
 +
| 86 || [5.0.0+] ListNetworkInstallTaskOccupiedSize
 +
|-
 +
| 87 || [6.0.0+] RequestQueryAvailableELicenses
 +
|-
 +
| 88 || [6.0.0+] RequestAssignELicenses
 +
|-
 +
| 89 || [6.0.0+] RequestExtendELicenses
 +
|-
 +
| 90 || [6.0.0+] RequestSyncELicenses
 +
|-
 +
| 91 || [6.0.0-14.1.2]
 +
|-
 +
| 92 || [6.0.0+] RequestQueryRevokeReason
 +
|-
 +
| 93 || [6.0.0+] RequestReportActiveELicenses
 +
|-
 +
| 94 || [6.0.0+] RequestReportActiveELicensesPassively
 +
|-
 +
| 95 || [6.0.0+] RequestRegisterDynamicRightsNotificationToken
 +
|-
 +
| 96 || [6.0.0+] RequestAssignAllDeviceLinkedELicenses
 +
|-
 +
| 97 || [6.0.0+] RequestRevokeAllELicenses
 +
|-
 +
| 98 || [6.0.0+] RequestPrefetchForDynamicRights
 +
|-
 +
| 99 || [7.0.0+] CreateNetworkInstallTask
 +
|-
 +
| 100 || [9.0.0+] ListNetworkInstallTaskRightsIds
 +
|-
 +
| 101 || [9.0.0+] RequestDownloadETickets
 +
|-
 +
| 102 || [9.0.0+] RequestQueryDownloadableContents
 +
|-
 +
| 103 || [9.0.0+] DeleteNetworkInstallTaskContentMeta
 +
|-
 +
| 104 || [9.0.0+] RequestIssueEdgeTokenForDebug
 +
|-
 +
| 105 || [9.0.0+] RequestQueryAvailableELicenses2
 +
|-
 +
| 106 || [9.0.0+] RequestAssignELicenses2
 +
|-
 +
| 107 || [10.0.0+] GetNetworkInstallTaskStateCounter
 +
|-
 +
| 108 || [10.0.0+] InvalidateDynamicRightsNaIdTokenCacheForDebug
 +
|-
 +
| 109 || [10.0.0+] ListNetworkInstallTaskPartialInstallContentMeta
 +
|-
 +
| 110 || [10.0.0+] ListNetworkInstallTaskRightsIdsFromIndex
 +
|-
 +
| 111 || [10.0.0+] AddNetworkInstallTaskContentMetaForUser
 +
|-
 +
| 112 || [10.0.0+] RequestAssignELicensesAndDownloadETickets
 +
|-
 +
| 113 || [10.0.0+] RequestQueryAvailableCommonELicenses
 +
|-
 +
| 114 || [10.0.0+] SetNetworkInstallTaskExtendedAttribute
 +
|-
 +
| 115 || [10.0.0+] GetNetworkInstallTaskExtendedAttribute
 +
|-
 +
| 116 || [10.0.0+] GetAllocatorInfo
 +
|-
 +
| 117 || [11.0.0+] RequestQueryDownloadableContentsByApplicationId
 +
|-
 +
| 118 || [10.0.0+] MarkNoDownloadRightsErrorResolved
 +
|-
 +
| 119 || [11.0.0+] GetApplyDeltaTaskAllAppliedContentMeta
 +
|-
 +
| 120 || [11.0.0+] PrioritizeNetworkInstallTask
 +
|-
 +
| 121 || [10.1.0+] RequestQueryAvailableCommonELicenses2
 +
|-
 +
| 122 || [10.1.0+] RequestAssignCommonELicenses
 +
|-
 +
| 123 || [10.1.0+] RequestAssignCommonELicenses2
 +
|-
 +
| 124 || [11.0.0+] IsNetworkInstallTaskFrontOfQueue
 +
|-
 +
| 125 || [11.0.0+] PrioritizeApplyDeltaTask
 +
|-
 +
| 126 || [12.0.0+] RerouteDownloadingPatch
 +
|-
 +
| 127 || [12.0.0+] UnmarkNoDownloadRightsErrorResolved
 +
|-
 +
| 128 || [12.0.0+] RequestContentsSize
 +
|-
 +
| 129 || [12.0.0+] RequestContentsAuthorizationToken
 +
|-
 +
| 130 || [13.0.0+] RequestCdnVendorDiscovery
 +
|-
 +
| 131 || [13.0.0+] RefreshDebugAvailability
 +
|-
 +
| 132 || [13.0.0+] ClearResponseSimulationEntry
 +
|-
 +
| 133 || [13.0.0+] RegisterResponseSimulationEntry
 +
|-
 +
| 134 || [13.0.0+] GetProcessedCdnVendors
 +
|-
 +
| 135 || [14.0.0+] RefreshRuntimeBehaviorsForDebug
 +
|-
 +
| 136 || [14.0.0+] RequestOnlineSubscriptionFreeTrialAvailability
 +
|-
 +
| 137 || [14.0.0+] GetNetworkInstallTaskContentMetaCount
 +
|-
 +
| 138 || [15.0.0+] RequestRevokeELicenses
 +
|-
 +
| 139 || [15.0.0+] EnableNetworkConnectionToUseApplicationCore
 +
|-
 +
| 140 || [15.0.0+] DisableNetworkConnectionToUseApplicationCore
 +
|-
 +
| 141 || [15.0.0+] IsNetworkConnectionEnabledToUseApplicationCore
 +
|-
 +
| 142 || [17.0.0+] RequestCheckSafeSystemVersion
 +
|-
 +
| 143 || [17.0.0+] RequestApplicationIcon
 +
|-
 +
| 144 || [17.0.0+] RequestDownloadIdbeIconFile
 +
|-
 +
| 147 || [18.0.0+]
 +
|-
 +
| 148 || [18.0.0+]
 +
|-
 +
| 150 || [19.0.0+]
 +
|-
 +
| 3000 || [17.0.0+] RequestLatestApplicationIcon
 +
|-
 +
| 3001 || [17.0.0+] RequestDownloadIdbeLatestIconFile
 +
|}
  
=ntc=
+
[5.0.0+] RequestGameCardRegistrationStatus/RequestRegisterGameCard removed 8-bytes of input, and now takes an additional type-0x5 input buffer.
  
Presumably Network Time Sync?
+
[12.0.0+] RequestQueryRevokeReason now returns an [[#IAsyncData]] instead of [[#IAsyncValue]].
  
=Network=
+
== CreateSystemUpdateTask ==
* <nowiki>https://sun.hac.%%.d4c.nintendo.net/v1/system_update_meta?device_id=%016llx</nowiki>
+
Takes an input u32 firmware_variation, an u32 '''unk''', a [[NCM_services#ContentMetaKey|ContentMetaKey]], returns an output [[#SystemUpdateTaskId]].
* <nowiki>https://aqua.hac.%%.d4c.nintendo.net/required_system_update_meta?device_id=%016llx</nowiki>
 
* <nowiki>https://%s.hac.%%.d4c.nintendo.net/t/%c/%016llx/%u?device_id=%016llx</nowiki> Returns content like the below URL. This is the content for [[NCA]]-type0. See below for %c. %016llx is titleID, %u is title-version.
 
* <nowiki>https://%s.hac.%%.d4c.nintendo.net/c/%c/%s</nowiki> Used for downloading content. First %s is atumn or atum. %c is one of: 'c', 'a', or 's'. %s is just the hex-string NcaId. The returned data is the same size readable from [[Content_Manager_services|NCM]], with another crypto layer. The server also returns two HTTP headers: "X-Nintendo-Content-Hash: {entire lowercase hex-string of the content SHA256 hash}" and "X-Nintendo-Content-ID: {lowercase hex-string for NcaId}"
 
* <nowiki>https://superfly.hac.%%.d4c.nintendo.net/v1/t/%016llx/dv</nowiki> %016llx is titleID, only for eShop titles it appears. Returns .json title-info.
 
* <nowiki>https://superfly.hac.%%.d4c.nintendo.net/v1/a/%016llx/dv</nowiki> %016llx is titleID, only for eShop titles it appears. Output is similar to above URL.
 
* <nowiki>https://aauth-%.ndas.srv.nintendo.net/v1/time</nowiki>
 
* ...
 
* <nowiki>"https://dauth-%.ndas.srv.nintendo.net/v1/device_auth_token"</nowiki> CURLOPT_POSTFIELDS is set to the output from: snprintf(..., "system_version=%08x&client_id=%s", <output parsed from a func>, "<hard-coded hex string>");
 
  
These are not accessible without the required TLS client cert+privk, minus the time URL which can be accessed without any client cert+privk at all.
+
Official sw sets '''unk''' to: <code>unk = inflag & 1 ? 0xC : 0x4</code>.
  
While atumn seems to be for system-titles, and atum for eShop titles, the latter titles are accessible fine with atumn(with "/t/" for NCA-type0 at least).
+
== DestroySystemUpdateTask ==
 +
Takes an input [[#SystemUpdateTaskId]], no output.
  
'a' is used when an input u8 is not 0x3, otherwise 's' is used. This is [[Content_Manager_services#Title_Types|title-type]]? A seperate function using the ".../c/" URL is hard-coded to use 'c'. This appears to match 's' usage attempts: the only URL that returned actual data with 's' was with titleID 0100000000000816.
+
== ListSystemUpdateTask ==
 +
Takes a type-0x6 output buffer, for an array of [[#SystemUpdateTaskId]]. Returns a s32 for total output entries.
  
Going by strings in NIM, it appears SOAP isn't used anymore. ecs appears to use REST API?
+
== GetSystemUpdateTaskInfo ==
 +
Takes an input [[#SystemUpdateTaskId]], returns an output [[#SystemUpdateTaskInfo]].
  
== User-Agent ==
+
== CommitSystemUpdateTask ==
NIM generates two User-Agent strings:
+
Takes an input [[#SystemUpdateTaskId]], no output.
  snprintf(..., "User-Agent: NintendoSDK Firmware/%s-%u (platform:%s; did:%016llx; eid:%s)", <string at [[System_Version_Title|sysver]]+0x68>, {u32 from [[System_Version_Title|sysver]]+4}, "NX", DeviceId, {[[NSD_services|NSD]] cmd11 output});
 
  snprintf(..., "User-Agent: NintendoSDK Firmware/%s-%u (platform:%s; eid:%s)", <string at [[System_Version_Title|sysver]]+0x68>, {u32 from [[System_Version_Title|sysver]]+4}, "NX", DeviceId, {[[NSD_services|NSD]] cmd11 output});
 
  
Where the 64bit DeviceId is parsed from the 0x10-bytes at outbuf+0xC6 from [[Settings_services|set:cal]] GetDeviceCert(DeviceCert_certname+2, aka where the hex string for the DeviceId is).
+
== RequestNetworkInstallTaskRun ==
 +
Takes a total of 0x10-bytes of input, returns an output [[#IAsyncResult]] and handle.
  
== sun ==
+
[13.0.0+] Now takes an additional 1-byte of input.
NIM sends a HTTP GET with the sun URL listed above to get the title-listing of the latest system-titles, as .json. The deviceid in the URL is the same one in the above User-Agent section. HTTP header "Accept:application/json" is sent in the request.
 
  
The response is json with a "system_update_metas" block, containing "title_id" and "title_version" entries. The actual server response only contains 1 title.
+
== GetNetworkInstallTaskInfo ==
 +
Takes an input [[#NetworkInstallTaskId]], returns an output [[#NetworkInstallTaskInfo]].
  
Example, from 2.0 system:
+
[10.0.0+] This now returns a total of 0x48-bytes of output instead of 0x40-bytes.
  
<code>{"timestamp":REDACTED-TIMESTSAMP,"system_update_metas":[{"title_id":"0100000000000816","title_version":201327002}]}</code>
+
== GetDownloadedSystemDataPath ==
 +
Takes an input u64 titleID, a [[#SystemUpdateTaskId]], and an type-0x16 output buffer containing the [[Filesystem_services#FspPath|FspPath]].
  
== aqua ==
+
Gets the FS FspPath for the specified task and title.
The following response is json from accessing the above aqua URL:
 
  
<code>{
+
== IsExFatDriverIncluded ==
"contents_delivery_required_title_id": "0100000000000816",
+
Takes an input [[#SystemUpdateTaskId]], returns an output u8 bool flag.
"contents_delivery_required_title_version": 0
+
 
}</code>
+
== GetApplyDeltaTaskInfo ==
 +
Takes an input [[#ApplyDeltaTaskId]], returns an output [[#ApplyDeltaTaskInfo]].
 +
 
 +
== CreateLocalCommunicationReceiveApplicationTask ==
 +
Takes an input [[NCM_services#StorageId|StorageId]], an u16 port, an u32 Ipv4Address, an u32 '''unk''', an u64 <code>nn::ncm::ApplicationId</code>, a type-0x5 input buffer containing an array of [[NCM_services#ContentMetaKey|ContentMetaKey]], returns an output [[#LocalCommunicationReceiveApplicationTaskId]].
 +
 
 +
This is the ReceiveApplication version of [[#CreateLocalCommunicationReceiveSystemUpdateTask]].
 +
 
 +
The wrapper used by official sw passes hard-coded value 0x2 for '''unk'''.
 +
 
 +
== RequestLocalCommunicationReceiveApplicationTaskRun ==
 +
Takes an input [[#LocalCommunicationReceiveApplicationTaskId]], returns an output Event and an [[#IAsyncResult]].
 +
 
 +
This is the ReceiveApplication version of [[#RequestLocalCommunicationReceiveSystemUpdateTaskRun]].
 +
 
 +
== GetLocalCommunicationReceiveApplicationTaskInfo ==
 +
Takes an input [[#LocalCommunicationReceiveApplicationTaskId]], returns an output [[#LocalCommunicationReceiveApplicationTaskInfo]].
 +
 
 +
This is the ReceiveApplication version of [[#GetSystemUpdateTaskInfo]].
 +
 
 +
== CreateLocalCommunicationSendApplicationTask ==
 +
Takes an input u16 port, an u32 Ipv4Address, an u64 <code>nn::ncm::ApplicationId</code>, a type-0x5 input buffer containing an array of {unknown}, returns an output [[#LocalCommunicationSendApplicationTaskId]].
 +
 
 +
This is the SendApplication version of [[#CreateLocalCommunicationReceiveSystemUpdateTask]].
 +
 
 +
== RequestLocalCommunicationSendApplicationTaskRun ==
 +
Takes an input [[#LocalCommunicationSendApplicationTaskId]], returns an output Event and an [[#IAsyncResult]].
 +
 
 +
This is the SendApplicationTask version of [[#RequestLocalCommunicationReceiveSystemUpdateTaskRun]].
 +
 
 +
== GetLocalCommunicationSendApplicationTaskInfo ==
 +
Takes an input [[#LocalCommunicationSendApplicationTaskId]], returns an output [[#LocalCommunicationSendApplicationTaskInfo]].
 +
 
 +
This is the SendApplication version of [[#GetSystemUpdateTaskInfo]].
 +
 
 +
== ListApplicationLocalCommunicationReceiveApplicationTask ==
 +
Takes a type-0x6 output buffer containing an array of [[#LocalCommunicationReceiveApplicationTaskId]] and an input u64 <code>nn::ncm::ApplicationId</code>. Returns a s32 for total output entries.
 +
 
 +
This is the ReceiveApplication version of [[#ListLocalCommunicationReceiveSystemUpdateTask]].
 +
 
 +
== ListApplicationLocalCommunicationSendApplicationTask ==
 +
Takes a type-0x6 output buffer containing an array of [[#LocalCommunicationSendApplicationTaskId]] and an input u64 <code>nn::ncm::ApplicationId</code>. Returns a s32 for total output entries.
 +
 
 +
This is the SendApplication version of [[#ListLocalCommunicationReceiveSystemUpdateTask]].
 +
 
 +
== CreateLocalCommunicationReceiveSystemUpdateTask ==
 +
Takes an input u16 port, an u32 Ipv4Address, an u32 firmware_variation, an u32 '''unk''', a [[NCM_services#ContentMetaKey|ContentMetaKey]], returns an output [[#LocalCommunicationReceiveSystemUpdateTaskId]].
 +
 
 +
Official sw sets '''unk''' to: <code>unk = stateflag==0 ? 0x4 : 0xC</code>. The port/Ipv4Address params originate from the [[NS_Services#RequestReceiveSystemUpdate|RequestReceiveSystemUpdate]] params.
 +
 
 +
This is the ReceiveSystemUpdate version of [[#CreateSystemUpdateTask]].
 +
 
 +
The ContentMetaKey is for the SystemUpdate Meta.
 +
 
 +
This does state setup, copies ContentMetaKey/firmware_variation/unk into state + more setup, and does socket setup.
 +
 
 +
[[Sockets_services|Socket]] setup (standard names are used here, instead of the actual Nintendo func/param names):
 +
* Sets the output sockfd in state to -1 (unrelated to "sockfd" below).
 +
* Clears the sockaddr_in.
 +
* sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); {handle error on fail}
 +
* Initializes sockaddr_in: sin_addr = htonl({input ipaddr}), sin_port = htons({input port}), and sin_family = AF_INET (sin_len is left at 0).
 +
* Uses fcntl with F_GETFL/F_SETFL to set O_NONBLOCK, handling error on fail.
 +
* connect(sockfd, sockaddr_in, sizeof(sockaddr_in));
 +
** On failure:
 +
** When the error is EINPROGRESS:
 +
*** Uses select() with input setup for {content of writefds = sockfd}, and timeval setup for a 5-second timeout.
 +
*** When the ret is 0, returns an error since a timeout occured. When the ret is not negative, proceeds to the below setsockopt handling. When negative, run the below error handling.
 +
** Does error handling and returns.
 +
* u64 tmpval=1; setsockopt(sockfd, SOL_SOCKET, SO_VENDOR + 0x1, &tmpval, sizeof(tmpval)); {handle error on fail}
 +
* Uses fcntl with F_GETFL/F_SETFL to clear O_NONBLOCK, handling error on fail.
 +
* Writes sockfd to the output sockfd state field, then returns 0.
 +
* All error handling following successful sockfd creation via socket() will also close the socket, when certain errors occur.
 +
 
 +
== ListLocalCommunicationReceiveSystemUpdateTask ==
 +
Takes a type-0x6 output buffer, for an array of [[#LocalCommunicationReceiveSystemUpdateTaskId]]. Returns a s32 for total output entries.
 +
 
 +
This is the ReceiveSystemUpdate version of [[#ListSystemUpdateTask]].
 +
 
 +
== RequestLocalCommunicationReceiveSystemUpdateTaskRun ==
 +
Takes an input [[#LocalCommunicationReceiveSystemUpdateTaskId]], returns an output Event and an [[#IAsyncResult]].
 +
 
 +
This is the ReceiveSystemUpdate version of RequestSystemUpdateTaskRun.
 +
 
 +
This creates the [[#IAsyncResult]] object + the async [[#Contents_Delivery|thread]] which handles the [[#IAsyncResult]] operation, which uses the state previously setup by [[#CreateLocalCommunicationReceiveSystemUpdateTask]]. This throws an error if the object was already created.
 +
 
 +
== GetLocalCommunicationReceiveSystemUpdateTaskInfo ==
 +
Takes an input [[#LocalCommunicationReceiveSystemUpdateTaskId]], returns an output [[#LocalCommunicationReceiveSystemUpdateTaskInfo]].
 +
 
 +
This is the ReceiveSystemUpdate version of [[#GetSystemUpdateTaskInfo]].
 +
 
 +
== CreateLocalCommunicationSendSystemUpdateTask ==
 +
Takes an input u16 port, an u32 Ipv4Address, an u32 firmware_variation, and a [[NCM_services#ContentMetaKey|ContentMetaKey]], returns an output [[#LocalCommunicationSendSystemUpdateTaskId]].
 +
 
 +
[8.0.0+] This now takes an additional 0x8-bytes of input.
 +
 
 +
The port/Ipv4Address params originate from the [[NS_Services#RequestSendSystemUpdate|RequestSendSystemUpdate]] params.
 +
 
 +
The ContentMetaKey is for the SystemUpdate Meta ([[NCM_services#ContentMetaType|ContentMetaType]] must match SystemUpdate).
 +
 
 +
This is the Send version of [[#CreateLocalCommunicationReceiveSystemUpdateTask]].
 +
 
 +
This does state setup, does the above ContentMetaType validation, copies ContentMetaKey/firmware_variation into state, and does socket setup.
 +
 
 +
[[Sockets_services|Socket]] setup (standard names are used here, instead of the actual Nintendo func/param names):
 +
* Sets the output sockfds in state to -1 (unrelated to "sockfd" below).
 +
* Clears the sockaddr_in.
 +
* sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); {handle error on fail}
 +
* Uses fcntl with F_GETFL/F_SETFL to set O_NONBLOCK, handling error on fail.
 +
* u64 tmpval=1; setsockopt(sockfd, SOL_SOCKET, SO_VENDOR + 0x1, &tmpval, sizeof(tmpval)); {handle error on fail}
 +
* u32 tmpval2=1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &tmpval2, sizeof(tmpval2)); {handle error on fail}
 +
* Initializes sockaddr_in: sin_addr = htonl({input ipaddr}), sin_port = htons({input port}), and sin_family = AF_INET (sin_len is left at 0).
 +
* bind(sockfd, sockaddr_in, sizeof(sockaddr_in)); {handle error on fail}
 +
* listen(sockfd, 1); {handle error on fail}
 +
* Writes sockfd to the output sockfd state field, copies the input ipaddr u32 into state, then returns 0.
 +
* The error handling for bind()/listen() will also close the socket, when certain errors occur.
 +
 
 +
== RequestLocalCommunicationSendSystemUpdateTaskRun ==
 +
Takes an input [[#LocalCommunicationSendSystemUpdateTaskId]], returns an output Event and an [[#IAsyncResult]].
 +
 
 +
This is the Send version of [[#RequestLocalCommunicationReceiveSystemUpdateTaskRun]].
 +
 
 +
This creates the [[#IAsyncResult]] object + the async [[#Contents_Delivery|thread]] which handles the [[#IAsyncResult]] operation, which uses the state previously setup by [[#CreateLocalCommunicationSendSystemUpdateTask]]. This throws an error if the object was already created.
 +
 
 +
== GetLocalCommunicationSendSystemUpdateTaskInfo ==
 +
Takes an input [[#LocalCommunicationSendSystemUpdateTaskId]], returns an output [[#LocalCommunicationSendSystemUpdateTaskInfo]].
 +
 
 +
This is the Send version of [[#GetLocalCommunicationReceiveSystemUpdateTaskInfo]].
 +
 
 +
== ListLocalCommunicationSendSystemUpdateTask ==
 +
Takes a type-0x6 output buffer, for an array of [[#LocalCommunicationSendSystemUpdateTaskId]]. Returns a s32 for total output entries.
 +
 
 +
This is the Send version of [[#ListLocalCommunicationReceiveSystemUpdateTask]].
 +
 
 +
= nim:shp =
 +
This is "nn::nim::detail::IShopServiceManager".
 +
 
 +
This is only available when [[Process_Manager_services|pm:bm]] GetBootMode returns output 0 (Normal).
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || RequestDeviceAuthenticationToken
 +
|-
 +
| 1 || [3.0.0+] RequestCachedDeviceAuthenticationToken
 +
|-
 +
| 2 || [10.0.0+] RequestEdgeToken
 +
|-
 +
| 3 || [10.0.0+] RequestCachedEdgeToken
 +
|-
 +
| 100 || RequestRegisterDeviceAccount
 +
|-
 +
| 101 || RequestUnregisterDeviceAccount
 +
|-
 +
| 102 || [1.0.0-14.1.2] RequestDeviceAccountStatus
 +
|-
 +
| 103 || [1.0.0-14.1.2] GetDeviceAccountInfo
 +
|-
 +
| 104 || [1.0.0-14.1.2] RequestDeviceRegistrationInfo
 +
|-
 +
| 105 || [1.0.0-14.1.2] RequestTransferDeviceAccount
 +
|-
 +
| 106 || [3.0.0-14.1.2] RequestSyncRegistration
 +
|-
 +
| 107 || [3.0.0+] IsOwnDeviceId
 +
|-
 +
| 108 || [14.0.0+] RevertSystemSaveDataOfDeviceAccountForDebug
 +
|-
 +
| 200 || RequestRegisterNotificationToken
 +
|-
 +
| 300 || RequestUnlinkDevice
 +
|-
 +
| 301 || RequestUnlinkDeviceIntegrated
 +
|-
 +
| 302 || RequestLinkDevice
 +
|-
 +
| 303 || [1.0.0-13.2.1] HasDeviceLink
 +
|-
 +
| 304 || [4.0.0+] RequestUnlinkDeviceAll
 +
|-
 +
| 305 || [4.0.0-13.2.1] RequestCreateVirtualAccount
 +
|-
 +
| 306 || [4.0.0+] RequestDeviceLinkStatus
 +
|-
 +
| 400 || [1.0.0-13.2.1] GetAccountByVirtualAccount
 +
|-
 +
| 401 || [6.0.0-13.2.1] GetVirtualAccount
 +
|-
 +
| 500 || RequestSyncTicketLegacy ([1.0.0-8.1.0] RequestSyncTicket)
 +
|-
 +
| 501 || [1.0.0-14.1.2] RequestDownloadTicket
 +
|-
 +
| 502 || [4.0.0+] [[#RequestDownloadTicketForPrepurchasedContents]]
 +
|-
 +
| 503 || [9.0.0+] RequestSyncTicket
 +
|-
 +
| 504 || [9.0.0+] RequestDownloadTicketForPrepurchasedContents2
 +
|-
 +
| 505 || [13.1.0+] RequestDownloadTicketForPrepurchasedContentsForAccount
 +
|-
 +
| 600 || [14.0.0+] IsInitialLaunchFinished
 +
|-
 +
| 601 || [14.0.0+] NotifyFinishInitialLaunch
 +
|}
 +
 
 +
== RequestDownloadTicketForPrepurchasedContents ==
 +
[6.0.0+] Now takes an additional 4-bytes of input.
 +
 
 +
= nim:eca =
 +
This is "nn::nim::detail::IShopServiceAccessServerInterface".
 +
 
 +
This was added with [5.0.0+].
 +
 
 +
This is only available when [[Process_Manager_services|pm:bm]] GetBootMode returns output 0 (Normal).
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || CreateServerInterface
 +
|-
 +
| 1 || [6.0.0+] RefreshDebugAvailability
 +
|-
 +
| 2 || [6.0.0+] ClearDebugResponse
 +
|-
 +
| 3 || [6.0.0+] RegisterDebugResponse
 +
|-
 +
| 4 || [10.0.0+] IsLargeResourceAvailable
 +
|-
 +
| 5 || [17.0.0+] CreateServerInterface2
 +
|}
 +
 
 +
== IShopServiceAccessServer ==
 +
This is "nn::nim::detail::IShopServiceAccessServer".
 +
 
 +
This was added with [5.0.0+].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || CreateAccessorInterface
 +
|}
 +
 
 +
=== IShopServiceAccessor ===
 +
This is "nn::nim::detail::IShopServiceAccessor".
 +
 
 +
This was added with [5.0.0+].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || CreateAsyncInterface
 +
|}
 +
 
 +
==== IShopServiceAsync ====
 +
This is "nn::nim::detail::IShopServiceAsync".
 +
 
 +
This was added with [5.0.0+].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || Cancel
 +
|-
 +
| 1 || GetSize
 +
|-
 +
| 2 || Read
 +
|-
 +
| 3 || GetErrorCode
 +
|-
 +
| 4 || Request
 +
|-
 +
| 5 || Prepare
 +
|}
 +
 
 +
= nim:ecas =
 +
This is "nn::nim::detail::IShopServiceAccessSystemInterface".
 +
 
 +
This was added with [7.0.0+].
 +
 
 +
This is only available when [[Process_Manager_services|pm:bm]] GetBootMode returns output 0 (Normal).
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || RegisterSpecialClient
 +
|-
 +
| 1 || UnregisterSpecialClient
 +
|}
 +
 
 +
= ntc =
 +
This is "nn::ntc::detail::service::IStaticService".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || OpenEnsureNetworkClockAvailabilityService
 +
|-
 +
| 100 || [3.0.0+] SuspendAutonomicTimeCorrection
 +
|-
 +
| 101 || [3.0.0+] ResumeAutonomicTimeCorrection
 +
|}
 +
 
 +
Network-time-sync uses the "<...>/time" HTTPS URL listed in the below Network section. This just returns an UTC Unix time string.
 +
 
 +
== IEnsureNetworkClockAvailabilityService ==
 +
This is "nn::ntc::detail::service::IEnsureNetworkClockAvailabilityService".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || StartTask
 +
|-
 +
| 1 || GetFinishNotificationEvent
 +
|-
 +
| 2 || GetResult
 +
|-
 +
| 3 || Cancel
 +
|-
 +
| 4 || IsProcessing
 +
|-
 +
| 5 || [3.0.0+] GetServerTime
 +
|}
 +
 
 +
= SystemUpdateTaskId =
 +
This is "nn::nim::SystemUpdateTaskId". This is an 0x10 byte struct containing an nn::util::Uuid.
 +
 
 +
= SystemUpdateTaskInfo =
 +
This is "nn::nim::SystemUpdateTaskInfo". This is a 0x28-byte struct.
 +
 
 +
[3.0.0+] This is a 0x38-byte struct.
 +
 
 +
[5.0.0+] This is a 0x40-byte struct.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x1 || InstallProgressState
 +
|-
 +
| 0x4 || 0x4 || LastResult
 +
|-
 +
| 0x8 || 0x8 || InstalledSize
 +
|-
 +
| 0x10 || 0x8 || TotalSize
 +
|-
 +
| 0x18 || 0x8 || [[NCM_services#ContentMetaKey|ContentMetaKey]]
 +
|-
 +
| 0x28 || 0x8 || BytesInstalled
 +
|-
 +
| 0x30 || 0x8 || ElapsedTimeNs
 +
|-
 +
| 0x38 || 0x1 || SystemUpdateTaskApplyInfo
 +
|}
 +
 
 +
The first 0x18-bytes are obtained from [[NCM_services#GetProgress]] and the 0x10-bytes at +0x8 are returned by [[NS_Services#GetDownloadProgress]].
 +
 
 +
The two u64s at +0x28/+0x30 are obtained from [[NCM_services#GetThroughput]] and used by [[NS_Services|NS]] to calculate "ThroughputKBps" for a SystemPlayReport.
 +
 
 +
The byte at +0x38 is obtained from [[NCM_services#GetSystemUpdateTaskApplyInfo]].
 +
 
 +
= NetworkInstallTaskId =
 +
This is "nn::nim::NetworkInstallTaskId". This is a 0x10-byte struct.
 +
 
 +
= NetworkInstallTaskInfo =
 +
This is "nn::nim::NetworkInstallTaskInfo". This is a 0x28-byte struct.
 +
 
 +
[3.0.0+] This is a 0x40-byte struct.
 +
 
 +
= ApplyDeltaTaskId =
 +
This is "nn::nim::ApplyDeltaTaskId". This is a 0x10-byte struct.
 +
 
 +
= ApplyDeltaTaskInfo =
 +
This is "nn::nim::ApplyDeltaTaskInfo". This is a 0x20-byte struct.
 +
 
 +
[3.0.0+] This is a 0x30-byte struct.
 +
 
 +
= ReceiveSystemUpdateTask =
 +
This is "nn::nim::LocalCommunicationReceiveSystemUpdateTaskId". This is a 0x10-byte struct.
 +
 
 +
= ReceiveSystemUpdateTaskInfo =
 +
This is "nn::nim::LocalCommunicationReceiveSystemUpdateTaskInfo". This is a 0x38-byte struct.
 +
 
 +
= SendSystemUpdateTask =
 +
This is "nn::nim::LocalCommunicationSendSystemUpdateTaskId". This is a 0x10-byte struct.
 +
 
 +
= SendSystemUpdateTaskInfo =
 +
This is "nn::nim::LocalCommunicationSendSystemUpdateTaskInfo". This is a 0x20-byte struct.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x1 || Status
 +
|-
 +
| 0x1 || 0x7 || ?
 +
|-
 +
| 0x8 || 0x10 || [[NS_Services#SystemUpdateProgress|SystemUpdateProgress]]
 +
|-
 +
| 0x18 || 0x1 || Unknown
 +
|-
 +
| 0x19 || 0x7 || Padding
 +
|}
 +
 
 +
= LocalCommunicationReceiveApplicationTaskId =
 +
This is "nn::nim::LocalCommunicationReceiveApplicationTaskId". This is a 0x10-byte struct.
 +
 
 +
= LocalCommunicationReceiveApplicationTaskInfo =
 +
This is "nn::nim::LocalCommunicationReceiveApplicationTaskInfo". This is a 0x38-byte struct.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x1 || Status
 +
|-
 +
| 0x1 || 0x7 || ?
 +
|-
 +
| 0x8 || 0x10 || [[NS_Services#ReceiveApplicationProgress|ReceiveApplicationProgress]]
 +
|-
 +
| 0x18 || 0x20 || Unknown
 +
|}
 +
 
 +
= LocalCommunicationSendApplicationTaskId =
 +
This is "nn::nim::LocalCommunicationSendApplicationTaskId". This is a 0x10-byte struct.
 +
 
 +
= LocalCommunicationSendApplicationTaskInfo =
 +
This is "nn::nim::LocalCommunicationSendApplicationTaskInfo". This is a 0x20-byte struct.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x1 || Status
 +
|-
 +
| 0x1 || 0x7 || ?
 +
|-
 +
| 0x8 || 0x10 || [[NS_Services#SendApplicationProgress|SendApplicationProgress]]
 +
|-
 +
| 0x18 || 0x8 || Unknown
 +
|}
 +
 
 +
= IAsyncValue =
 +
This is "nn::nim::detail::IAsyncValue".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || GetSize
 +
|-
 +
| 1 || Get
 +
|-
 +
| 2 || Cancel
 +
|-
 +
| 3 || [4.0.0+] GetErrorContext
 +
|}
 +
 
 +
= IAsyncResult =
 +
This is "nn::nim::detail::IAsyncResult".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || Get
 +
|-
 +
| 1 || Cancel
 +
|-
 +
| 2 || [4.0.0+] GetErrorContext
 +
|}
 +
 
 +
= IAsyncProgressResult =
 +
This is "nn::nim::detail::IAsyncProgressResult".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || Get
 +
|-
 +
| 1 || Cancel
 +
|-
 +
| 2 || GetProgress
 +
|-
 +
| 3 || [4.0.0+] GetErrorContext
 +
|}
 +
 
 +
= IAsyncData =
 +
This is "nn::nim::detail::IAsyncData".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || Get
 +
|-
 +
| 1 || Cancel
 +
|-
 +
| 2 || GetSize
 +
|-
 +
| 3 || Read
 +
|-
 +
| 4 || GetETag
 +
|-
 +
| 5 || [4.0.0+] GetErrorContext
 +
|}
 +
 
 +
= Notes =
 +
nnMain calls two funcs only when when [[Process_Manager_services|pm:bm]] GetBootMode output is 0 or 1 (Normal/Maintenance), which are: [[ETicket_services|es]] service init, and [[Account_services|acc:e:u1]] service init.
 +
 
 +
nnMain only handles [[PSC_services|ovln:snd]] initialization/deinit when the output from [[Process_Manager_services|pm:bm]] GetBootMode is 0 (Normal).
 +
 
 +
When initializing [[SSL_services|ssl]], when the input flag is 0 it uses SslVersion = {ApiVersion | Auto}, while when flag is set it uses {ApiVersion | <each flag bit for TLS 1.0-1.2>}. The input flag is set when [[Process_Manager_services|pm:bm]] GetBootMode output is 1 or 2 (Maintenance/SafeMode), otherwise it's 0.
 +
 
 +
nnMain calls a savedata init func with an input flag determined with the output from [[Process_Manager_services|pm:bm]] GetBootMode. flag=0 for BootMode Normal, flag=1 for BootMode non-Normal. When flag is set, it deletes the savedata for savedata [[Flash_Filesystem|nim_sys]], returning the error on failure. Regardless of flag, it then calls a func which handles mounting savedata nim_sys (and creating it if needed). After checking error and calling another func (with error check), if flag is clear it proceeds with handling other savedata etc, otherwise it calls a func (also called with flag=0 once finished) then returns.
 +
 
 +
Various hosted services require BootMode Normal, see above.
 +
 
 +
== Contents Delivery ==
 +
Content can be transferred with a custom protocol over the network. This is intended for use with local [[LDN_services|ldn]] networks, however the used IP addresses can be arbitrary. This can be used for SystemUpdates via the above Send/Receive commands (which are then used via [[NS_Services#ns:su|ns:su]]). Application Patch content can also be transferred with this.
 +
 
 +
See [[#CreateLocalCommunicationReceiveSystemUpdateTask]]/[[#CreateLocalCommunicationSendSystemUpdateTask]] for the socket setup during Receive/Send task creation. Receive system = client, while Send system = server.
 +
 
 +
The Receive async [[#RequestLocalCommunicationReceiveSystemUpdateTaskRun|thread]] does the following:
 +
* Sets the <code>nn::fs::PriorityRaw</code> using a value loaded from state.
 +
* Calls a func, and writes the returned Result into state.
 +
* Signals the async Event and returns.
 +
** That func does:
 +
** This handles installation, with messages being used via vtable funcptrs.
 +
 
 +
The Send async [[#RequestLocalCommunicationSendSystemUpdateTaskRun|thread]] does the following (the SendApplication [[#RequestLocalCommunicationSendApplicationTaskRun|thread]] is identical except it uses different previously setup state):
 +
* This is identical to the Receive thread except the called func is different.
 +
** That func does:
 +
** Gets [[System_Settings|system-setting]] <code>nim.errorsimulate!error_localcommunication_result</code>, returning that as an error if set + non-zero.
 +
** Does socket setup:
 +
** Calls a func.
 +
** When any of the above fail (including the system-setting), the Result is written into state, then the Result is returned.
 +
** Lastly this returns 0.
 +
*** The above func does:
 +
*** This repeatedly receives requests, processes them, and sends the replies. This loop (and func) will only exit when an error occurs, or when request ID 0x0 is used (the latter causes the func to return 0).
 +
*** This handles the requests as required by the ID, no particular order is required by the server.
 +
*** All IDs in the below table are implemented by the server, for both SystemUpdate and Application.
 +
*** An error is thrown if the ID is unrecognized.
 +
 
 +
The above socket setup for the Send async thread does the following:
 +
* Clears sockaddr_in and sets addrlen to 0x10.
 +
* Enters a loop which repeatedly calls a func. If that func fails, this will immediately return.
 +
* Within that loop the following is done:
 +
** sockfd = accept(listen_sockfd, &sockaddr_in, &addrlen); {handle error on fail - listen_sockfd is the saved sockfd from [[#CreateLocalCommunicationSendSystemUpdateTask]]}
 +
** Exits the loop when the ipaddr within sockaddr_in matches the saved ipaddr in state from [[#CreateLocalCommunicationSendSystemUpdateTask]] (originally from the cmd input param). Otherwise, close sockfd and continue the loop (with the above func being called again).
 +
* The following is done after the loop:
 +
* u64 tmpval=1; setsockopt(sockfd, SOL_SOCKET, SO_VENDOR + 0x1, &tmpval, sizeof(tmpval)); {handle error on fail}
 +
* Uses [[Network_Interface_services|nifm]] GetInternetConnectionStatus, returning an error if this is successful. Hence, the output from this is ignored.
 +
* Uses fcntl with F_GETFL/F_SETFL to clear O_NONBLOCK with sockfd, handling error on fail.
 +
* u32 tmpval2=0x4000;
 +
* u32 tmpval3=0x20000;
 +
* setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &tmpval2, sizeof(tmpval2)); {error is ignored}
 +
* setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &tmpval3, sizeof(tmpval3)); {error is ignored}
 +
* Writes sockfd to the output state sockfd and returns 0.
 +
** The func used with the above loop does the following:
 +
** Uses select() with input setup for {content of readfds = sockfd}, and timeval setup for a 1-second timeout. This is used repeatedly, until this returns an error (in which case error handling is done) or returns non-zero.
 +
** Then this returns 0.
 +
 
 +
Messages (requests/replies) begin with the following 0x10-byte header, then any associated data.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x4 || u32 magicnum. Must match 0x7152444c (request messages from the Receive system) or 0x7352444c (reply messages from the Send system). Code validating the magicnum always checks both magicnums, not an individual one.
 +
|-
 +
| 0x4 || 0x1 || u8 ID. The reply ID must match the request ID.
 +
|-
 +
| 0x5 || 0x1 || Padding
 +
|-
 +
| 0x6 || 0x2 || u16 meta_size. Must be <=0x1000.
 +
|-
 +
| 0x8 || 0x8 || s64 data_size. Must not be negative. During message-specific handling with request/reply this must also match the expected value (except for ID 0x0 which is ignored in this case).
 +
|}
 +
 
 +
After the header is the associated data for meta_size and data_size. The functions which generate the header always leave meta_size at value 0, when receiving the data for meta_size the received data is unused.
 +
 
 +
The first message used by the client with SystemUpdate is ID 0x1.
 +
 
 +
With SystemUpdate the server only uses StorageId=BuiltInSystem.
 +
 
 +
Messages:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! ID || Request data_size / data || Reply data_size / data || Description
 +
|-
 +
| 0x0 || 0x0 || 0x0 || Tells the server to exit. When handling this the handler func will immediately return 0, without sending a reply.
 +
|-
 +
| 0x1 || [[NCM_services#ContentMetaKey|ContentMetaKey]] || [[CNMT#Content_Records|PackagedContentInfo]] || Gets the PackagedContentInfo with type==Meta for the specified ContentMetaKey. The SystemUpdate client uses the ContentMetaKey from [[#CreateLocalCommunicationReceiveSystemUpdateTask]].
 +
|-
 +
| 0x2 || 0x18-bytes: [[NCM_services#ContentId|ContentId]], u8 flag, u8 pad[7]. When flag is 0, during the transfer [[#LocalCommunicationSendSystemUpdateTaskInfo]] [[NS_Services#SystemUpdateProgress|SystemUpdateProgress]] current_size is increased using the size of the current chunk. Once the transfer is finished, the end result is that it would be increased by the total content-size. The only time the nim client sets this flag to 1 with SystemUpdate is with the SystemUpdate Meta content. || Size from [[NCM_services#GetSizeFromContentId|GetSizeFromContentId]] with data from [[NCM_services#ReadContentIdFile|ReadContentIdFile]]. || Gets the entire content data for the specified ContentId. The client uses each received chunk of data during the transfer with [[NCM_services|WritePlaceHolder]].
 +
|-
 +
| 0x3 || 0x10-byte input for [[ETicket_services|es]] GetCommonTicketAndCertificateSize/GetCommonTicketAndCertificateData. || 0x8-bytes: two size u32s. Then two blocks of data with the sizes specified by the u32s. The server loads the sizes and data from [[ETicket_services|es]] GetCommonTicketAndCertificateSize/GetCommonTicketAndCertificateData. || The two blocks of data are used as the buffers for [[ETicket_services|es]] ImportTicket by the client. This is used for transferring the specified Application Patch CommonTicket.
 +
|-
 +
| 0x4 || s64 total_size || 0x0 || The input data is copied into the server state, for [[#LocalCommunicationSendSystemUpdateTaskInfo]] [[NS_Services#SystemUpdateProgress|SystemUpdateProgress]] total_size.
 +
|}
 +
 
 +
[[Category:Services]]

Latest revision as of 22:19, 19 November 2024

nim

This is "nn::nim::detail::INetworkInstallManager".

Cmd Name
0 #CreateSystemUpdateTask
1 #DestroySystemUpdateTask
2 #ListSystemUpdateTask
3 RequestSystemUpdateTaskRun
4 #GetSystemUpdateTaskInfo
5 #CommitSystemUpdateTask
6 CreateNetworkInstallTaskDeprecated
7 DestroyNetworkInstallTask
8 ListNetworkInstallTask
9 #RequestNetworkInstallTaskRun
10 #GetNetworkInstallTaskInfo
11 CommitNetworkInstallTask
12 RequestLatestSystemUpdateMeta
14 ListApplicationNetworkInstallTask
15 ListNetworkInstallTaskContentMeta
16 RequestLatestVersion
17 SetNetworkInstallTaskAttribute
18 AddNetworkInstallTaskContentMeta
19 #GetDownloadedSystemDataPath
20 CalculateNetworkInstallTaskRequiredSize
21 #IsExFatDriverIncluded
22 GetBackgroundDownloadStressTaskInfo
23 [2.0.0+] RequestDeviceAuthenticationToken
24 [2.0.0+] RequestGameCardRegistrationStatus
25 [2.0.0+] RequestRegisterGameCard
26 [2.0.0+] RequestRegisterNotificationToken
27 [2.0.0+] RequestDownloadTaskList
28 [2.0.0+] RequestApplicationControl
29 [2.0.0+] RequestLatestApplicationControl
30 [2.0.0+] RequestVersionList
31 [2.0.0+] CreateApplyDeltaTask
32 [2.0.0+] DestroyApplyDeltaTask
33 [2.0.0+] ListApplicationApplyDeltaTask
34 [2.0.0+] RequestApplyDeltaTaskRun
35 [2.0.0+] #GetApplyDeltaTaskInfo
36 [2.0.0+] ListApplyDeltaTaskContentMeta
37 [2.0.0+] CommitApplyDeltaTask
38 [2.0.0+] CalculateApplyDeltaTaskRequiredSize
39 [2.0.0+] PrepareShutdown
40 [2.0.0+] ListApplyDeltaTask
41 [2.0.0+] ClearNotEnoughSpaceStateOfApplyDeltaTask
42 [3.0.0+] CreateApplyDeltaTaskFromDownloadTask
43 [3.0.0+] GetBackgroundApplyDeltaStressTaskInfo
44 [3.0.0+] GetApplyDeltaTaskRequiredStorage
45 [3.0.0+] CalculateNetworkInstallTaskContentsSize
46 [3.0.0+] PrepareShutdownForSystemUpdate
47 [4.0.0-9.2.0] FindMaxRequiredApplicationVersionOfTask
48 [4.0.0+] CommitNetworkInstallTaskPartially
49 [4.0.0+] ListNetworkInstallTaskCommittedContentMeta
50 [4.0.0+] ListNetworkInstallTaskNotCommittedContentMeta
51 [4.0.0+] FindMaxRequiredSystemVersionOfTask
52 [4.0.0+] GetNetworkInstallTaskErrorContext
53 [4.0.0+] #CreateLocalCommunicationReceiveApplicationTask
54 [4.0.0+] DestroyLocalCommunicationReceiveApplicationTask
55 [4.0.0+] ListLocalCommunicationReceiveApplicationTask
56 [4.0.0+] #RequestLocalCommunicationReceiveApplicationTaskRun
57 [4.0.0+] #GetLocalCommunicationReceiveApplicationTaskInfo
58 [4.0.0+] CommitLocalCommunicationReceiveApplicationTask
59 [4.0.0+] ListLocalCommunicationReceiveApplicationTaskContentMeta
60 [4.0.0+] #CreateLocalCommunicationSendApplicationTask
61 [4.0.0+] #RequestLocalCommunicationSendApplicationTaskRun
62 [4.0.0+] GetLocalCommunicationReceiveApplicationTaskErrorContext
63 [4.0.0+] #GetLocalCommunicationSendApplicationTaskInfo
64 [4.0.0+] DestroyLocalCommunicationSendApplicationTask
65 [4.0.0+] GetLocalCommunicationSendApplicationTaskErrorContext
66 [4.0.0+] CalculateLocalCommunicationReceiveApplicationTaskRequiredSize
67 [4.0.0+] #ListApplicationLocalCommunicationReceiveApplicationTask
68 [4.0.0+] #ListApplicationLocalCommunicationSendApplicationTask
69 [4.0.0+] #CreateLocalCommunicationReceiveSystemUpdateTask
70 [4.0.0+] DestroyLocalCommunicationReceiveSystemUpdateTask
71 [4.0.0+] #ListLocalCommunicationReceiveSystemUpdateTask
72 [4.0.0+] #RequestLocalCommunicationReceiveSystemUpdateTaskRun
73 [4.0.0+] #GetLocalCommunicationReceiveSystemUpdateTaskInfo
74 [4.0.0+] CommitLocalCommunicationReceiveSystemUpdateTask
75 [4.0.0+] GetLocalCommunicationReceiveSystemUpdateTaskErrorContext
76 [4.0.0+] #CreateLocalCommunicationSendSystemUpdateTask
77 [4.0.0+] #RequestLocalCommunicationSendSystemUpdateTaskRun
78 [4.0.0+] #GetLocalCommunicationSendSystemUpdateTaskInfo
79 [4.0.0+] DestroyLocalCommunicationSendSystemUpdateTask
80 [4.0.0+] GetLocalCommunicationSendSystemUpdateTaskErrorContext
81 [4.0.0+] #ListLocalCommunicationSendSystemUpdateTask
82 [4.0.0+] GetReceivedSystemDataPath
83 [4.0.0+] CalculateApplyDeltaTaskOccupiedSize
84 [5.0.0+] ReloadErrorSimulation
85 [5.0.0+] ListNetworkInstallTaskContentMetaFromInstallMeta
86 [5.0.0+] ListNetworkInstallTaskOccupiedSize
87 [6.0.0+] RequestQueryAvailableELicenses
88 [6.0.0+] RequestAssignELicenses
89 [6.0.0+] RequestExtendELicenses
90 [6.0.0+] RequestSyncELicenses
91 [6.0.0-14.1.2]
92 [6.0.0+] RequestQueryRevokeReason
93 [6.0.0+] RequestReportActiveELicenses
94 [6.0.0+] RequestReportActiveELicensesPassively
95 [6.0.0+] RequestRegisterDynamicRightsNotificationToken
96 [6.0.0+] RequestAssignAllDeviceLinkedELicenses
97 [6.0.0+] RequestRevokeAllELicenses
98 [6.0.0+] RequestPrefetchForDynamicRights
99 [7.0.0+] CreateNetworkInstallTask
100 [9.0.0+] ListNetworkInstallTaskRightsIds
101 [9.0.0+] RequestDownloadETickets
102 [9.0.0+] RequestQueryDownloadableContents
103 [9.0.0+] DeleteNetworkInstallTaskContentMeta
104 [9.0.0+] RequestIssueEdgeTokenForDebug
105 [9.0.0+] RequestQueryAvailableELicenses2
106 [9.0.0+] RequestAssignELicenses2
107 [10.0.0+] GetNetworkInstallTaskStateCounter
108 [10.0.0+] InvalidateDynamicRightsNaIdTokenCacheForDebug
109 [10.0.0+] ListNetworkInstallTaskPartialInstallContentMeta
110 [10.0.0+] ListNetworkInstallTaskRightsIdsFromIndex
111 [10.0.0+] AddNetworkInstallTaskContentMetaForUser
112 [10.0.0+] RequestAssignELicensesAndDownloadETickets
113 [10.0.0+] RequestQueryAvailableCommonELicenses
114 [10.0.0+] SetNetworkInstallTaskExtendedAttribute
115 [10.0.0+] GetNetworkInstallTaskExtendedAttribute
116 [10.0.0+] GetAllocatorInfo
117 [11.0.0+] RequestQueryDownloadableContentsByApplicationId
118 [10.0.0+] MarkNoDownloadRightsErrorResolved
119 [11.0.0+] GetApplyDeltaTaskAllAppliedContentMeta
120 [11.0.0+] PrioritizeNetworkInstallTask
121 [10.1.0+] RequestQueryAvailableCommonELicenses2
122 [10.1.0+] RequestAssignCommonELicenses
123 [10.1.0+] RequestAssignCommonELicenses2
124 [11.0.0+] IsNetworkInstallTaskFrontOfQueue
125 [11.0.0+] PrioritizeApplyDeltaTask
126 [12.0.0+] RerouteDownloadingPatch
127 [12.0.0+] UnmarkNoDownloadRightsErrorResolved
128 [12.0.0+] RequestContentsSize
129 [12.0.0+] RequestContentsAuthorizationToken
130 [13.0.0+] RequestCdnVendorDiscovery
131 [13.0.0+] RefreshDebugAvailability
132 [13.0.0+] ClearResponseSimulationEntry
133 [13.0.0+] RegisterResponseSimulationEntry
134 [13.0.0+] GetProcessedCdnVendors
135 [14.0.0+] RefreshRuntimeBehaviorsForDebug
136 [14.0.0+] RequestOnlineSubscriptionFreeTrialAvailability
137 [14.0.0+] GetNetworkInstallTaskContentMetaCount
138 [15.0.0+] RequestRevokeELicenses
139 [15.0.0+] EnableNetworkConnectionToUseApplicationCore
140 [15.0.0+] DisableNetworkConnectionToUseApplicationCore
141 [15.0.0+] IsNetworkConnectionEnabledToUseApplicationCore
142 [17.0.0+] RequestCheckSafeSystemVersion
143 [17.0.0+] RequestApplicationIcon
144 [17.0.0+] RequestDownloadIdbeIconFile
147 [18.0.0+]
148 [18.0.0+]
150 [19.0.0+]
3000 [17.0.0+] RequestLatestApplicationIcon
3001 [17.0.0+] RequestDownloadIdbeLatestIconFile

[5.0.0+] RequestGameCardRegistrationStatus/RequestRegisterGameCard removed 8-bytes of input, and now takes an additional type-0x5 input buffer.

[12.0.0+] RequestQueryRevokeReason now returns an #IAsyncData instead of #IAsyncValue.

CreateSystemUpdateTask

Takes an input u32 firmware_variation, an u32 unk, a ContentMetaKey, returns an output #SystemUpdateTaskId.

Official sw sets unk to: unk = inflag & 1 ? 0xC : 0x4.

DestroySystemUpdateTask

Takes an input #SystemUpdateTaskId, no output.

ListSystemUpdateTask

Takes a type-0x6 output buffer, for an array of #SystemUpdateTaskId. Returns a s32 for total output entries.

GetSystemUpdateTaskInfo

Takes an input #SystemUpdateTaskId, returns an output #SystemUpdateTaskInfo.

CommitSystemUpdateTask

Takes an input #SystemUpdateTaskId, no output.

RequestNetworkInstallTaskRun

Takes a total of 0x10-bytes of input, returns an output #IAsyncResult and handle.

[13.0.0+] Now takes an additional 1-byte of input.

GetNetworkInstallTaskInfo

Takes an input #NetworkInstallTaskId, returns an output #NetworkInstallTaskInfo.

[10.0.0+] This now returns a total of 0x48-bytes of output instead of 0x40-bytes.

GetDownloadedSystemDataPath

Takes an input u64 titleID, a #SystemUpdateTaskId, and an type-0x16 output buffer containing the FspPath.

Gets the FS FspPath for the specified task and title.

IsExFatDriverIncluded

Takes an input #SystemUpdateTaskId, returns an output u8 bool flag.

GetApplyDeltaTaskInfo

Takes an input #ApplyDeltaTaskId, returns an output #ApplyDeltaTaskInfo.

CreateLocalCommunicationReceiveApplicationTask

Takes an input StorageId, an u16 port, an u32 Ipv4Address, an u32 unk, an u64 nn::ncm::ApplicationId, a type-0x5 input buffer containing an array of ContentMetaKey, returns an output #LocalCommunicationReceiveApplicationTaskId.

This is the ReceiveApplication version of #CreateLocalCommunicationReceiveSystemUpdateTask.

The wrapper used by official sw passes hard-coded value 0x2 for unk.

RequestLocalCommunicationReceiveApplicationTaskRun

Takes an input #LocalCommunicationReceiveApplicationTaskId, returns an output Event and an #IAsyncResult.

This is the ReceiveApplication version of #RequestLocalCommunicationReceiveSystemUpdateTaskRun.

GetLocalCommunicationReceiveApplicationTaskInfo

Takes an input #LocalCommunicationReceiveApplicationTaskId, returns an output #LocalCommunicationReceiveApplicationTaskInfo.

This is the ReceiveApplication version of #GetSystemUpdateTaskInfo.

CreateLocalCommunicationSendApplicationTask

Takes an input u16 port, an u32 Ipv4Address, an u64 nn::ncm::ApplicationId, a type-0x5 input buffer containing an array of {unknown}, returns an output #LocalCommunicationSendApplicationTaskId.

This is the SendApplication version of #CreateLocalCommunicationReceiveSystemUpdateTask.

RequestLocalCommunicationSendApplicationTaskRun

Takes an input #LocalCommunicationSendApplicationTaskId, returns an output Event and an #IAsyncResult.

This is the SendApplicationTask version of #RequestLocalCommunicationReceiveSystemUpdateTaskRun.

GetLocalCommunicationSendApplicationTaskInfo

Takes an input #LocalCommunicationSendApplicationTaskId, returns an output #LocalCommunicationSendApplicationTaskInfo.

This is the SendApplication version of #GetSystemUpdateTaskInfo.

ListApplicationLocalCommunicationReceiveApplicationTask

Takes a type-0x6 output buffer containing an array of #LocalCommunicationReceiveApplicationTaskId and an input u64 nn::ncm::ApplicationId. Returns a s32 for total output entries.

This is the ReceiveApplication version of #ListLocalCommunicationReceiveSystemUpdateTask.

ListApplicationLocalCommunicationSendApplicationTask

Takes a type-0x6 output buffer containing an array of #LocalCommunicationSendApplicationTaskId and an input u64 nn::ncm::ApplicationId. Returns a s32 for total output entries.

This is the SendApplication version of #ListLocalCommunicationReceiveSystemUpdateTask.

CreateLocalCommunicationReceiveSystemUpdateTask

Takes an input u16 port, an u32 Ipv4Address, an u32 firmware_variation, an u32 unk, a ContentMetaKey, returns an output #LocalCommunicationReceiveSystemUpdateTaskId.

Official sw sets unk to: unk = stateflag==0 ? 0x4 : 0xC. The port/Ipv4Address params originate from the RequestReceiveSystemUpdate params.

This is the ReceiveSystemUpdate version of #CreateSystemUpdateTask.

The ContentMetaKey is for the SystemUpdate Meta.

This does state setup, copies ContentMetaKey/firmware_variation/unk into state + more setup, and does socket setup.

Socket setup (standard names are used here, instead of the actual Nintendo func/param names):

  • Sets the output sockfd in state to -1 (unrelated to "sockfd" below).
  • Clears the sockaddr_in.
  • sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); {handle error on fail}
  • Initializes sockaddr_in: sin_addr = htonl({input ipaddr}), sin_port = htons({input port}), and sin_family = AF_INET (sin_len is left at 0).
  • Uses fcntl with F_GETFL/F_SETFL to set O_NONBLOCK, handling error on fail.
  • connect(sockfd, sockaddr_in, sizeof(sockaddr_in));
    • On failure:
    • When the error is EINPROGRESS:
      • Uses select() with input setup for {content of writefds = sockfd}, and timeval setup for a 5-second timeout.
      • When the ret is 0, returns an error since a timeout occured. When the ret is not negative, proceeds to the below setsockopt handling. When negative, run the below error handling.
    • Does error handling and returns.
  • u64 tmpval=1; setsockopt(sockfd, SOL_SOCKET, SO_VENDOR + 0x1, &tmpval, sizeof(tmpval)); {handle error on fail}
  • Uses fcntl with F_GETFL/F_SETFL to clear O_NONBLOCK, handling error on fail.
  • Writes sockfd to the output sockfd state field, then returns 0.
  • All error handling following successful sockfd creation via socket() will also close the socket, when certain errors occur.

ListLocalCommunicationReceiveSystemUpdateTask

Takes a type-0x6 output buffer, for an array of #LocalCommunicationReceiveSystemUpdateTaskId. Returns a s32 for total output entries.

This is the ReceiveSystemUpdate version of #ListSystemUpdateTask.

RequestLocalCommunicationReceiveSystemUpdateTaskRun

Takes an input #LocalCommunicationReceiveSystemUpdateTaskId, returns an output Event and an #IAsyncResult.

This is the ReceiveSystemUpdate version of RequestSystemUpdateTaskRun.

This creates the #IAsyncResult object + the async thread which handles the #IAsyncResult operation, which uses the state previously setup by #CreateLocalCommunicationReceiveSystemUpdateTask. This throws an error if the object was already created.

GetLocalCommunicationReceiveSystemUpdateTaskInfo

Takes an input #LocalCommunicationReceiveSystemUpdateTaskId, returns an output #LocalCommunicationReceiveSystemUpdateTaskInfo.

This is the ReceiveSystemUpdate version of #GetSystemUpdateTaskInfo.

CreateLocalCommunicationSendSystemUpdateTask

Takes an input u16 port, an u32 Ipv4Address, an u32 firmware_variation, and a ContentMetaKey, returns an output #LocalCommunicationSendSystemUpdateTaskId.

[8.0.0+] This now takes an additional 0x8-bytes of input.

The port/Ipv4Address params originate from the RequestSendSystemUpdate params.

The ContentMetaKey is for the SystemUpdate Meta (ContentMetaType must match SystemUpdate).

This is the Send version of #CreateLocalCommunicationReceiveSystemUpdateTask.

This does state setup, does the above ContentMetaType validation, copies ContentMetaKey/firmware_variation into state, and does socket setup.

Socket setup (standard names are used here, instead of the actual Nintendo func/param names):

  • Sets the output sockfds in state to -1 (unrelated to "sockfd" below).
  • Clears the sockaddr_in.
  • sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); {handle error on fail}
  • Uses fcntl with F_GETFL/F_SETFL to set O_NONBLOCK, handling error on fail.
  • u64 tmpval=1; setsockopt(sockfd, SOL_SOCKET, SO_VENDOR + 0x1, &tmpval, sizeof(tmpval)); {handle error on fail}
  • u32 tmpval2=1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &tmpval2, sizeof(tmpval2)); {handle error on fail}
  • Initializes sockaddr_in: sin_addr = htonl({input ipaddr}), sin_port = htons({input port}), and sin_family = AF_INET (sin_len is left at 0).
  • bind(sockfd, sockaddr_in, sizeof(sockaddr_in)); {handle error on fail}
  • listen(sockfd, 1); {handle error on fail}
  • Writes sockfd to the output sockfd state field, copies the input ipaddr u32 into state, then returns 0.
  • The error handling for bind()/listen() will also close the socket, when certain errors occur.

RequestLocalCommunicationSendSystemUpdateTaskRun

Takes an input #LocalCommunicationSendSystemUpdateTaskId, returns an output Event and an #IAsyncResult.

This is the Send version of #RequestLocalCommunicationReceiveSystemUpdateTaskRun.

This creates the #IAsyncResult object + the async thread which handles the #IAsyncResult operation, which uses the state previously setup by #CreateLocalCommunicationSendSystemUpdateTask. This throws an error if the object was already created.

GetLocalCommunicationSendSystemUpdateTaskInfo

Takes an input #LocalCommunicationSendSystemUpdateTaskId, returns an output #LocalCommunicationSendSystemUpdateTaskInfo.

This is the Send version of #GetLocalCommunicationReceiveSystemUpdateTaskInfo.

ListLocalCommunicationSendSystemUpdateTask

Takes a type-0x6 output buffer, for an array of #LocalCommunicationSendSystemUpdateTaskId. Returns a s32 for total output entries.

This is the Send version of #ListLocalCommunicationReceiveSystemUpdateTask.

nim:shp

This is "nn::nim::detail::IShopServiceManager".

This is only available when pm:bm GetBootMode returns output 0 (Normal).

Cmd Name
0 RequestDeviceAuthenticationToken
1 [3.0.0+] RequestCachedDeviceAuthenticationToken
2 [10.0.0+] RequestEdgeToken
3 [10.0.0+] RequestCachedEdgeToken
100 RequestRegisterDeviceAccount
101 RequestUnregisterDeviceAccount
102 [1.0.0-14.1.2] RequestDeviceAccountStatus
103 [1.0.0-14.1.2] GetDeviceAccountInfo
104 [1.0.0-14.1.2] RequestDeviceRegistrationInfo
105 [1.0.0-14.1.2] RequestTransferDeviceAccount
106 [3.0.0-14.1.2] RequestSyncRegistration
107 [3.0.0+] IsOwnDeviceId
108 [14.0.0+] RevertSystemSaveDataOfDeviceAccountForDebug
200 RequestRegisterNotificationToken
300 RequestUnlinkDevice
301 RequestUnlinkDeviceIntegrated
302 RequestLinkDevice
303 [1.0.0-13.2.1] HasDeviceLink
304 [4.0.0+] RequestUnlinkDeviceAll
305 [4.0.0-13.2.1] RequestCreateVirtualAccount
306 [4.0.0+] RequestDeviceLinkStatus
400 [1.0.0-13.2.1] GetAccountByVirtualAccount
401 [6.0.0-13.2.1] GetVirtualAccount
500 RequestSyncTicketLegacy ([1.0.0-8.1.0] RequestSyncTicket)
501 [1.0.0-14.1.2] RequestDownloadTicket
502 [4.0.0+] #RequestDownloadTicketForPrepurchasedContents
503 [9.0.0+] RequestSyncTicket
504 [9.0.0+] RequestDownloadTicketForPrepurchasedContents2
505 [13.1.0+] RequestDownloadTicketForPrepurchasedContentsForAccount
600 [14.0.0+] IsInitialLaunchFinished
601 [14.0.0+] NotifyFinishInitialLaunch

RequestDownloadTicketForPrepurchasedContents

[6.0.0+] Now takes an additional 4-bytes of input.

nim:eca

This is "nn::nim::detail::IShopServiceAccessServerInterface".

This was added with [5.0.0+].

This is only available when pm:bm GetBootMode returns output 0 (Normal).

Cmd Name
0 CreateServerInterface
1 [6.0.0+] RefreshDebugAvailability
2 [6.0.0+] ClearDebugResponse
3 [6.0.0+] RegisterDebugResponse
4 [10.0.0+] IsLargeResourceAvailable
5 [17.0.0+] CreateServerInterface2

IShopServiceAccessServer

This is "nn::nim::detail::IShopServiceAccessServer".

This was added with [5.0.0+].

Cmd Name
0 CreateAccessorInterface

IShopServiceAccessor

This is "nn::nim::detail::IShopServiceAccessor".

This was added with [5.0.0+].

Cmd Name
0 CreateAsyncInterface

IShopServiceAsync

This is "nn::nim::detail::IShopServiceAsync".

This was added with [5.0.0+].

Cmd Name
0 Cancel
1 GetSize
2 Read
3 GetErrorCode
4 Request
5 Prepare

nim:ecas

This is "nn::nim::detail::IShopServiceAccessSystemInterface".

This was added with [7.0.0+].

This is only available when pm:bm GetBootMode returns output 0 (Normal).

Cmd Name
0 RegisterSpecialClient
1 UnregisterSpecialClient

ntc

This is "nn::ntc::detail::service::IStaticService".

Cmd Name
0 OpenEnsureNetworkClockAvailabilityService
100 [3.0.0+] SuspendAutonomicTimeCorrection
101 [3.0.0+] ResumeAutonomicTimeCorrection

Network-time-sync uses the "<...>/time" HTTPS URL listed in the below Network section. This just returns an UTC Unix time string.

IEnsureNetworkClockAvailabilityService

This is "nn::ntc::detail::service::IEnsureNetworkClockAvailabilityService".

Cmd Name
0 StartTask
1 GetFinishNotificationEvent
2 GetResult
3 Cancel
4 IsProcessing
5 [3.0.0+] GetServerTime

SystemUpdateTaskId

This is "nn::nim::SystemUpdateTaskId". This is an 0x10 byte struct containing an nn::util::Uuid.

SystemUpdateTaskInfo

This is "nn::nim::SystemUpdateTaskInfo". This is a 0x28-byte struct.

[3.0.0+] This is a 0x38-byte struct.

[5.0.0+] This is a 0x40-byte struct.

Offset Size Description
0x0 0x1 InstallProgressState
0x4 0x4 LastResult
0x8 0x8 InstalledSize
0x10 0x8 TotalSize
0x18 0x8 ContentMetaKey
0x28 0x8 BytesInstalled
0x30 0x8 ElapsedTimeNs
0x38 0x1 SystemUpdateTaskApplyInfo

The first 0x18-bytes are obtained from NCM_services#GetProgress and the 0x10-bytes at +0x8 are returned by NS_Services#GetDownloadProgress.

The two u64s at +0x28/+0x30 are obtained from NCM_services#GetThroughput and used by NS to calculate "ThroughputKBps" for a SystemPlayReport.

The byte at +0x38 is obtained from NCM_services#GetSystemUpdateTaskApplyInfo.

NetworkInstallTaskId

This is "nn::nim::NetworkInstallTaskId". This is a 0x10-byte struct.

NetworkInstallTaskInfo

This is "nn::nim::NetworkInstallTaskInfo". This is a 0x28-byte struct.

[3.0.0+] This is a 0x40-byte struct.

ApplyDeltaTaskId

This is "nn::nim::ApplyDeltaTaskId". This is a 0x10-byte struct.

ApplyDeltaTaskInfo

This is "nn::nim::ApplyDeltaTaskInfo". This is a 0x20-byte struct.

[3.0.0+] This is a 0x30-byte struct.

ReceiveSystemUpdateTask

This is "nn::nim::LocalCommunicationReceiveSystemUpdateTaskId". This is a 0x10-byte struct.

ReceiveSystemUpdateTaskInfo

This is "nn::nim::LocalCommunicationReceiveSystemUpdateTaskInfo". This is a 0x38-byte struct.

SendSystemUpdateTask

This is "nn::nim::LocalCommunicationSendSystemUpdateTaskId". This is a 0x10-byte struct.

SendSystemUpdateTaskInfo

This is "nn::nim::LocalCommunicationSendSystemUpdateTaskInfo". This is a 0x20-byte struct.

Offset Size Description
0x0 0x1 Status
0x1 0x7 ?
0x8 0x10 SystemUpdateProgress
0x18 0x1 Unknown
0x19 0x7 Padding

LocalCommunicationReceiveApplicationTaskId

This is "nn::nim::LocalCommunicationReceiveApplicationTaskId". This is a 0x10-byte struct.

LocalCommunicationReceiveApplicationTaskInfo

This is "nn::nim::LocalCommunicationReceiveApplicationTaskInfo". This is a 0x38-byte struct.

Offset Size Description
0x0 0x1 Status
0x1 0x7 ?
0x8 0x10 ReceiveApplicationProgress
0x18 0x20 Unknown

LocalCommunicationSendApplicationTaskId

This is "nn::nim::LocalCommunicationSendApplicationTaskId". This is a 0x10-byte struct.

LocalCommunicationSendApplicationTaskInfo

This is "nn::nim::LocalCommunicationSendApplicationTaskInfo". This is a 0x20-byte struct.

Offset Size Description
0x0 0x1 Status
0x1 0x7 ?
0x8 0x10 SendApplicationProgress
0x18 0x8 Unknown

IAsyncValue

This is "nn::nim::detail::IAsyncValue".

Cmd Name
0 GetSize
1 Get
2 Cancel
3 [4.0.0+] GetErrorContext

IAsyncResult

This is "nn::nim::detail::IAsyncResult".

Cmd Name
0 Get
1 Cancel
2 [4.0.0+] GetErrorContext

IAsyncProgressResult

This is "nn::nim::detail::IAsyncProgressResult".

Cmd Name
0 Get
1 Cancel
2 GetProgress
3 [4.0.0+] GetErrorContext

IAsyncData

This is "nn::nim::detail::IAsyncData".

Cmd Name
0 Get
1 Cancel
2 GetSize
3 Read
4 GetETag
5 [4.0.0+] GetErrorContext

Notes

nnMain calls two funcs only when when pm:bm GetBootMode output is 0 or 1 (Normal/Maintenance), which are: es service init, and acc:e:u1 service init.

nnMain only handles ovln:snd initialization/deinit when the output from pm:bm GetBootMode is 0 (Normal).

When initializing ssl, when the input flag is 0 it uses SslVersion = {ApiVersion | Auto}, while when flag is set it uses {ApiVersion | <each flag bit for TLS 1.0-1.2>}. The input flag is set when pm:bm GetBootMode output is 1 or 2 (Maintenance/SafeMode), otherwise it's 0.

nnMain calls a savedata init func with an input flag determined with the output from pm:bm GetBootMode. flag=0 for BootMode Normal, flag=1 for BootMode non-Normal. When flag is set, it deletes the savedata for savedata nim_sys, returning the error on failure. Regardless of flag, it then calls a func which handles mounting savedata nim_sys (and creating it if needed). After checking error and calling another func (with error check), if flag is clear it proceeds with handling other savedata etc, otherwise it calls a func (also called with flag=0 once finished) then returns.

Various hosted services require BootMode Normal, see above.

Contents Delivery

Content can be transferred with a custom protocol over the network. This is intended for use with local ldn networks, however the used IP addresses can be arbitrary. This can be used for SystemUpdates via the above Send/Receive commands (which are then used via ns:su). Application Patch content can also be transferred with this.

See #CreateLocalCommunicationReceiveSystemUpdateTask/#CreateLocalCommunicationSendSystemUpdateTask for the socket setup during Receive/Send task creation. Receive system = client, while Send system = server.

The Receive async thread does the following:

  • Sets the nn::fs::PriorityRaw using a value loaded from state.
  • Calls a func, and writes the returned Result into state.
  • Signals the async Event and returns.
    • That func does:
    • This handles installation, with messages being used via vtable funcptrs.

The Send async thread does the following (the SendApplication thread is identical except it uses different previously setup state):

  • This is identical to the Receive thread except the called func is different.
    • That func does:
    • Gets system-setting nim.errorsimulate!error_localcommunication_result, returning that as an error if set + non-zero.
    • Does socket setup:
    • Calls a func.
    • When any of the above fail (including the system-setting), the Result is written into state, then the Result is returned.
    • Lastly this returns 0.
      • The above func does:
      • This repeatedly receives requests, processes them, and sends the replies. This loop (and func) will only exit when an error occurs, or when request ID 0x0 is used (the latter causes the func to return 0).
      • This handles the requests as required by the ID, no particular order is required by the server.
      • All IDs in the below table are implemented by the server, for both SystemUpdate and Application.
      • An error is thrown if the ID is unrecognized.

The above socket setup for the Send async thread does the following:

  • Clears sockaddr_in and sets addrlen to 0x10.
  • Enters a loop which repeatedly calls a func. If that func fails, this will immediately return.
  • Within that loop the following is done:
  • The following is done after the loop:
  • u64 tmpval=1; setsockopt(sockfd, SOL_SOCKET, SO_VENDOR + 0x1, &tmpval, sizeof(tmpval)); {handle error on fail}
  • Uses nifm GetInternetConnectionStatus, returning an error if this is successful. Hence, the output from this is ignored.
  • Uses fcntl with F_GETFL/F_SETFL to clear O_NONBLOCK with sockfd, handling error on fail.
  • u32 tmpval2=0x4000;
  • u32 tmpval3=0x20000;
  • setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &tmpval2, sizeof(tmpval2)); {error is ignored}
  • setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &tmpval3, sizeof(tmpval3)); {error is ignored}
  • Writes sockfd to the output state sockfd and returns 0.
    • The func used with the above loop does the following:
    • Uses select() with input setup for {content of readfds = sockfd}, and timeval setup for a 1-second timeout. This is used repeatedly, until this returns an error (in which case error handling is done) or returns non-zero.
    • Then this returns 0.

Messages (requests/replies) begin with the following 0x10-byte header, then any associated data.

Offset Size Description
0x0 0x4 u32 magicnum. Must match 0x7152444c (request messages from the Receive system) or 0x7352444c (reply messages from the Send system). Code validating the magicnum always checks both magicnums, not an individual one.
0x4 0x1 u8 ID. The reply ID must match the request ID.
0x5 0x1 Padding
0x6 0x2 u16 meta_size. Must be <=0x1000.
0x8 0x8 s64 data_size. Must not be negative. During message-specific handling with request/reply this must also match the expected value (except for ID 0x0 which is ignored in this case).

After the header is the associated data for meta_size and data_size. The functions which generate the header always leave meta_size at value 0, when receiving the data for meta_size the received data is unused.

The first message used by the client with SystemUpdate is ID 0x1.

With SystemUpdate the server only uses StorageId=BuiltInSystem.

Messages:

ID Request data_size / data Reply data_size / data Description
0x0 0x0 0x0 Tells the server to exit. When handling this the handler func will immediately return 0, without sending a reply.
0x1 ContentMetaKey PackagedContentInfo Gets the PackagedContentInfo with type==Meta for the specified ContentMetaKey. The SystemUpdate client uses the ContentMetaKey from #CreateLocalCommunicationReceiveSystemUpdateTask.
0x2 0x18-bytes: ContentId, u8 flag, u8 pad[7]. When flag is 0, during the transfer #LocalCommunicationSendSystemUpdateTaskInfo SystemUpdateProgress current_size is increased using the size of the current chunk. Once the transfer is finished, the end result is that it would be increased by the total content-size. The only time the nim client sets this flag to 1 with SystemUpdate is with the SystemUpdate Meta content. Size from GetSizeFromContentId with data from ReadContentIdFile. Gets the entire content data for the specified ContentId. The client uses each received chunk of data during the transfer with WritePlaceHolder.
0x3 0x10-byte input for es GetCommonTicketAndCertificateSize/GetCommonTicketAndCertificateData. 0x8-bytes: two size u32s. Then two blocks of data with the sizes specified by the u32s. The server loads the sizes and data from es GetCommonTicketAndCertificateSize/GetCommonTicketAndCertificateData. The two blocks of data are used as the buffers for es ImportTicket by the client. This is used for transferring the specified Application Patch CommonTicket.
0x4 s64 total_size 0x0 The input data is copied into the server state, for #LocalCommunicationSendSystemUpdateTaskInfo SystemUpdateProgress total_size.