Migration services: Difference between revisions

No edit summary
No edit summary
 
(3 intermediate revisions by the same user not shown)
Line 169: Line 169:
| 0 || GetUid
| 0 || GetUid
|-
|-
| 1 || GetServerProfile
| 1 || [[#GetServerProfile|GetServerProfile]]
|-
|-
| 100 || PrepareAsync
| 100 || PrepareAsync
Line 191: Line 191:
| 500 || Abort
| 500 || Abort
|}
|}
=== GetServerProfile ===
Takes a type-0x1A output buffer containing a [[#ServerProfile|ServerProfile]].


== IClient ==
== IClient ==
Line 289: Line 292:
| 1 || [7.0.0-19.0.1] GetApplicationId
| 1 || [7.0.0-19.0.1] GetApplicationId
|-
|-
| 2 || GetServerProfile
| 2 || [[#GetServerProfile_2|GetServerProfile]]
|-
|-
| 3 || [17.0.0+] ListApplicationIds
| 3 || [17.0.0+] ListApplicationIds
Line 299: Line 302:
| 102 || [20.0.0+]
| 102 || [20.0.0+]
|-
|-
| 200 || WaitConnectionAsync
| 200 || [[#WaitConnectionAsync|WaitConnectionAsync]]
|-
|-
| 201 || GetClientProfile
| 201 || GetClientProfile
Line 321: Line 324:
| 999 || [8.0.0+] DebugWaitStateSynchronizationFinalizedAsync
| 999 || [8.0.0+] DebugWaitStateSynchronizationFinalizedAsync
|}
|}
=== GetServerProfile ===
Takes a type-0x1A output buffer containing a [[#ServerProfile|ServerProfile]].


=== PrepareAsync ===
=== PrepareAsync ===
Line 328: Line 334:


[20.0.0+] The above policy functionality is no longer present. This now eventually uses network request [[Network|transfer_events/start]].
[20.0.0+] The above policy functionality is no longer present. This now eventually uses network request [[Network|transfer_events/start]].
=== WaitConnectionAsync ===
No input, returns an [[#IAsyncContext|IAsyncContext]].
The async task does the following:
* ...
* Initializes the data used for the AdvertiseData.
* Calls a func which:
** Calls a func which handles [[LDN_services|ldn]] initialization and network creation. SetProtocol is also used with a value from state.
** Calls a func which:
*** Handles setup for the server socket.
*** Uses [[LDN_services|SetAdvertiseData]] with the above AdvertiseData buffer.
*** Waits for a ldn Node to connect, with timeout etc handling.
*** Then [[LDN_services|SetStationAcceptPolicy]] is used with value 3 (WhiteList), and [[LDN_services|AddAcceptFilterEntry]] is used.
** Calls a func which waits for a socket connection (with timeout etc), and handles socket setup for it.
** Uses [[LDN_services|SetAdvertiseData]] with buf/size = 0 (empty AdvertiseData).
** Uses [[LDN_services|SetStationAcceptPolicy]] with value 1 (AlwaysReject).
** Enters a loop waiting for a state field to become value 0x3. Two funcs are called repeatedly in this loop, with cleanup and return being handled if these return error.
*** The first func receives socket data and handles it. The second func calls a func to get data for sending, then sends the socket data. Both have timeout etc handling.
** Updates state and returns 0.
* ...


=== Cmd510 ===
=== Cmd510 ===
Line 407: Line 434:
! Cmd || Name
! Cmd || Name
|-
|-
| 0 ||  
| 0 || [[#GetServerProfile_3|GetServerProfile]]
|-
|-
| 10 ||  
| 10 ||  
Line 445: Line 472:
| 900 ||  
| 900 ||  
|}
|}
=== GetServerProfile ===
Unofficial name.
Takes a type-0x1A output buffer containing a [[#ServerProfile|ServerProfile]].


=== Cmd230 ===
=== Cmd230 ===
Line 636: Line 668:
= ServerProfile =
= ServerProfile =
This is a 0x100-byte struct.
This is a 0x100-byte struct.
It's unknown whether user/savedata/device use the same struct (size is the same for these).
Any data here which is initialized is usually zeros?
= Protocol =
Once connected with [[LDN_services|ldn]], the client node connects to the server with TCP port 441.
The first byte of messages is the message-type.
Messages are encrypted with AES-128-GCM. The key is derived during the initial message-handling loop (WaitConnectionAsync).


= AdvertiseData =
= AdvertiseData =
Line 642: Line 685:
The global constant used with hashing below is the same regardless of the AdvertiseData.
The global constant used with hashing below is the same regardless of the AdvertiseData.


Later the server also sets the AdvertiseData to {0x10-byte data}.
Later the server also sets the AdvertiseData to {0x10-byte Uuid previously used below}.
 
The Uuid used below is generated with <code>nn::util::GenerateUuid</code>.


== user ==
== user ==
Line 695: Line 740:
! Offset || Size || Description
! Offset || Size || Description
|-
|-
| 0x0 || 0x10 ||  
| 0x0 || 0x10 || Uuid
|-
|-
| 0x10 || 0x8 || AccountId
| 0x10 || 0x8 || AccountId
Line 711: Line 756:


The hash is calculated by using SHA256-update with each field separately, followed by global constant:
The hash is calculated by using SHA256-update with each field separately, followed by global constant:
* +0x0 size 0x10
* Uuid
* AccountId
* AccountId
* ApplicationId
* ApplicationId
Line 725: Line 770:
! Offset || Size || Description
! Offset || Size || Description
|-
|-
| 0x0 || 0x10 ||  
| 0x0 || 0x10 || Uuid
|-
|-
| 0x10 || 0x40 (0x8*0x8) || Array of u64s with the below count.
| 0x10 || 0x40 (0x8*0x8) || Array of u64s with the below count.
Line 739: Line 784:


The hash is calculated by using SHA256-update with each field separately, followed by global constant:
The hash is calculated by using SHA256-update with each field separately, followed by global constant:
* +0x0 size 0x10-bytes
* Uuid
* +0x10 size 0x40-bytes
* +0x10 size 0x40-bytes
* +0x50 size 0x4-bytes
* +0x50 size 0x4-bytes