Changes

no edit summary
Line 90: Line 90:  
|-
 
|-
 
| 0 || [[#CreateSystemLocalCommunicationService]]
 
| 0 || [[#CreateSystemLocalCommunicationService]]
 +
|-
 +
| 1 || [18.0.0+] [[#CreateClientProcessMonitor]]
 
|}
 
|}
    
== CreateSystemLocalCommunicationService ==
 
== CreateSystemLocalCommunicationService ==
Returns an [[#ISystemLocalCommunicationService]].
+
No input. Returns an [[#ISystemLocalCommunicationService]].
    
The user-process closes the ISystemServiceCreator object immediately after using this cmd. Official sw ignores errors from this cmd.
 
The user-process closes the ISystemServiceCreator object immediately after using this cmd. Official sw ignores errors from this cmd.
 +
 +
== CreateClientProcessMonitor ==
 +
No input. Returns an [[#IClientProcessMonitor]].
    
== ISystemLocalCommunicationService ==
 
== ISystemLocalCommunicationService ==
Line 125: Line 130:  
|-
 
|-
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 +
|-
 +
| 105 || [13.1.0+] [[#SetBluetoothAudioDeviceConnectableMode]]
 +
|-
 +
| 106 || [18.0.0+]
 
|-
 
|-
 
| 200 || [[#OpenAccessPoint]]
 
| 200 || [[#OpenAccessPoint]]
Line 163: Line 172:  
|-
 
|-
 
| 403 || [7.0.0+] [[#InitializeSystem2]]
 
| 403 || [7.0.0+] [[#InitializeSystem2]]
|}
  −
  −
=== GetState ===
  −
No input, returns an output u32.
  −
  −
sdknso implements this by <code>return</code>ing the u32, with 0 being returned on error / when service isn't initialized.
  −
  −
{| class="wikitable" border="1"
  −
|-
  −
!  Value
  −
!  Description
   
|-
 
|-
| 0 || None
+
| 500 || [18.0.0+] EnableActionFrame
 
|-
 
|-
| 1 || Initialized
+
| 501 || [18.0.0+] DisableActionFrame
 
|-
 
|-
| 2 || AccessPointOpened
+
| 502 || [18.0.0+] SendActionFrame
 
|-
 
|-
| 3 || AccessPointCreated
+
| 503 || [18.0.0+] RecvActionFrame
 
|-
 
|-
| 4 || StationOpened
+
| 505 || [18.0.0+] SetHomeChannel
 
|-
 
|-
| 5 || StationConnected
+
| 600 || [18.0.0+] SetTxPower
|-
  −
| 6 || Error
   
|-
 
|-
 +
| 601 || [18.0.0+] ResetTxPower
 
|}
 
|}
 +
 +
=== GetState ===
 +
No input, returns an output [[#State]].
 +
 +
sdknso implements this by <code>return</code>ing the u32, with 0 being returned on error / when service isn't initialized.
    
=== GetNetworkInfo ===
 
=== GetNetworkInfo ===
Line 198: Line 200:     
=== GetDisconnectReason ===
 
=== GetDisconnectReason ===
No input, returns an output s16.
+
No input, returns an output [[#DisconnectReason]].
    
sdknso implements this by <code>return</code>ing the s16 as a s32, with -1 being returned on error.
 
sdknso implements this by <code>return</code>ing the s16 as a s32, with -1 being returned on error.
   −
{| class="wikitable" border="1"
+
=== GetSecurityParameter ===
|-
  −
!  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]].
 
No input, returns an output [[#SecurityParameter]].
   Line 266: Line 246:     
The input value is written into state.
 
The input value is written into state.
 +
 +
=== SetBluetoothAudioDeviceConnectableMode ===
 +
Takes an input [[#BluetoothAudioDeviceConnectableMode]], no output.
    
=== OpenAccessPoint ===
 
=== OpenAccessPoint ===
Line 399: Line 382:     
[[#GetState|State]] must be 0, this cmd eventually sets the State to value 1.
 
[[#GetState|State]] must be 0, this cmd eventually sets the State to value 1.
 +
 +
== IClientProcessMonitor ==
 +
This is "nn::ldn::detail::IClientProcessMonitor".
 +
 +
This was added with [18.0.0+].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || RegisterClient
 +
|}
    
= ldn:u =
 
= ldn:u =
Line 408: Line 403:  
|-
 
|-
 
| 0 || [[#CreateUserLocalCommunicationService]]
 
| 0 || [[#CreateUserLocalCommunicationService]]
 +
|-
 +
| 1 || [18.0.0+] [[#CreateClientProcessMonitor]]
 
|}
 
|}
   Line 445: Line 442:  
|-
 
|-
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 +
|-
 +
| 105 || [13.1.0+] [[#SetBluetoothAudioDeviceConnectableMode]]
 +
|-
 +
| 106 || [18.0.0+]
 
|-
 
|-
 
| 200 || [[#OpenAccessPoint]]
 
| 200 || [[#OpenAccessPoint]]
Line 481: Line 482:  
|-
 
|-
 
| 402 || [7.0.0+] [[#Initialize2]]
 
| 402 || [7.0.0+] [[#Initialize2]]
 +
|-
 +
| 500 || [18.0.0+] EnableActionFrame
 +
|-
 +
| 501 || [18.0.0+] DisableActionFrame
 +
|-
 +
| 502 || [18.0.0+] SendActionFrame
 +
|-
 +
| 503 || [18.0.0+] RecvActionFrame
 +
|-
 +
| 505 || [18.0.0+] SetHomeChannel
 +
|-
 +
| 600 || [18.0.0+] SetTxPower
 +
|-
 +
| 601 || [18.0.0+] ResetTxPower
 
|}
 
|}
   Line 569: Line 584:     
= lp2p:app, lp2p:sys =
 
= lp2p:app, lp2p:sys =
These are "nn::lp2p::detail::INetworkServiceCreator".
+
These are "nn::lp2p::detail::ISfServiceCreator".
    
These were added with [9.0.0+].
 
These were added with [9.0.0+].
Line 585: Line 600:     
== CreateNetworkService ==
 
== CreateNetworkService ==
Takes an input u32, an u64 pid_reserved, a PID, returns an output [[#INetworkService]].
+
Takes a PID-descriptor, a reserved input u64 and an input u32. Returns an output [[#ISfService]].
    
The input u32 must be value 0x1.
 
The input u32 must be value 0x1.
    
== CreateNetworkServiceMonitor ==
 
== CreateNetworkServiceMonitor ==
Takes an input u64 pid_reserved, a PID, returns an output [[#INetworkServiceMonitor]].
+
Takes a PID-descriptor and a reserved input u64. Returns an output [[#ISfServiceMonitor]].
   −
== INetworkService ==
+
== ISfService ==
This is "nn::lp2p::detail::INetworkService".
+
This is "nn::lp2p::detail::ISfService".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 611: Line 626:  
| [9.0.0-9.0.1] 288 || [[#GetGroupInfo]]
 
| [9.0.0-9.0.1] 288 || [[#GetGroupInfo]]
 
|-
 
|-
| [9.0.0-9.0.1] 296 || [[#Join]]
+
| [9.0.0-9.0.1] 296 || [[#GetGroupInfo2]]
 
|-
 
|-
 
| [9.0.0-9.0.1] 304 || [[#GetGroupOwner]]
 
| [9.0.0-9.0.1] 304 || [[#GetGroupOwner]]
Line 617: Line 632:  
| [9.0.0-9.0.1] 312 || [[#GetIpConfig]]
 
| [9.0.0-9.0.1] 312 || [[#GetIpConfig]]
 
|-
 
|-
| [9.0.0-9.0.1] 320 || [[#Leave]]
+
| [9.0.0-9.0.1] 320 || [[#GetLinkLevel]]
 
|-
 
|-
 
| 512 || [[#Scan]]
 
| 512 || [[#Scan]]
Line 633: Line 648:  
| 1552 || [[#AddAcceptableGroupId]]
 
| 1552 || [[#AddAcceptableGroupId]]
 
|-
 
|-
| 1560 || [9.1.0+] [[#RemoveAcceptableGroupId]]
+
| 1560 || [9.1.0+] [[#ClearAcceptableGroupId]]
 
|}
 
|}
   Line 644: Line 659:     
=== Scan ===
 
=== Scan ===
Takes a type-0x19 input buffer containing a [[#GroupInfo]], a type-0x22 output buffer containing an array of [[#ScanResult]], returns an output s32 total_out.
+
Takes a type-0x19 input buffer containing a [[#GroupInfo]] and a type-0x22 output buffer containing an array of [[#ScanResult]]. Returns an output s32 '''TotalOut'''.
    
=== CreateGroup ===
 
=== CreateGroup ===
Takes a type-0x31 input buffer containing a [[#GroupInfo]], no output.
+
Takes a type-0x31 input buffer containing a [[#GroupInfo]]. No output.
    
[[Mario Kart Live: Home Circuit|mklive]] uses the following string with this: "Failed to create a group: %08X".
 
[[Mario Kart Live: Home Circuit|mklive]] uses the following string with this: "Failed to create a group: %08X".
Line 659: Line 674:     
=== SetAdvertiseData ===
 
=== SetAdvertiseData ===
Takes a type-0x21 input buffer, no output.
+
Takes a type-0x21 input buffer. No output.
    
The buffer size must be <=0x80. The [[#GetRole|role]] must be <=1.
 
The buffer size must be <=0x80. The [[#GetRole|role]] must be <=1.
Line 666: Line 681:     
=== SendToOtherGroup ===
 
=== SendToOtherGroup ===
Takes an input [[#MacAddress_2|MacAddress]], a [[#GroupId]], a s16 frequency, a s16 channel, an u32 flags, a type-0x21 input buffer, no output.
+
Takes an input [[#MacAddress_2|MacAddress]], a [[#GroupId]], a s16 '''Frequency''', a s16 '''Channel''', an u32 '''MessageFlag''' and a type-0x21 input buffer. No output.
    
The buffer size must be <=0x400.
 
The buffer size must be <=0x400.
Line 685: Line 700:     
=== RecvFromOtherGroup ===
 
=== RecvFromOtherGroup ===
Takes an input u32 flags, a type-0x22 output buffer, returns a [[#MacAddress_2|MacAddress]], an u16, a s16, an u32 out_size, a s32.
+
Takes an input u32 '''MessageFlag''' and a type-0x22 output buffer. Returns a [[#MacAddress_2|MacAddress]], an u16 '''Frequency''', a s16 '''Channel''', an u32 '''OutSize''' and a s32.
   −
The out_size is the original size used for copying to the output buffer, before it's clamped to the output-buffer size.
+
The OutSize is the original size used for copying to the output buffer, before it's clamped to the output-buffer size.
   −
Only bit0 is used from flags: clear = block until data is available, set = return error when data is not available.
+
Only bit0 is used from MessageFlag: clear = block until data is available, set = return error when data is not available.
    
When data is not available, the error from [[#GetNetworkInterfaceLastError]] will be returned if it's set.
 
When data is not available, the error from [[#GetNetworkInterfaceLastError]] will be returned if it's set.
Line 698: Line 713:     
=== AddAcceptableGroupId ===
 
=== AddAcceptableGroupId ===
Takes an input [[#GroupId]], no output.
+
Takes an input [[#GroupId]]. No output.
   −
=== RemoveAcceptableGroupId ===
+
=== ClearAcceptableGroupId ===
 
No input/output.
 
No input/output.
   −
== INetworkServiceMonitor ==
+
== ISfServiceMonitor ==
This is "nn::lp2p::detail::INetworkServiceMonitor".
+
This is "nn::lp2p::detail::ISfServiceMonitor".
    
This interface has no commands, until [9.1.0+] which added actual commands.
 
This interface has no commands, until [9.1.0+] which added actual commands.
Line 726: Line 741:  
| 288 || [[#GetGroupInfo]]
 
| 288 || [[#GetGroupInfo]]
 
|-
 
|-
| 296 || [[#Join]]
+
| 296 || [[#GetGroupInfo2]]
 
|-
 
|-
 
| 304 || [[#GetGroupOwner]]
 
| 304 || [[#GetGroupOwner]]
Line 732: Line 747:  
| 312 || [[#GetIpConfig]]
 
| 312 || [[#GetIpConfig]]
 
|-
 
|-
| 320 || [[#Leave]]
+
| 320 || [[#GetLinkLevel]]
 
|-
 
|-
 
| 328 || [[#AttachJoinEvent]]
 
| 328 || [[#AttachJoinEvent]]
Line 745: Line 760:     
=== AttachNetworkInterfaceStateChangeEvent ===
 
=== AttachNetworkInterfaceStateChangeEvent ===
No input, returns an output Event handle with EventClearMode=0.
+
No input. Returns an output Event handle with EventClearMode=0.
    
=== GetNetworkInterfaceLastError ===
 
=== GetNetworkInterfaceLastError ===
Line 751: Line 766:     
=== GetRole ===
 
=== GetRole ===
No input, returns an output u8.
+
No input. Returns an output u8.
    
=== GetAdvertiseData ===
 
=== GetAdvertiseData ===
Takes a type-0x22 output buffer, returns 2 output u16s.
+
Takes a type-0x22 output buffer. Returns two output u16s.
    
Validates that the [[#GetRole|role]] is value 2, then copies data from state into the output buffer. The first output u16 is the size used for the memcpy, the second u16 is the original size from state.
 
Validates that the [[#GetRole|role]] is value 2, then copies data from state into the output buffer. The first output u16 is the size used for the memcpy, the second u16 is the original size from state.
    
=== GetAdvertiseData2 ===
 
=== GetAdvertiseData2 ===
Takes a type-0x22 output buffer, returns 2 output u16s.
+
Takes a type-0x22 output buffer. Returns two output u16s.
    
This is identical to [[#GetAdvertiseData]] except this doesn't run the role validation.
 
This is identical to [[#GetAdvertiseData]] except this doesn't run the role validation.
Line 768: Line 783:  
Validates that the [[#GetRole|role]] is non-zero, then copies the struct from state into the output buffer.
 
Validates that the [[#GetRole|role]] is non-zero, then copies the struct from state into the output buffer.
   −
=== Join ===
+
=== GetGroupInfo2 ===
 
Takes a type-0x32 output buffer containing a [[#GroupInfo]] and a type-0x31 input buffer containing a [[#GroupInfo]].
 
Takes a type-0x32 output buffer containing a [[#GroupInfo]] and a type-0x31 input buffer containing a [[#GroupInfo]].
   Line 774: Line 789:     
=== GetGroupOwner ===
 
=== GetGroupOwner ===
No input, returns an output 0x80-bytes [[#NodeInfo_2|NodeInfo]].
+
No input. Returns an output [[#NodeInfo_2|NodeInfo]].
    
Validates that the [[#GetRole|role]] is non-zero, then copies the data from state to output.
 
Validates that the [[#GetRole|role]] is non-zero, then copies the data from state to output.
Line 785: Line 800:  
+0x20 is the <code>struct sockaddr</code> IP address, +0x40 is the <code>struct sockaddr</code> subnet-mask, +0x60 is the <code>struct sockaddr</code> gateway(?). The address for the last one is set to localhost.
 
+0x20 is the <code>struct sockaddr</code> IP address, +0x40 is the <code>struct sockaddr</code> subnet-mask, +0x60 is the <code>struct sockaddr</code> gateway(?). The address for the last one is set to localhost.
   −
=== Leave ===
+
=== GetLinkLevel ===
No input, returns an output u32.
+
No input. Returns an output u32.
    
=== AttachJoinEvent ===
 
=== AttachJoinEvent ===
No input, returns an output Event handle with EventClearMode=0.
+
No input. Returns an output Event handle with EventClearMode=0.
    
=== GetMembers ===
 
=== GetMembers ===
Takes a type-0x22 output buffer containing an array of [[#NodeInfo_2|NodeInfo]], returns an output s32 total_out.
+
Takes a type-0x22 output buffer containing an array of [[#NodeInfo_2|NodeInfo]]. Returns an output s32 '''TotalOut'''.
    
Validates that the [[#GetRole|role]] is value 1. Then any entries from state which are available are copied into the output array buffer, if there's space available. A maximum of 8 entries can be returned.
 
Validates that the [[#GetRole|role]] is value 1. Then any entries from state which are available are copied into the output array buffer, if there's space available. A maximum of 8 entries can be returned.
Line 799: Line 814:     
= lp2p:m =
 
= lp2p:m =
This is "nn::lp2p::detail::IMonitorServiceCreator".
+
This is "nn::lp2p::monitor::detail::ISfMonitorServiceCreator".
    
This was added with [9.1.0+].
 
This was added with [9.1.0+].
Line 811: Line 826:     
== CreateMonitorService ==
 
== CreateMonitorService ==
Takes a PID, a total of 0x10-bytes of input, and returns an [[#IMonitorService]].
+
Takes a PID-descriptor, a reserved input u64 and an input u64. Returns an [[#ISfMonitorService]].
   −
== IMonitorService ==
+
== ISfMonitorService ==
This is "nn::lp2p::detail::IMonitorService".
+
This is "nn::lp2p::monitor::detail::ISfMonitorService".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 824: Line 839:  
| 288 || [[#GetGroupInfo]]
 
| 288 || [[#GetGroupInfo]]
 
|-
 
|-
| 320 || [[#Leave]]
+
| 320 || [[#GetLinkLevel]]
 
|}
 
|}
   Line 830: Line 845:  
Returns 0.
 
Returns 0.
   −
= Ipv4Address =
+
= State =
This is "nn::ldn::Ipv4Address". This is a 0x4-byte struct with 4-byte alignment.
+
This is "nn::ldn::State".
 
  −
This is essentially the same as <code>struct in_addr</code>, except this is little-endian.
  −
 
  −
This is generally "169.254.XXX.{...}", where XXX is random per created network.
  −
 
  −
= SubnetMask =
  −
This is "nn::ldn::SubnetMask". This is a 0x4-byte struct with 4-byte alignment.
  −
 
  −
This is essentially the same as <code>struct in_addr</code>, except this is little-endian.
  −
 
  −
= 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.
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Value
! Size
+
! Description
! Description
   
|-
 
|-
| 0x0 || 0x1 || Length excluding NUL-terminator, must be 0x1-0x20.
+
| 0 || None
 
|-
 
|-
| 0x1 || 0x21 || SSID string including NUL-terminator, str[{above length}] must be 0.
+
| 1 || Initialized
|}
  −
 
  −
= NetworkInfo =
  −
This is "nn::ldn::NetworkInfo". This is a 0x480-byte struct. The data at +0x50 is another struct.
  −
 
  −
The fields listed as Reserved (besides the fields before +0x10) are cleared during the memset and are not written to again afterwards, with cmds which return NetworkInfo.
  −
 
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Offset
+
| 2 || AccessPoint
! Size
  −
! Description
   
|-
 
|-
| 0x0 || 0x8 || LocalCommunicationId
+
| 3 || AccessPointCreated
 
|-
 
|-
| 0x8 || 0x2 || Reserved
+
| 4 || Station
 
|-
 
|-
| 0xA || 0x2 || Arbitrary user data which can be used for filtering with [[#ScanFilter]].
+
| 5 || StationConnected
 
|-
 
|-
| 0xC || 0x4 || Reserved
+
| 6 || Error
 
|-
 
|-
| 0x10 || 0x10 || Last 0x10-bytes of [[#SecurityParameter]]. NetworkId which is used to generate/overwrite the [[#Ssid]]. With [[#Scan]]/[[#ScanPrivate]], this is only done after filtering when +0x4B is value 0x2. The converted Ssid is a 0x20-byte lowercase hex string version of the input NetworkId.
+
|}
 +
 
 +
= Ipv4Address =
 +
This is "nn::ldn::Ipv4Address". This is a 0x4-byte struct with 4-byte alignment.
 +
 
 +
This is essentially the same as <code>struct in_addr</code>, except this is little-endian.
 +
 
 +
This is generally "169.254.XXX.{...}", where XXX is random per created network.
 +
 
 +
= SubnetMask =
 +
This is "nn::ldn::SubnetMask". This is a 0x4-byte struct with 4-byte alignment.
 +
 
 +
This is essentially the same as <code>struct in_addr</code>, except this is little-endian.
 +
 
 +
= 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.
 +
 
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 0x20 || 0x6 || [[#MacAddress|MacAddress]]
+
! Offset
 +
! Size
 +
! Description
 
|-
 
|-
| 0x26 || 0x22 || [[#Ssid]]
+
| 0x0 || 0x1 || Length (excluding NUL-terminator, must be 0x1-0x20)
 +
|-
 +
| 0x1 || 0x21 || Raw (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.
 +
 
 +
The fields listed as Reserved (besides the fields before +0x10) are cleared during the memset and are not written to again afterwards, with cmds which return NetworkInfo.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x8 || LocalCommunicationId
 +
|-
 +
| 0x8 || 0x2 || Reserved
 +
|-
 +
| 0xA || 0x2 || Arbitrary user data which can be used for filtering with [[#ScanFilter]].
 +
|-
 +
| 0xC || 0x4 || Reserved
 +
|-
 +
| 0x10 || 0x10 || Last 0x10-bytes of [[#SecurityParameter]]. NetworkId which is used to generate/overwrite the [[#Ssid]]. With [[#Scan]]/[[#ScanPrivate]], this is only done after filtering when +0x4B is value 0x2. The converted Ssid is a 0x20-byte lowercase hex string version of the input NetworkId.
 +
|-
 +
| 0x20 || 0x6 || [[#MacAddress|MacAddress]]
 +
|-
 +
| 0x26 || 0x22 || [[#Ssid]]
 
|-
 
|-
 
| 0x48 || 0x2 || s16 NetworkChannel
 
| 0x48 || 0x2 || s16 NetworkChannel
Line 947: Line 986:  
| 0x4C || 0x10 || Cleared to zero for the tmp struct.
 
| 0x4C || 0x10 || Cleared to zero for the tmp struct.
 
|-
 
|-
| 0x5C || 0x4 || Flags. Masked with 0x37 for [[#Scan]], with [[#ScanPrivate]] this is masked with 0x3F.
+
| 0x5C || 0x4 || [[#ScanFilterFlag|Flag]] (masked with 0x37 for [[#Scan]], with [[#ScanPrivate]] this is masked with 0x3F)
 
|}
 
|}
   −
Flags:
+
= ScanFilterFlag =
 +
This is "nn::ldn::ScanFilterFlag".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Bit
+
! Value
! Description
+
! Description
 +
|-
 +
| 0x0 || None
 +
|-
 +
| 0x1 || LocalCommunicationId
 +
|-
 +
| 0x2 || SessionId
 +
|-
 +
| 0x4 || NetworkType
 
|-
 
|-
| 0 || When set, enables using ScanFilter+0.
+
| 0x8 || Bssid
 
|-
 
|-
| 1 || When set, enables using ScanFilter+0x10.
+
| 0x10 || Ssid
 
|-
 
|-
| 2 || When set, enables using ScanFilter+0x20.
+
| 0x20 || SceneId
 
|-
 
|-
| 3 || When set, enables using the ScanFilter [[#MacAddress|MacAddress]].
+
| 0x21 || IntentId
 
|-
 
|-
| 4 || When set, enables using the ScanFilter [[#Ssid]].
+
| 0x23 || NetworkId
 
|-
 
|-
| 5 || When set, enables using ScanFilter+0xA.
+
| 0x3F || All
 
|}
 
|}
   Line 1,024: Line 1,072:  
!  Description
 
!  Description
 
|-
 
|-
| 0 ||  
+
| 0 || Disabled
 
|-
 
|-
| 1 || This is the default.
+
| 1 || Enabled
 
|}
 
|}
   −
= SecurityConfig =
+
= BluetoothAudioDeviceConnectableMode =
This is "nn::ldn::SecurityConfig". This is a 0x44-byte struct with 2-byte alignment.
+
This is "nn::ldn::BluetoothAudioDeviceConnectableMode". This is an u32 enum.
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Value
! Size
+
! Description
! Description
  −
|-
  −
| 0x0 || 0x2 || Type, a default of value 1 can be used here. Overwritten by [[#CreateNetwork]]/[[#CreateNetworkPrivate]] and [[#Connect]]/[[#ConnectPrivate]]. The value used internally by these cmds must be 1-3.
   
|-
 
|-
| 0x2 || 0x2 || Data size. Must be 0x10-0x40.
+
| 0 || Disabled
 
|-
 
|-
| 0x4 || 0x40 || Data, used with key derivation.
+
| 1 || Enabled
 
|}
 
|}
   −
Type:
+
= SecurityMode =
* 1-2: Broadcast Action frame data is encrypted and is verified with SHA256.
+
This is "nn::ldn::SecurityMode". This is an u32 enum.
* 3: Broadcast Action frame data is plaintext and is verified with SHA256.
  −
 
  −
* 1: Data frames are encrypted.
  −
* 2-3: Data frames for normal data-transfer are plaintext - the network is Open.
  −
 
  −
= SecurityParameter =
  −
This is "nn::ldn::SecurityParameter". This is a 0x20-byte struct with 1-byte alignment.
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Value
! Size
+
! Description
! Description
+
|-
 +
| 0 || Any
 +
|-
 +
| 1 || Product
 
|-
 
|-
| 0x0 || 0x10 || Data, used with the same key derivation as [[#SecurityConfig]].
+
| 2 || Debug
 
|-
 
|-
| 0x10 || 0x10 || NetworkId, see [[#NetworkInfo]].
+
| 3 || SystemDebug
 
|}
 
|}
   −
= UserConfig =
+
= SecurityConfig =
This is "nn::ldn::UserConfig". This is a 0x30-byte struct with 1-byte alignment.
+
This is "nn::ldn::SecurityConfig". This is a 0x44-byte struct with 2-byte alignment.
 
  −
sdknso copies the input UserConfig to a tmp struct on stack, which is then used with the cmd.
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,077: Line 1,116:  
! Description
 
! Description
 
|-
 
|-
| 0x0 || 0x20 || NUL-terminated string for the user nickname.
+
| 0x0 || 0x2 || [[#SecurityMode|SecurityMode]] (overwritten by [[#CreateNetwork]]/[[#CreateNetworkPrivate]] and [[#Connect]]/[[#ConnectPrivate]], the value used internally by these cmds must be 1-3)
 
|-
 
|-
| 0x20 || 0x10 || Cleared to zero during the copy.
+
| 0x2 || 0x2 || PassphraseSize (must be 0x10-0x40)
 +
|-
 +
| 0x4 || 0x40 || Passphrase (used with key derivation)
 
|}
 
|}
   −
= AddressEntry =
+
Type:
This is "nn::ldn::AddressEntry". This is a 0xC-byte struct.
+
* 1-2: Broadcast Action frame data is encrypted and is verified with SHA256.
 +
* 3: Broadcast Action frame data is plaintext and is verified with SHA256.
 +
 
 +
* 1: Data frames are encrypted.
 +
* 2-3: Data frames for normal data-transfer are plaintext - the network is Open.
 +
 
 +
= SecurityParameter =
 +
This is "nn::ldn::SecurityParameter". This is a 0x20-byte struct with 1-byte alignment.
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,091: Line 1,139:  
! Description
 
! Description
 
|-
 
|-
| 0x0 || 0x4 || [[#Ipv4Address]]
+
| 0x0 || 0x10 || ServerRandom (used with the same key derivation as [[#SecurityConfig]])
 
|-
 
|-
| 0x4 || 0x6 || [[#MacAddress|MacAddress]]
+
| 0x10 || 0x10 || [[#SessionId|SessionId]]
|-
  −
| 0xA || 0x2 || Padding
   
|}
 
|}
   −
= AcceptPolicy =
+
= SessionId =
This is "nn::ldn::AcceptPolicy". This is an u8.
+
This is "nn::ldn::SessionId".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Value
+
! Offset
! Description
+
! Size
 +
! Description
 
|-
 
|-
| 0 || Allow all.
+
| 0x0 || 0x10 || Random
|-
  −
| 1 || Deny all.
  −
|-
  −
| 2 || Blacklist, addresses in the [[#AddAcceptFilterEntry|list]] are not allowed.
  −
|-
  −
| 3 || Whitelist, only addresses in the [[#AddAcceptFilterEntry|list]] are allowed.
   
|}
 
|}
   −
= MacAddress =
+
= UserConfig =
This is "nn::ldn::MacAddress". This is a 6-byte struct with 1-byte alignment.
+
This is "nn::ldn::UserConfig". This is a 0x30-byte struct with 1-byte alignment.
   −
= NodeInfo =
+
sdknso copies the input UserConfig to a tmp struct on stack, which is then used with the cmd.
This is "nn::ldn::NodeInfo".
  −
 
  −
The fields listed as Reserved are cleared during the memset and are not written to again afterwards, with cmds which return [[#NetworkInfo]].
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,129: Line 1,167:  
! Description
 
! Description
 
|-
 
|-
| 0x0 || 0x4 || [[#Ipv4Address]]
+
| 0x0 || 0x21 || UserName (NUL-terminated string for the user nickname)
 
|-
 
|-
| 0x4 || 0x6 || [[#MacAddress|MacAddress]]
+
| 0x21 || 0xF || Reserved (cleared to zero during the copy)
|-
+
|}
| 0xA || 0x1 || s8 ID / index
+
 
|-
+
= AddressEntry =
| 0xB || 0x1 || IsConnected
+
This is "nn::ldn::AddressEntry". This is a 0xC-byte struct.
 +
 
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 0xC || 0x20 || First 0x20-bytes of [[#UserConfig]].
+
! Offset
 +
! Size
 +
! Description
 
|-
 
|-
| 0x2C || 0x2 || Reserved
+
| 0x0 || 0x4 || [[#Ipv4Address]]
 
|-
 
|-
| 0x2E || 0x2 || s16 LocalCommunicationVersion
+
| 0x4 || 0x6 || [[#MacAddress|MacAddress]]
 
|-
 
|-
| 0x30 || 0x10 || Reserved
+
| 0xA || 0x2 || Reserved
 
|}
 
|}
   −
= ConnectOption =
+
= AcceptPolicy =
This is "nn::ldn::ConnectOption". This is an u32 bitmask.
+
This is "nn::ldn::AcceptPolicy". This is an u8.
   −
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.
+
{| class="wikitable" border="1"
 +
|-
 +
!  Value
 +
!  Description
 +
|-
 +
| 0 || AlwaysAccept
 +
|-
 +
| 1 || AlwaysReject
 +
|-
 +
| 2 || BlackList (addresses in the [[#AddAcceptFilterEntry|list]] are not allowed)
 +
|-
 +
| 3 || WhiteList (only addresses in the [[#AddAcceptFilterEntry|list]] are allowed)
 +
|}
   −
When bit0 here is set after using the above cmds, the sdknso funcs will use [[Error_Applet|ShowError]] with the returned Result if: (rc & 0x3FE1FF) == 0xE0CB.
+
= MacAddress =
 +
This is "nn::ldn::MacAddress". This is a 6-byte struct with 1-byte alignment.
   −
This must be <=0x1, besides this validation ConnectOption is ignored by [[#Connect]]/[[#ConnectPrivate]].
+
= NodeInfo =
 +
This is "nn::ldn::NodeInfo".
   −
= OperationMode =
+
The fields listed as Reserved are cleared during the memset and are not written to again afterwards, with cmds which return [[#NetworkInfo]].
This is "nn::ldn::OperationMode". This is an u32 enum.
  −
 
  −
This controls bit1 in the value passed to [[WLAN_services|wlan:lcl]] cmd0/cmd1: bit1 = OperationMode==1.
  −
 
  −
Value 1 seems to affect power (?) related fields in the beacon tags?
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Value
+
! Offset
! Description
+
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x4 || [[#Ipv4Address]]
 +
|-
 +
| 0x4 || 0x6 || [[#MacAddress|MacAddress]]
 
|-
 
|-
| 0 || This is the default.
+
| 0xA || 0x1 || NodeId
 
|-
 
|-
| 1 ||  
+
| 0xB || 0x1 || IsConnected
|}
+
|-
 
+
| 0xC || 0x21 || UserName (first 0x21-bytes of [[#UserConfig]])
= MacAddress =
+
|-
This is "nn::lp2p::MacAddress". Same as [[#MacAddress|MacAddress]].
+
| 0x2D || 0x1 || Reserved
 +
|-
 +
| 0x2E || 0x2 || LocalCommunicationVersion
 +
|-
 +
| 0x30 || 0x10 || Reserved
 +
|}
   −
= GroupId =
+
= ConnectOption =
This is "nn::lp2p::GroupId". This is a 6-byte struct with 1-byte alignment.
+
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 [[Error_Applet|ShowError]] with the returned Result if: (rc & 0x3FE1FF) == 0xE0CB.
   −
This is a WiFi BSSID.
+
This must be <=0x1, besides this validation ConnectOption is ignored by [[#Connect]]/[[#ConnectPrivate]].
   −
= NodeInfo =
+
= DisconnectReason =
This is "nn::lp2p::NodeInfo". This is a 0x80-byte struct.
+
This is "nn::ldn::DisconnectReason".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Value
! Size
+
! Description
! Description
   
|-
 
|-
| 0x0 || || <code>struct sockaddr</code> for the IP address.
+
| -1 || Unknown
 
|-
 
|-
| 0x24 || 0x6 || [[#MacAddress_2|MacAddress]]
+
| 0 || None
|}
+
|-
 +
| 1 || DisconnectedByUser
 +
|-
 +
| 2 || DisconnectedBySystem
 +
|-
 +
| 3 || DestroyedByUser
 +
|-
 +
| 4 || DestroyedBySystem
 +
|-
 +
| 5 || Rejected
 +
|-
 +
| 6 || SignalLost
 +
|}
   −
= GroupInfo =
+
= OperationMode =
This is "nn::lp2p::GroupInfo". This is a 0x200-byte struct.
+
This is "nn::ldn::OperationMode". This is an u32 enum.
   −
[[Mario Kart Live: Home Circuit|mklive]] sets the SSID to a string generated from random data.
+
This controls bit1 in the value passed to [[WLAN_services|wlan:lcl]] cmd0/cmd1: bit1 = OperationMode==1.
   −
[[#Scan_2|Scan]] only uses the following fields for the cmd input struct: SupportedPlatform/Priority, Frequency/Channel, and PresharedKeyBinarySize/PresharedKey.
+
Value 1 seems to affect power (?) related fields in the beacon tags?
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Value
! Size
+
! Description
! Description
   
|-
 
|-
| 0x0 || 0x10 || When zero, this is set to randomly-generated data. Used during key derivation.
+
| 0 || Stable
 
|-
 
|-
| 0x10 || 0x8 || LocalCommunicationId. When zero, the value from control.nacp is loaded. This is later validated by [[#Join]]/[[#CreateGroup]] the same way as the [[#NetworkConfig]] field. Used during key derivation.
+
| 1 || HighSpeed
|-
+
|}
| 0x18 || 0x6 || [[#GroupId]] ("GROUP ID  (BSSID)"). When zero, the default is used. The default should be used here: an error is thrown if the data here doesn't match the output from [[WLAN_services|wlan:lcl]] cmd2.
+
 
 +
= MacAddress =
 +
This is "nn::lp2p::MacAddress". Same as [[#MacAddress|MacAddress]].
 +
 
 +
= GroupId =
 +
This is "nn::lp2p::GroupId". This is a 6-byte struct with 1-byte alignment.
 +
 
 +
This is a WiFi BSSID.
 +
 
 +
= NodeInfo =
 +
This is "nn::lp2p::NodeInfo". This is a 0x80-byte struct.
 +
 
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 0x1E || 0x21 || ServiceName ("GROUP NAME (SSID)"). NUL-terminated string. See below.
+
! Offset
 +
! Size
 +
! Description
 
|-
 
|-
| 0x3F || 0x1 || s8 Flags count. Must be <=0x3F.
+
| 0x0 || || <code>struct sockaddr</code> for the IP address.
 
|-
 
|-
| 0x40 || 0x40 || Array of s8 with the above count. Each entry value must be <=0x3F. Each entry is an array index used to load a set of flags from a global array with the specified index. global_flags are also masked with flags loaded from here. User-processes use entryval=1 as the default, with [11.0.0+] entryval=0 can be used for standard WPA2-PSK (see +0x8A).
+
| 0x24 || 0x6 || [[#MacAddress_2|MacAddress]]
|-
+
|}
| 0x80 || 0x1 || SupportedPlatform. Must match value 1. 0 is PlatformIdNX, 1 is PlatformIdFuji.
+
 
|-
+
= GroupInfo =
| 0x81 || 0x1 || MemberCountMax. s8, Must be <=0x8. During group creation this is passed to [[WLAN_services|wlan:lcl]] cmd40, when this is value 0 a default of value 1 is passed. During group-creation when the below +0x88 field is not value 0x2, the passed [[BTM_services#SetWlanMode|WlanMode]] is <code>x81_field_val > 3</code>.
+
This is "nn::lp2p::GroupInfo". This is a 0x200-byte struct.
 +
 
 +
[[Mario Kart Live: Home Circuit|mklive]] sets the SSID to a string generated from random data.
 +
 
 +
[[#Scan_2|Scan]] only uses the following fields for the cmd input struct: SupportedPlatform/Priority, Frequency/Channel, and PresharedKeyBinarySize/PresharedKey.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x10 || Wrapped master key. When zero, set to randomly-generated data. This is decrypted with a "static AES key" and used to derive the 4 encryption keys for the session.
 +
|-
 +
| 0x10 || 0x8 || LocalCommunicationId. When zero, the value from control.nacp is loaded. This is later validated by [[#Join]]/[[#CreateGroup]] the same way as the [[#NetworkConfig]] field. Used during key derivation to derive keys B and D.
 +
|-
 +
| 0x18 || 0x6 || [[#GroupId]] ("GROUP ID  (BSSID)"). When zero, the default is used. The default should be used here: an error is thrown if the data here doesn't match the output from [[WLAN_services|wlan:lcl]] cmd2.
 +
|-
 +
| 0x1E || 0x21 || ServiceName ("GROUP NAME (SSID)"). NUL-terminated string. See below.
 +
|-
 +
| 0x3F || 0x1 || s8 Flags count. Must be <=0x3F.
 +
|-
 +
| 0x40 || 0x40 || Array of s8 with the above count. Each entry value must be <=0x3F. Each entry is an array index used to load a set of flags from a global array with the specified index. global_flags are also masked with flags loaded from here. User-processes use entryval=1 as the default, with [11.0.0+] entryval=0 can be used for standard WPA2-PSK (see +0x8A).
 +
|-
 +
| 0x80 || 0x1 || SupportedPlatform. Must match value 1. 0 is PlatformIdNX, 1 is PlatformIdRcd.
 +
|-
 +
| 0x81 || 0x1 || MemberCountMax. s8, Must be <=0x8. During group creation this is passed to [[WLAN_services|wlan:lcl]] cmd40, when this is value 0 a default of value 1 is passed. During group-creation when the below +0x88 field is not value 0x2, the passed [[BTM_services#SetWlanMode|WlanMode]] is <code>x81_field_val > 3</code>.
 
|-
 
|-
 
| 0x82 || 0x1 ||  
 
| 0x82 || 0x1 ||  
Line 1,247: Line 1,362:  
| 0x1C0 || 0x1 || PresharedKeyBinarySize. Must be 0x20 for PresharedKeyBinary. [11.0.0+] With WPA2-PSK, this must be value 1.
 
| 0x1C0 || 0x1 || PresharedKeyBinarySize. Must be 0x20 for PresharedKeyBinary. [11.0.0+] With WPA2-PSK, this must be value 1.
 
|-
 
|-
| 0x1C1 || 0x3F ([9.0.0-10.2.0] 0x20) || PresharedKey. Used during key derivation. [11.0.0+] With WPA2-PSK, this is the passphrase string (length must be at least 8).
+
| 0x1C1 || 0x3F ([9.0.0-10.2.0] 0x20) || PresharedKey. Used to derive encryption keys A and C. [11.0.0+] With WPA2-PSK, this is the passphrase string (length must be at least 8).
 
|}
 
|}
   Line 1,273: Line 1,388:  
** All string characters which were already written are summed same way as above. Then: <code>return character_lookup_table[sum % 0x2B];</code> (If the length passed to this function is 0, this will instead just return character_lookup_table[0])
 
** All string characters which were already written are summed same way as above. Then: <code>return character_lookup_table[sum % 0x2B];</code> (If the length passed to this function is 0, this will instead just return character_lookup_table[0])
 
*** character_lookup_table contains 0x2B entries: [V-A][k-a][5-0][Z-W].
 
*** character_lookup_table contains 0x2B entries: [V-A][k-a][5-0][Z-W].
  −
      
loaded_flags are first loaded from elsewhere, then masked with the above flags when available. loaded_flags are used when +0x8A is 0. global_flags are loaded from global data. These flags are only used with [[#CreateGroup]]/[[#Join]]. Flags (note that the following was updated with [11.0.0+], and differs from below):
 
loaded_flags are first loaded from elsewhere, then masked with the above flags when available. loaded_flags are used when +0x8A is 0. global_flags are loaded from global data. These flags are only used with [[#CreateGroup]]/[[#Join]]. Flags (note that the following was updated with [11.0.0+], and differs from below):
Line 1,537: Line 1,650:  
Communication uses sockets with standard Data frames and the above Action frames. Switch consoles presumably only use the Action frames to communicate with each other?
 
Communication uses sockets with standard Data frames and the above Action frames. Switch consoles presumably only use the Action frames to communicate with each other?
   −
The key derived by ldn-sysmodule is used directly as the static CCMP key for all data-frames (CCMP / MIC is standard). However, with [[#GroupInfo]]+0x8A value 3, standard WPA2-PSK is used instead.
+
Key A derived by ldn-sysmodule is used directly as the static CCMP key for all data-frames (CCMP / MIC is standard). However, with [[#GroupInfo]]+0x8A value 3, standard WPA2-PSK is used instead.
    
This uses infrastructure-mode (AccessPoint), and DHCP is used. The group-owner is the AccessPoint. Note that the probe response includes the same Nintendo tags included with the beacon. Once connected, the group-owner sends the same Epigram-vendor Action frame(s) described in [[#ldn]]. At this point socket communication can begin, including DHCP usage.
 
This uses infrastructure-mode (AccessPoint), and DHCP is used. The group-owner is the AccessPoint. Note that the probe response includes the same Nintendo tags included with the beacon. Once connected, the group-owner sends the same Epigram-vendor Action frame(s) described in [[#ldn]]. At this point socket communication can begin, including DHCP usage.
Line 1,548: Line 1,661:  
* "Renewal Time Value: (0s) 0 seconds"
 
* "Renewal Time Value: (0s) 0 seconds"
 
* "Rebinding Time Value: (0s) 0 seconds"
 
* "Rebinding Time Value: (0s) 0 seconds"
* "Interface MTU: 1500"
+
* "Interface MTU: 1500"
 +
 
 +
Note that the above options doesn't include "Domain Name Server" or "Router", the client device may fail to connect if it doesn't allow those DHCP options to be missing.
 +
 
 +
=== Beacon ===
 +
The SSID in the beacon can optionally be [[#GroupInfo|hidden]] (all-zero with the same length as the original SSID). The beacon contains two vendor-specific Nintendo information elements with OUI <code>00:22:aa</code>; each IE has a 2-byte ID following the OUI. These Nintendo IEs are not used when standard WPA2-PSK is being used.
 +
 
 +
The beacon is identical to ldn, except for the following (besides SSID length difference and the lp2p-only Nintendo tags):
 +
* "Tag: HT Capabilities (802.11n D1.10)": "HT Short GI for 20MHz" is set to "Not supported", for ldn it's "Supported".
 +
* "Tag: Vendor Specific: Microsoft Corp.: WMM/WME: Parameter Element" "Ac Parameters ACI 0": "CW Min: 15" for lp2p, "CW Min: 63" for ldn.
 +
 
 +
Note that during group creation the beacon may be missing the Nintendo IEs in some cases, since group creation didn't finish yet.
 +
 
 +
==== Nintendo IE 0 ====
 +
 
 +
The first Nintendo IE (ID 0x0600) contains the following fixed parameters:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x1 || Fixed 0x20; perhaps a version or other magic number.
 +
|-
 +
| 0x1 || 0x1 || [[#GroupInfo|SecurityType]]
 +
|-
 +
| 0x2 || 0x1 || [[#GroupInfo|StaticAesKeyIndex]]
 +
|-
 +
| 0x3 || 0x1 || Fixed zero; padding byte.
 +
|-
 +
| 0x4 || 0x8 || Big-endian (i.e. byte-reversed) version of [[#GroupInfo|LocalCommunicationId]]. This is the only context where LocalCommunicationId is reversed.
 +
|-
 +
| 0xC || 0x10 || Wrapped master key. Same as [[#GroupInfo]]+0x0.
 +
|-
 +
| 0x1C || 0x4 || If encryption is enabled, a randomly-generated nonce, else nothing. Appending 8 zero bytes to this yields the AES-GCM IV.
 +
|-
 +
| 0x20 || 0x10 || If encryption is enabled, the AES-GCM MAC tag, else nothing. All bytes prior to this (fixed 0x20 through nonce) are the additional authenticated data. All bytes after this are encrypted with key B.
 +
|}
 +
 
 +
After this, TLV tagged parameters occur. Each TLV tag is formatted as:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x1 || Tag type
 +
|-
 +
| 0x1 || 0x1 || Length
 +
|-
 +
| 0x2 || {above size} || Data for the tag
 +
|}
 +
 
 +
Known TLV tags:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Type
 +
! Size
 +
! Description
 +
|-
 +
| 0x1 || 0x2 || Additional network parameters: 0xAB 0xCD. A=[[#GroupInfo]]+0x82, B=[[#GroupInfo|MemberCountMax]], C=[[#GroupInfo|NetworkMode]], D=[[#GroupInfo|PerformanceRequirement]].
 +
|-
 +
| 0x2 || 0x8 || Flags: Bitwise-or of (1<<f) for each entry in [[#GroupInfo]]+0x40
 +
|}
   −
Note that the above options doesn't include "Domain Name Server" or "Router", the client device may fail to connect if it doesn't allow those DHCP options to be missing.
+
==== Nintendo IE 1 ====
   −
=== Beacon ===
+
The second Nintendo IE (ID 0x0601) contains only TLVs. If encryption is enabled, a 0x4-byte nonce and 0x10-byte AES-GCM tag are written first, as above, and the TLVs are encrypted. Key C is used.
The SSID in the beacon can optionally be [[#GroupInfo|hidden]] (all-zero with the same length as the original SSID). The beacon contains two vendor-specific Nintendo information elements with OUI <code>00:22:aa</code>; each IE has a 2-byte ID following the OUI. These Nintendo IEs are not used when standard WPA2-PSK is being used.
  −
 
  −
The beacon is identical to ldn, except for the following (besides SSID length difference and the lp2p-only Nintendo tags):
  −
* "Tag: Traffic Indication Map (TIM)": "DTIM count" for lp2p is 1, with ldn it's 0.
  −
* "Tag: HT Capabilities (802.11n D1.10)": "HT Short GI for 20MHz" is set to "Not supported", for ldn it's "Supported".
  −
* "Tag: Vendor Specific: Microsoft Corp.: WMM/WME: Parameter Element" "Ac Parameters ACI 0": "CW Min: 15" for lp2p, "CW Min: 63" for ldn.
  −
 
  −
Note that during group creation the beacon may be missing the Nintendo IEs in some cases, since group creation didn't finish yet.
  −
 
  −
The first Nintendo IE (ID 0x0600) contains the following data:
  −
 
  −
{| class="wikitable" border="1"
  −
|-
  −
! Offset
  −
! Size
  −
! Description
  −
|-
  −
| 0x0 || 0x2 || Usually 20 02?(Second byte depends on whether encryption is used?)
  −
|-
  −
| 0x2 || 0x2 || Usually 01 00 or 02 00?(varies)
  −
|-
  −
| 0x4 || 0x8 || Big-endian version of [[#GroupInfo]]+0x10.
  −
|-
  −
| 0xC || 0x10 || Same as [[#GroupInfo]]+0x0.
  −
|-
  −
| 0x1C || || Start of encrypted (and crypto-related) data if enabled. 0x22-bytes when encrypted, 0xE-bytes when plaintext.
  −
|}
     −
The second Nintendo IE (ID 0x0601) contains the following data (data is encrypted if enabled, there's also an additional 0x14-bytes when encrypted):
+
Known TLV tags:
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Type
 
! Size
 
! Size
 
! Description
 
! Description
 
|-
 
|-
| 0x0 || 0x1 || Plaintext: usually 21?
+
| 0x21 || Varies || AdvertiseData
|-
  −
| 0x1 || 0x1 || Plaintext: AdvertiseData size
  −
|-
  −
| 0x2 || {above size} || Plaintext: AdvertiseData
   
|}
 
|}