NIM services
nim
This is "nn::nim::detail::INetworkInstallManager".
Cmd | Name |
---|---|
0 | #CreateSystemUpdateTask |
1 | #DestroySystemUpdateTask |
2 | #ListSystemUpdateTask |
3 | RequestSystemUpdateTaskRun |
4 | #GetSystemUpdateTaskInfo |
5 | #CommitSystemUpdateTask |
6 | CreateNetworkInstallTask |
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+] |
85 | [5.0.0+] ListNetworkInstallTaskContentMetaFromInstallMeta |
86 | [5.0.0+] ListNetworkInstallTaskOccupiedSize |
87 | [6.0.0+] |
88 | [6.0.0+] |
89 | [6.0.0+] |
90 | [6.0.0+] |
91 | [6.0.0+] |
92 | [6.0.0+] |
93 | [6.0.0+] |
94 | [6.0.0+] |
95 | [6.0.0+] |
96 | [6.0.0+] |
97 | [6.0.0+] |
98 | [6.0.0+] |
99 | [7.0.0+] |
100 | [9.0.0+] |
101 | [9.0.0+] |
102 | [9.0.0+] |
103 | [9.0.0+] |
104 | [9.0.0+] |
105 | [9.0.0+] |
106 | [9.0.0+] |
107 | [10.0.0+] |
108 | [10.0.0+] |
109 | [10.0.0+] |
110 | [10.0.0+] |
111 | [10.0.0+] |
112 | [10.0.0+] |
113 | [10.0.0+] |
114 | [10.0.0+] |
115 | [10.0.0+] |
116 | [10.0.0+] |
117 | [11.0.0+] |
118 | [10.0.0+] |
119 | [11.0.0+] |
120 | [11.0.0+] |
121 | [10.1.0+] |
122 | [10.1.0+] |
123 | [10.1.0+] |
124 | [11.0.0+] |
125 | [11.0.0+] |
126 | [12.0.0+] |
127 | [12.0.0+] |
128 | [12.0.0+] |
129 | [12.0.0+] |
130 | [13.0.0+] |
131 | [13.0.0+] |
132 | [13.0.0+] |
133 | [13.0.0+] |
134 | [13.0.0+] |
[5.0.0+] RequestGameCardRegistrationStatus/RequestRegisterGameCard removed 8-bytes of input, and now takes an additional type-0x5 input buffer.
[8.0.0+] #CreateLocalCommunicationSendSystemUpdateTask now takes an additional 0x8-bytes of input.
[12.0.0+] Cmd92 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 #NetworkInstallTask, 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 ContentPath.
Gets the FS ContentPath for the specified task and title.
IsExFatDriverIncluded
Takes an input #SystemUpdateTaskId, returns an output u8 bool flag.
GetApplyDeltaTaskInfo
Takes an input #ApplyDeltaTask, 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 #ReceiveApplicationTask.
This is the ReceiveApplication version of #CreateLocalCommunicationReceiveSystemUpdateTask.
The wrapper used by official sw passes hard-coded value 0x2 for unk.
RequestLocalCommunicationReceiveApplicationTaskRun
Takes an input #ReceiveApplicationTask, returns an output Event and an #IAsyncResult.
This is the ReceiveApplication version of #RequestLocalCommunicationReceiveSystemUpdateTaskRun.
GetLocalCommunicationReceiveApplicationTaskInfo
Takes an input #ReceiveApplicationTask, returns an output #ReceiveApplicationTaskInfo.
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 #SendApplicationTask.
This is the SendApplication version of #CreateLocalCommunicationReceiveSystemUpdateTask.
RequestLocalCommunicationSendApplicationTaskRun
Takes an input #SendApplicationTask, returns an output Event and an #IAsyncResult.
This is the SendApplicationTask version of #RequestLocalCommunicationReceiveSystemUpdateTaskRun.
GetLocalCommunicationSendApplicationTaskInfo
Takes an input #SendApplicationTask, returns an output #SendApplicationTaskInfo.
This is the SendApplication version of #GetSystemUpdateTaskInfo.
ListApplicationLocalCommunicationReceiveApplicationTask
Takes a type-0x6 output buffer containing an array of #ReceiveApplicationTask 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 #SendApplicationTask 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 #ReceiveSystemUpdateTask.
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 #ReceiveSystemUpdateTask. Returns a s32 for total output entries.
This is the ReceiveSystemUpdate version of #ListSystemUpdateTask.
RequestLocalCommunicationReceiveSystemUpdateTaskRun
Takes an input #ReceiveSystemUpdateTask, 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 #Cmd69. This throws an error if the object was already created.
GetLocalCommunicationReceiveSystemUpdateTaskInfo
Takes an input #ReceiveSystemUpdateTask, returns an output #ReceiveSystemUpdateTaskInfo.
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 #SendSystemUpdateTask.
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 #SendSystemUpdateTask, 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 #SendSystemUpdateTask, returns an output #SendSystemUpdateTaskInfo.
This is the Send version of #GetLocalCommunicationReceiveSystemUpdateTaskInfo.
ListLocalCommunicationSendSystemUpdateTask
Takes a type-0x6 output buffer, for an array of #SendSystemUpdateTask. Returns a s32 for total output entries.
This is the Send version of #ListLocalCommunicationReceiveSystemUpdateTask.
SystemUpdateTaskId
This is an 0x10 byte struct containing an nn::util::Uuid.
SystemUpdateTaskInfo
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 |
This is a 0x28-byte struct. [3.0.0+] This is a 0x38-byte struct. [5.0.0+] This is a 0x40-byte struct.
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.
NetworkInstallTask
This is a 0x10-byte struct.
NetworkInstallTaskInfo
This is a 0x28-byte struct. [3.0.0+] This is a 0x40-byte struct.
ApplyDeltaTask
This is a 0x10-byte struct.
ApplyDeltaTaskInfo
This is a 0x20-byte struct. [3.0.0+] This is a 0x30-byte struct.
ReceiveSystemUpdateTask
This is a 0x10-byte struct.
ReceiveSystemUpdateTaskInfo
This is a 0x38-byte struct.
SendSystemUpdateTask
This is a 0x10-byte struct.
SendSystemUpdateTaskInfo
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Status |
0x1 | 0x7 | ? |
0x8 | 0x10 | SystemUpdateProgress |
0x18 | 0x1 | Unknown |
0x19 | 0x7 | Padding |
This is a 0x20-byte struct.
ReceiveApplicationTask
This is a 0x10-byte struct.
ReceiveApplicationTaskInfo
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Status |
0x1 | 0x7 | ? |
0x8 | 0x10 | ReceiveApplicationProgress |
0x18 | 0x20 | Unknown |
This is a 0x38-byte struct.
SendApplicationTask
This is a 0x10-byte struct.
SendApplicationTaskInfo
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Status |
0x1 | 0x7 | ? |
0x8 | 0x10 | SendApplicationProgress |
0x18 | 0x8 | Unknown |
This is a 0x20-byte struct.
nim:shp
This is "nn::nim::detail::IShopServiceManager".
Cmd | Name |
---|---|
0 | RequestDeviceAuthenticationToken |
1 | [3.0.0+] RequestCachedDeviceAuthenticationToken |
2 | [10.0.0+] RequestEdgeToken |
3 | [10.0.0+] RequestCachedEdgeToken |
100 | RequestRegisterDeviceAccount |
101 | RequestUnregisterDeviceAccount |
102 | RequestDeviceAccountStatus |
103 | GetDeviceAccountInfo |
104 | RequestDeviceRegistrationInfo |
105 | RequestTransferDeviceAccount |
106 | [3.0.0+] RequestSyncRegistration |
107 | [3.0.0+] IsOwnDeviceId |
200 | RequestRegisterNotificationToken |
300 | RequestUnlinkDevice |
301 | RequestUnlinkDeviceIntegrated |
302 | RequestLinkDevice |
303 | HasDeviceLink |
304 | [4.0.0+] RequestUnlinkDeviceAll |
305 | [4.0.0+] RequestCreateVirtualAccount |
306 | [4.0.0+] RequestDeviceLinkStatus |
400 | GetAccountByVirtualAccount |
401 | [6.0.0+] GetVirtualAccount |
500 | RequestSyncTicketLegacy ([1.0.0-8.1.0] RequestSyncTicket) |
501 | RequestDownloadTicket |
502 | [4.0.0+] #RequestDownloadTicketForPrepurchasedContents |
503 | [9.0.0+] RequestSyncTicket |
504 | [9.0.0+] RequestDownloadTicketForPrepurchasedContents2 |
505 | [13.1.0+] |
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+].
Cmd | Name |
---|---|
0 | CreateServerInterface |
1 | [6.0.0+] RefreshDebugAvailability |
2 | [6.0.0+] ClearDebugResponse |
3 | [6.0.0+] RegisterDebugResponse |
4 | [10.0.0+] IsLargeResourceAvailable |
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+].
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 |
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 |
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 #Cmd69/#Cmd76 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:
- sockfd = accept(listen_sockfd, &sockaddr_in, &addrlen); {handle error on fail - listen_sockfd is the saved sockfd from #Cmd76}
- Exits the loop when the ipaddr within sockaddr_in matches the saved ipaddr in state from #Cmd76 (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 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 #Cmd69. |
0x2 | 0x18-bytes: ContentId, u8 flag, u8 pad[7]. When flag is 0, during the transfer #SendSystemUpdateTaskInfo 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 #SendSystemUpdateTaskInfo SystemUpdateProgress total_size. |