LDN handles all local network communication.
ldn:m
This is "nn::ldn::detail::IMonitorServiceCreator".
Cmd | Name |
---|---|
0 | #CreateMonitorService |
CreateMonitorService
Returns an #IMonitorService.
The user-process closes the IMonitorServiceCreator object immediately after using this cmd.
IMonitorService
This is "nn::ldn::detail::IMonitorService".
GetStateForMonitor
No input, returns an output u32.
sdknso implements this by return
ing the u32, with 0 being returned on error.
GetNetworkInfoForMonitor
Takes a type-0x1A output buffer containing a #NetworkInfo.
GetIpv4AddressForMonitor
No input, returns an output #Ipv4Address and a #SubnetMask.
GetDisconnectReasonForMonitor
No input, returns an output s16.
This is not exposed by sdknso.
This just returns 0.
GetSecurityParameterForMonitor
No input, returns an output #SecurityParameter.
This is not exposed by sdknso.
GetNetworkConfigForMonitor
No input, returns an output #NetworkConfig.
This is not exposed by sdknso.
InitializeMonitor
No input/output.
This is used immediately after object creation. Official sw will Abort if this fails.
This just returns 0.
FinalizeMonitor
No input/output.
This is used during service exit, prior to closing the object. Official sw will Abort if this fails.
This just returns 0.
ldn:s
This is "nn::ldn::detail::ISystemServiceCreator".
Cmd | Name |
---|---|
0 | #CreateSystemLocalCommunicationService |
CreateSystemLocalCommunicationService
Returns an #ISystemLocalCommunicationService.
The user-process closes the ISystemServiceCreator object immediately after using this cmd. Official sw ignores errors from this cmd.
ISystemLocalCommunicationService
This is "nn::ldn::detail::ISystemLocalCommunicationService".
Cmd | Name |
---|---|
0 | #GetState |
1 | #GetNetworkInfo |
2 | #GetIpv4Address |
3 | #GetDisconnectReason |
4 | #GetSecurityParameter |
5 | #GetNetworkConfig |
100 | #AttachStateChangeEvent |
101 | #GetNetworkInfoLatestUpdate |
102 | #Scan |
103 | #ScanPrivate |
104 | [5.0.0+] #SetWirelessControllerRestriction |
200 | #OpenAccessPoint |
201 | #CloseAccessPoint |
202 | #CreateNetwork |
203 | #CreateNetworkPrivate |
204 | #DestroyNetwork |
205 | #Reject |
206 | #SetAdvertiseData |
207 | #SetStationAcceptPolicy |
208 | #AddAcceptFilterEntry |
209 | #ClearAcceptFilter |
300 | #OpenStation |
301 | #CloseStation |
302 | #Connect |
303 | #ConnectPrivate |
304 | #Disconnect |
400 | #InitializeSystem |
401 | #FinalizeSystem |
402 | [4.0.0+] #SetOperationMode |
403 | [7.0.0+] #InitializeSystem2 |
GetState
No input, returns an output u32.
sdknso implements this by return
ing the u32, with 0 being returned on error / when service isn't initialized.
Value | Description |
---|---|
0 | None |
1 | Initialized |
2 | AccessPointOpened |
3 | AccessPointCreated |
4 | StationOpened |
5 | StationConnected |
6 | Invalid |
GetNetworkInfo
Takes a type-0x1A output buffer containing a #NetworkInfo.
GetIpv4Address
No input, returns an output #Ipv4Address and a #SubnetMask.
GetDisconnectReason
No input, returns an output s16.
sdknso implements this by return
ing the s16 as a s32, with -1 being returned on error.
Value | Description |
---|---|
-1 | See above. |
0 | None |
1 | User |
2 | SystemRequest |
3 | DestroyedByAdmin |
4 | DestroyedBySystemRequest |
5 | Admin |
6 | SignalLost |
GetSecurityParameter
No input, returns an output #SecurityParameter.
GetNetworkConfig
No input, returns an output #NetworkConfig.
AttachStateChangeEvent
No input, returns an output Event handle.
sdknso uses EventClearMode=1 with this. sdknso will Abort if this cmd fails.
GetNetworkInfoLatestUpdate
Takes a type-0x1A output buffer containing a #NetworkInfo and a type-0xA output buffer containing an array of #NodeLatestUpdate.
The array count must be 8.
Scan
Takes a type-0x22 output buffer containing an array of #NetworkInfo, a s16 channel, a #ScanFilter, returns an output s16 total_out.
sdknso copies the output s16 to a s32, the value passed for the input s16 is from an user-specified s32 (user-apps generally use value 0 for this).
This is the same as #ScanPrivate, except this also has the same channel-override functionality as #CreateNetwork.
State must be 3-5.
The array count must be at least 1. This is clamped to a maximum of 0x18.
ScanPrivate
Takes a type-0x22 output buffer containing an array of #NetworkInfo, a s16 channel, a #ScanFilter, returns an output s16 total_out.
sdknso copies the output s16 to a s32, the value passed for the input s16 is from an user-specified s32.
See #Scan.
SetWirelessControllerRestriction
Takes an input #WirelessControllerRestriction, no output.
State must be 1.
OpenAccessPoint
No input/output.
State must be 1, this cmd eventually sets the State to value 2.
CloseAccessPoint
No input/output.
State must be 2-3, this cmd eventually sets the State to value 1.
CreateNetwork
Takes an input #SecurityConfig, an #UserConfig, a #NetworkConfig, no output.
This is the same as #CreateNetworkPrivate, except the #AddressEntry params are 0, and the #SecurityParameter is generated from "nn::util::TinyMt::GenerateRandomBytes".
Unlike CreateNetworkPrivate, this overwrites the channel field in the #NetworkConfig. When the cached IsDevelopment value is true, the output from GetLdnChannel will overwrite that field if the s32 setting value is >=0, otherwise the original value is used. Otherwise when the IsDevelopment field is false (retail), the channel is overwritten with value 0.
This overwrites the u16 field at #SecurityConfig+0. When the cached IsDevelopment value is false (retail), value 1 is used, otherwise the original value is used.
State must be 2, this cmd eventually sets the State to value 3.
CreateNetworkPrivate
Takes an input #SecurityConfig, a #SecurityParameter, an #UserConfig, a #NetworkConfig, a type-0x9 input buffer containing an array of #AddressEntry, no output.
The buffer/count for #AddressEntry can be 0, in which case the network will be non-Private like #CreateNetwork. The count must be <=8.
See #CreateNetwork.
DestroyNetwork
No input/output.
State must be 3, this cmd eventually sets the State to value 2.
Reject
Takes an input #Ipv4Address, no output.
State must be 3.
SetAdvertiseData
Takes a type-0x21 input buffer, no output.
The input buffer contains arbitrary user data.
The buffer size must be <=0x180. An empty buffer (addr=NULL/size=0) can be used to reset the AdvertiseData size in state to zero.
State must be 2-3.
SetStationAcceptPolicy
Takes an input #AcceptPolicy, no output.
State must be 2-3.
AddAcceptFilterEntry
Takes an input #MacAddress, no output.
There are two sdknso funcs implementing this: one which takes a #MacAddress directly, the other loads the #MacAddress from the input #NodeInfo.
State must be 2-3.
ClearAcceptFilter
No input/output.
State must be 2-3.
OpenStation
No input/output.
State must be 1, this cmd eventually sets the State to value 4.
CloseStation
No input/output.
State must be 4-5, this cmd eventually sets the State to value 1.
Connect
Takes a type-0x19 input buffer containing a #NetworkInfo, a #SecurityConfig, an #UserConfig, a s32 LocalCommunicationVersion, a #ConnectOption, no output.
State must be 4, this cmd eventually sets the State to value 5.
This is identical to #ConnectPrivate (besides the below), except the data internally passed for #SecurityParameter/#NetworkConfig are loaded from the input #NetworkInfo.
This overwrites the u16 field at #SecurityConfig+0. When the cached IsDevelopment value is false (retail), value 1 is used, otherwise the used value is: original_field == 0 ? {u16 #NetworkInfo+0x60} : original_field.
u32 LocalCommunicationVersion>>15 must be 0.
ConnectPrivate
Takes a #SecurityConfig, #SecurityParameter, an #UserConfig, a s32 LocalCommunicationVersion, a #ConnectOption, a #NetworkConfig, no output.
See #Connect.
This overwrites the u16 field at #SecurityConfig+0. When the cached IsDevelopment value is false (retail), value 1 is used, otherwise the original value is used.
Disconnect
No input/output.
State must be 5, this cmd eventually sets the State to value 4.
InitializeSystem
Takes an input PID and an u64 pid_placeholder.
This is used immediately after object creation.
With [7.0.0+] #InitializeSystem2 is used instead.
FinalizeSystem
No input/output.
This is used during service exit, prior to closing the object. Official sw will Abort if this fails.
If State is set for it, this will run the equivalent of #CloseAccessPoint/#CloseStation when needed.
State must be non-zero, this cmd eventually sets the State to value 0.
SetOperationMode
Takes an input #OperationMode, no output.
State must be 1.
InitializeSystem2
Takes an input PID, an u32, and an u64 pid_placeholder.
Official sw uses hard-coded value 0x1 for the u32.
The input u32 is ignored, the impl for this cmd is identical to #InitializeSystem.
State must be 0, this cmd eventually sets the State to value 1.
ldn:u
This is "nn::ldn::detail::IUserServiceCreator".
Cmd | Name |
---|---|
0 | #CreateUserLocalCommunicationService |
CreateUserLocalCommunicationService
Returns an #IUserLocalCommunicationService.
The user-process closes the IUserServiceCreator object immediately after using this cmd. Official sw ignores errors from this cmd.
IUserLocalCommunicationService
This is "nn::ldn::detail::IUserLocalCommunicationService".
Cmd | Name |
---|---|
0 | #GetState |
1 | #GetNetworkInfo |
2 | #GetIpv4Address |
3 | #GetDisconnectReason |
4 | #GetSecurityParameter |
5 | #GetNetworkConfig |
100 | #AttachStateChangeEvent |
101 | #GetNetworkInfoLatestUpdate |
102 | #Scan |
103 | #ScanPrivate |
104 | [5.0.0+] #SetWirelessControllerRestriction |
200 | #OpenAccessPoint |
201 | #CloseAccessPoint |
202 | #CreateNetwork |
203 | #CreateNetworkPrivate |
204 | #DestroyNetwork |
205 | #Reject |
206 | #SetAdvertiseData |
207 | #SetStationAcceptPolicy |
208 | #AddAcceptFilterEntry |
209 | #ClearAcceptFilter |
300 | #OpenStation |
301 | #CloseStation |
302 | #Connect |
303 | #ConnectPrivate |
304 | #Disconnect |
400 | #Initialize |
401 | #Finalize |
402 | [7.0.0+] #Initialize2 |
Initialize
Takes an input PID and an u64 pid_placeholder.
This is used immediately after object creation.
With [7.0.0+] #Initialize2 is used instead.
Finalize
No input/output.
This is used during service exit, prior to closing the object. Official sw will Abort if this fails.
Initialize2
Takes an input PID, an u32, and an u64 pid_placeholder.
Official sw uses hard-coded value 0x1 for the u32.
The input u32 is ignored, the impl for this cmd is identical to #Initialize.
ndd
This is "nn::ndd::IService".
This was added with [5.0.0] and removed with [6.0.0].
Cmd | Name |
---|---|
0 | EnableAutoCommunication |
1 | DisableAutoCommunication |
2 | IsAutoCommunicationEnabled |
3 | EnablePowerSave |
4 | DisablePowerSave |
5 | IsPowerSaveEnabled |
6 | IsNetworkActive |
7 | AcquireSendDataUpdateEvent |
8 | AddSendData |
9 | ClearSendData |
10 | GetSendData |
11 | AcquireReceiveDataEvent |
12 | GetCurrentReceiveDataCounter |
13 | GetOldestReceiveDataCounter |
14 | GetNextReceiveDataCounter |
15 | GetAvailableReceiveDataCount |
16 | GetRecentReceiveDataCounter |
17 | GetReceiveData |
18 | AddReceiveData |
19 | ClearReceiveData |
20 | ClearDataIdFilter |
21 | AcquireDeviceScanEvent |
22 | StartDeviceScan |
23 | CancelDeviceScan |
24 | GetDeviceScanResult |
lp2p:app, lp2p:sys
These are "nn::lp2p::detail::INetworkServiceCreator".
These were added with [9.0.0+].
Cmd | Name |
---|---|
0 | CreateNetworkService |
8 | CreateNetworkServiceMonitor |
INetworkService
This is "nn::lp2p::detail::INetworkService".
Cmd | Name |
---|---|
0 | Initialize |
[9.0.0-9.0.1] 256 | AttachNetworkInterfaceStateChangeEvent |
[9.0.0-9.0.1] 264 | GetNetworkInterfaceLastError |
[9.0.0-9.0.1] 272 | GetRole |
[9.0.0-9.0.1] 280 | |
[9.0.0-9.0.1] 288 | GetGroupInfo |
[9.0.0-9.0.1] 296 | |
[9.0.0-9.0.1] 304 | |
[9.0.0-9.0.1] 312 | |
[9.0.0-9.0.1] 320 | |
512 | |
768 | |
776 | |
784 | |
1536 | SendToOtherGroup |
1544 | RecvFromOtherGroup |
1552 | AddAcceptableGroupId |
1560 | [9.1.0+] |
Initialize
Returns 0.
INetworkServiceMonitor
This is "nn::lp2p::detail::INetworkServiceMonitor".
This interface has no commands, until [9.1.0+] which added actual commands.
Cmd | Name |
---|---|
0 | Initialize |
256 | AttachNetworkInterfaceStateChangeEvent |
264 | GetNetworkInterfaceLastError |
272 | GetRole |
280 | |
281 | |
288 | GetGroupInfo |
296 | |
304 | |
312 | |
320 | |
328 | AttachJoinEvent |
336 |
Initialize
Returns 0.
lp2p:m
This is "nn::lp2p::detail::IMonitorServiceCreator".
This was added with [9.1.0+].
Cmd | Name |
---|---|
0 | #CreateMonitorService |
CreateMonitorService
Takes a PID, a total of 0x10-bytes of input, and returns an #IMonitorService.
IMonitorService
This is "nn::lp2p::detail::IMonitorService".
Cmd | Name |
---|---|
0 | Initialize |
288 | GetGroupInfo |
320 |
Initialize
Returns 0.
Ipv4Address
This is "nn::ldn::Ipv4Address". This is a 0x4-byte struct with 4-byte alignment.
This is essentially the same as struct in_addr
.
SubnetMask
This is "nn::ldn::SubnetMask". This is a 0x4-byte struct with 4-byte alignment.
This is essentially the same as struct in_addr
.
Ssid
This is "nn::ldn::Ssid".
When converting a Ssid to a string, the loaded chars from the string must be in the range of 0x20-0x7F, otherwise the byte written to the string will be 0.
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Length excluding NUL-terminator, must be 0x1-0x20. |
0x1 | 0x21 | SSID string including NUL-terminator, str[{above length}] must be 0. |
NetworkInfo
This is "nn::ldn::NetworkInfo". This is a 0x480-byte struct. The data at +0x50 is another struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | LocalCommunicationId |
0x8 | 0x2 | |
0xA | 0x2 | |
0xC | 0x4 | |
0x10 | 0x10 | Last 0x10-bytes of #SecurityParameter. |
0x20 | 0x6 | #MacAddress |
0x26 | 0x22 | #Ssid. After filtering with #Scan when +0x4B is value 0x2, this is overwritten with data converted from +0x10. |
0x48 | 0x2 | Channel |
0x4A | 0x1 | |
0x4B | 0x1 | |
0x4C | 0x4 | |
0x50 | 0x10 | First 0x10-bytes of #SecurityParameter. |
0x60 | 0x2 | Same as #SecurityConfig+0x0. |
0x62 | 0x4 | |
0x66 | 0x1 | |
0x67 | 0xD | |
0x74 | 0x20 | First 0x20-bytes of #UserConfig. |
0x94 | 0x2 | |
0x96 | 0x2 | s16 LocalCommunicationVersion |
0x98 | 0x1D2 | |
0x26A | 0x2 | AdvertiseData size |
0x26C | 0x180 | AdvertiseData |
0x3EC | 0x8C | |
0x478 | 0x8 |
ScanFilter
This is "nn::ldn::ScanFilter". This is a 0x60-byte struct with 8-byte alignment.
sdknso copies the input ScanFilter to a tmp struct on stack, which is then used with the cmd.
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | When enabled, this will be overwritten if it's -1. The data written for this is the first LocalCommunicationId for the user-process loaded via arp:r, if loading fails value 0 is written instead. During filtering if enabled, u8 #NetworkInfo+0x4B must match 0x2, and this ScanFilter field must match #NetworkInfo+0x0. |
0x8 | 0x2 | Padding |
0xA | 0x2 | During filtering if enabled, u8 #NetworkInfo+0x4B must match 0x2, and this ScanFilter field must match #NetworkInfo+0xA. |
0xC | 0x4 | Padding |
0x10 | 0x10 | During filtering if enabled, u8 #NetworkInfo+0x4B must match 0x2, and this ScanFilter data must match #NetworkInfo+0x10. |
0x20 | 0x4 | When enabled, must be <=0x3, and during filtering must match u8 #NetworkInfo+0x4B. |
0x24 | 0x6 | #MacAddress. Only copied with #ScanPrivate. During filtering if enabled, this must match #NetworkInfo+0x20. |
0x2A | 0x22 | #Ssid. During filtering if enabled, this must match #NetworkInfo+0x26 (the #Ssid there must be valid for this as well). The strings are compared, without verifying the length field in #Ssid matches. |
0x4C | 0x10 | Cleared to zero for the tmp struct. |
0x5C | 0x4 | Flags. Masked with 0x37 for #Scan, with #ScanPrivate this is masked with 0x3F. |
Flags:
Bit | Description |
---|---|
0 | When set, enables using ScanFilter+0. |
1 | When set, enables using ScanFilter+0x10. |
2 | When set, enables using ScanFilter+0x20. |
3 | When set, enables using the ScanFilter #MacAddress. |
4 | When set, enables using the ScanFilter #Ssid. |
5 | When set, enables using ScanFilter+0xA. |
NetworkConfig
This is "nn::ldn::NetworkConfig". This is a 0x20-byte struct with 8-byte alignment.
sdknso copies the input NetworkConfig to a tmp struct on stack, which is then used with the cmd (#CreateNetwork, #CreateNetworkPrivate, #ConnectPrivate).
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | LocalCommunicationId. Same as #NetworkInfo+0x0. #CreateNetwork/#CreateNetworkPrivate/#Connect/#ConnectPrivate: When -1, this is overwritten with the first LocalCommunicationId for the user-process loaded via arp:r, if loading fails value 0 is written instead. Otherwise when not -1, if control.nacp loading is successful with arp:r, this field must match one of the LocalCommunicationIds from there otherwise an error is thrown. |
0x8 | 0x2 | Cleared to zero during the copy. |
0xA | 0x2 | Same as #NetworkInfo+0xA. |
0xC | 0x4 | Cleared to zero during the copy. |
0x10 | 0x2 | s16 Channel, can be zero. Same as #NetworkInfo+0x48. |
0x12 | 0x1 | s8. Same as #NetworkInfo+0x66. #CreateNetwork/#CreateNetworkPrivate: Must be 0x1-0x8. |
0x13 | 0x1 | Cleared to zero during the copy. |
0x14 | 0x2 | Same as #NetworkInfo+0x96. Must not be negative. |
0x16 | 0xA | Cleared to zero during the copy. |
NodeLatestUpdate
This is "nn::ldn::NodeLatestUpdate". This is a 0x8-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Flag, the field in state is reset to zero by #GetNetworkInfoLatestUpdate after loading it. |
0x1 | 0x7 | Not initialized with #GetNetworkInfoLatestUpdate. |
WirelessControllerRestriction
This is "nn::ldn::WirelessControllerRestriction". This is an u32 enum.
Value | Description |
---|---|
0 | |
1 |
SecurityConfig
This is "nn::ldn::SecurityConfig". This is a 0x44-byte struct with 2-byte alignment.
Offset | Size | Description |
---|---|---|
0x0 | 0x2 | Overwritten by #CreateNetwork/#CreateNetworkPrivate and #Connect/#ConnectPrivate. The value used internally by these cmds must be 0x1-0x3. |
0x2 | 0x2 | Must be 0x10-0x40. |
0x4 | 0x40 |
SecurityParameter
This is "nn::ldn::SecurityParameter". This is a 0x20-byte struct with 1-byte alignment.
UserConfig
This is "nn::ldn::UserConfig". This is a 0x30-byte struct with 1-byte alignment.
sdknso copies the input UserConfig to a tmp struct on stack, which is then used with the cmd.
Offset | Size | Description |
---|---|---|
0x0 | 0x20 | NUL-terminated string for the user nickname. |
0x20 | 0x10 | Cleared to zero during the copy. |
AddressEntry
This is "nn::ldn::AddressEntry". This is a 0xC-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | #Ipv4Address |
0x4 | 0x6 | #MacAddress |
0xA | 0x2 | Padding |
AcceptPolicy
This is "nn::ldn::AcceptPolicy". This is an u8.
Value | Description |
---|---|
0 | |
1 | |
2 | |
3 |
MacAddress
This is "nn::ldn::MacAddress". This is a 6-byte struct with 1-byte alignment.
NodeInfo
This is "nn::ldn::NodeInfo".
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | #Ipv4Address |
0x4 | 0x6 | #MacAddress |
ConnectOption
This is "nn::ldn::ConnectOption". This is an u32 bitmask.
There's two versions of the sdknso funcs for #Connect/#ConnectPrivate: the version where the ConnectOption isn't user-specified uses a default value of 0x1 for it, with the same ShowError code without the bit0 check.
When bit0 here is set after using the above cmds, the sdknso funcs will use ShowError with the returned Result if: (rc & 0x3FE1FF) == 0xE0CB.
This must be <=0x1, besides this validation ConnectOption is ignored by #Connect/#ConnectPrivate.
OperationMode
This is "nn::ldn::OperationMode". This is an u32 enum.
Value | Description |
---|---|
0 | |
1 |