Migration services
Migration is a sysmodule designed for handling the Switch-to-Switch transfer system introduced in firmware 4.0.0.
With newer system-versions this sysmodule is only running when qlaunch is using migration from the relevant transfer menus (see ActivateMigrationService/DeactivateMigrationService).
mig:usr
This is "nn::migration::user::IService"
Cmd | Name |
---|---|
0 | [19.0.0+] |
1 | [20.0.0+] |
2 | [20.0.0+] |
10 | [7.0.0-19.0.1] TryGetLastUserMigrationInfo ([4.0.0-6.2.0] TryGetLastMigrationInfo) |
11 | [20.0.0+] |
100 | [7.0.0+] CreateUserMigrationServer ([4.0.0-6.2.0] CreateServer) |
101 | [7.0.0+] ResumeUserMigrationServer ([4.0.0-6.2.0] ResumeServer) |
200 | [7.0.0+] CreateUserMigrationClient ([4.0.0-6.2.0] CreateClient) |
201 | [7.0.0+] ResumeUserMigrationClient ([4.0.0-6.2.0] ResumeClient) |
1001 | [8.0.0+] GetSaveDataMigrationPolicyInfoAsync |
1010 | [7.0.0+] TryGetLastSaveDataMigrationInfo |
1100 | [7.0.0-19.0.1] CreateSaveDataMigrationServer |
1101 | [7.0.0+] ResumeSaveDataMigrationServer |
1110 | [17.0.0+] |
1200 | [7.0.0+] CreateSaveDataMigrationClient |
1201 | [7.0.0+] ResumeSaveDataMigrationClient |
2001 | [20.0.0+] |
2010 | [20.0.0+] |
2100 | [20.0.0+] |
2110 | [20.0.0+] |
2200 | [20.0.0+] |
2210 | [20.0.0+] |
2220 | [20.0.0+] |
2230 | [20.0.0+] |
2231 | [20.0.0+] |
2232 | [20.0.0+] |
2233 | [20.0.0+] |
2234 | [20.0.0+] |
2250 | [20.0.0+] |
2260 | [20.0.0+] |
2270 | [20.0.0+] |
2280 | [20.0.0+] |
2300 | [20.0.0+] |
2310 | [20.0.0+] |
2400 | [20.0.0+] |
2420 | [20.0.0+] |
CreateUserMigrationServer
Takes a total of 0x18-bytes of input, a type-0x19 input buffer, a TransferMemory handle, returns an #IServer.
ResumeUserMigrationServer
Takes an input u32, a TransferMemory handle, returns an #IServer.
CreateUserMigrationClient
Takes an input u32, a type-0x19 input buffer, a TransferMemory handle, returns an #IClient.
ResumeUserMigrationClient
Takes an input u32, a TransferMemory handle, returns an #IClient.
GetSaveDataMigrationPolicyInfoAsync
Takes an ApplicationId, returns an #IAsyncSaveDataMigrationPolicyInfoContext.
This is used by qlaunch before the actual savedata transfer is started.
This starts a network request for save_data_migration_policy.
[20.0.0+] This was stubbed. The network request is no longer done and the various IAsyncSaveDataMigrationPolicyInfoContext cmds just return success (besides GetSystemEvent). GetSaveDataMigrationPolicyInfo just returns the data which was set during object creation.
CreateSaveDataMigrationServer
Takes a total of 0x20-bytes of input, a type-0x19 input buffer, a TransferMemory handle, returns an IServer.
ResumeSaveDataMigrationServer
Takes an input u32, a TransferMemory handle, returns an IServer.
Cmd1110
Takes a total of 0x18-bytes of input, a type-0x19 input buffer, a type-0x5 input buffer containing an array of u64s, and a TransferMemory handle. Returns an IServer.
This is identical to CreateSaveDataMigrationServer except the u64-array is passed directly instead of from a single input u64.
CreateSaveDataMigrationClient
Takes an input u32, a type-0x19 input buffer, a TransferMemory handle, returns an IClient.
ResumeSaveDataMigrationClient
Takes an input u32, a TransferMemory handle, returns an IClient.
Cmd2100
Takes 4-bytes of input, a type-0x19 input buffer containing a 0x100-byte struct, a handle. Returns an IServer.
Cmd2110
Takes 4-bytes of input, a handle. Returns an IServer.
Cmd2200
Takes 4-bytes of input, a type-0x19 input buffer containing a 0x100-byte struct, a handle. Returns an IClient.
On NX this just calls a logging func and returns an error.
Cmd2210
Takes 4-bytes of input, a handle. Returns an IClient.
On NX this just calls a logging func and returns an error.
Cmd2250
Takes a total of 0x18-bytes of input, a handle. Returns an IUnknown.
Cmd2260
Takes 4-bytes of input, a handle. Returns an IUnknown.
Cmd2280
Takes an input u64, returns an #IAsyncContext.
This starts a network request for transfer_events/%lld/rollback.
Cmd2300
Takes a total of 0x18-bytes of input, a handle. Returns an IUploader.
Cmd2310
Takes 4-bytes of input, a handle. Returns an IUploader.
Cmd2400
Takes a total of 0x10-bytes of input, a handle. Returns an IDownloader.
Cmd2420
Takes 4-bytes of input, a handle. Returns an IDownloader.
IServer
This is "nn::migration::user::IServer"
Cmd | Name |
---|---|
0 | GetUid |
1 | GetServerProfile |
100 | PrepareAsync |
101 | GetConnectionRequirement |
102 | [20.0.0+] |
200 | WaitConnectionAsync |
201 | GetClientProfile |
202 | AcceptConnectionAsync |
203 | DeclineConnectionAsync |
300 | ProcessTransferAsync |
400 | CompleteAsync |
500 | Abort |
IClient
This is "nn::migration::user::IClient"
Cmd | Name |
---|---|
0 | GetClientProfile |
10 | CreateLoginSession |
11 | GetNetworkServiceAccountId |
12 | GetUserNickname |
13 | GetUserProfileImage |
100 | PrepareAsync |
101 | GetConnectionRequirement |
102 | [20.0.0+] |
200 | ScanServersAsync |
201 | ListServers |
210 | ConnectByServerIdAsync |
300 | GetStorageShortfall |
301 | GetTotalTransferInfo |
302 | GetImmigrantUid |
310 | GetCurrentTransferInfo |
311 | GetCurrentRelatedApplications |
320 | TransferNextAsync |
350 | SuspendAsync |
400 | CompleteAsync |
500 | Abort |
999 | DebugSynchronizeStateInFinalizationAsync |
IAsyncContext
This is "nn::migration::detail::IAsyncContext".
Cmd | Name |
---|---|
0 | GetSystemEvent |
1 | Cancel |
2 | HasDone |
3 | GetResult |
IAsyncSaveDataMigrationPolicyInfoContext
This is "nn::migration::detail::IAsyncSaveDataMigrationPolicyInfoContext".
Cmd | Name |
---|---|
0 | GetSystemEvent |
1 | Cancel |
2 | HasDone |
3 | GetResult |
100 | GetSaveDataMigrationPolicyInfo |
IServer
This is "nn::migration::savedata::IServer".
This was added with [7.0.0+].
Cmd | Name |
---|---|
0 | GetUid |
1 | [7.0.0-19.0.1] GetApplicationId |
2 | GetServerProfile |
3 | [17.0.0+] ListApplicationIds |
100 | PrepareAsync |
101 | GetConnectionRequirement |
102 | [20.0.0+] |
200 | WaitConnectionAsync |
201 | GetClientProfile |
202 | [20.0.0+] |
203 | [20.0.0+] |
210 | [8.0.0+] WaitAcceptanceAsync |
300 | ProcessTransferAsync |
400 | CompleteAsync |
500 | [7.0.0-19.0.1] Abort |
510 | [19.0.0+] |
998 | [8.0.0+] DebugTryGetState |
999 | [8.0.0+] DebugWaitStateSynchronizationFinalizedAsync |
PrepareAsync
No input, returns an IAsyncContext.
Besides various other functionality, the async task also uses functionality similar to GetSaveDataMigrationPolicyInfoAsync, throwing an error if needed.
[20.0.0+] The above policy functionality is no longer present. This now eventually uses network request transfer_events/start.
Cmd510
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/%lld/abort_transfer.
IClient
This is "nn::migration::savedata::IClient".
This was added with [7.0.0+].
Cmd | Name |
---|---|
0 | GetClientProfile |
100 | GetConnectionRequirement |
101 | [20.0.0+] |
200 | ScanServersAsync |
201 | ListServers |
210 | ConnectByServerIdAsync |
220 | [8.0.0+] AcceptAsync |
221 | [8.0.0+] DeclineAsync |
300 | GetStorageShortfall |
301 | GetTotalTransferInfo |
302 | GetImmigrantUid |
303 | GetApplicationId |
304 | [17.0.0+] ListApplicationIds |
310 | GetCurrentTransferInfo |
320 | TransferNextAsync |
350 | SuspendAsync |
400 | CompleteAsync |
500 | [7.0.0-19.0.1] Abort |
510 | [19.0.0+] |
996 | [8.0.0+] DebugTryGetState |
997 | [8.0.0+] DebugSynchronizeStateInFinalization0Async |
998 | [8.0.0+] DebugSynchronizeStateInFinalization1Async |
999 | DebugSynchronizeStateFinalizedAsync |
ListServers
[20.0.0+] The struct size is now 0x130-bytes instead of 0x128-bytes.
CompleteAsync
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/%lld/finish_transfer.
IServer
This is "nn::migration::device::IServer".
This was added with [20.0.0+].
Cmd | Name |
---|---|
0 | |
10 | |
20 | |
21 | |
30 | |
40 | |
50 | |
100 | |
110 | |
111 | |
120 | |
130 | |
200 | |
230 | |
290 | |
300 | |
400 | |
510 | |
900 |
Cmd230
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/start.
Cmd510
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/%lld/abort_transfer.
IClient
This is "nn::migration::device::IClient".
This was added with [20.0.0+].
Cmd | Name |
---|---|
10 | |
20 | |
30 | |
100 | |
110 | |
111 | |
200 | |
210 | |
220 | |
230 | |
240 | |
250 | |
290 | |
300 | |
310 | |
320 | |
330 | |
340 | |
400 | |
500 | |
610 | |
700 | |
710 | |
720 |
IUnknown
This was added with [20.0.0+].
Cmd | Name |
---|---|
0 | |
1 | |
2 | |
3 | |
100 | |
110 |
IUploader
This is "nn::migration::device::IUploader".
This was added with [20.0.0+].
Cmd | Name |
---|---|
90 | |
100 | |
310 | |
320 | |
330 | |
340 | |
350 | |
400 | |
500 | |
610 | |
900 |
Cmd100
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/start.
Cmd500
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/%lld/finish_upload.
Cmd610
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/%lld/abort_upload.
Cmd900
Takes a total of 4-bytes of input, returns an IAsyncContext.
Besides other functionality, this async task may call the same network-request func as #Cmd500.
IDownloader
This is "nn::migration::device::IDownloader".
This was added with [20.0.0+].
Cmd | Name |
---|---|
10 | |
20 | |
30 | |
90 | |
100 | |
300 | |
310 | |
320 | |
330 | |
400 | |
500 | |
610 | |
620 | |
900 |
Cmd500
No input, returns an IAsyncContext.
Besides other functionality, this async task uses network request transfer_events/%lld/finish_download.
Cmd900
Takes a total of 4-bytes of input, returns an IAsyncContext.
Besides other functionality, this async task may call the same network-request func as Cmd500.
ServerProfile
This is a 0x100-byte struct.
AdvertiseData
These sections document the initial AdvertiseData used by migration.
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}.
user
Used by nn::migration::user::*.
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | AccountId |
0x8 | 0x58 | Unused |
0x60 | 0x100 | ServerProfile |
0x160 | 0x20 | SHA256 hash |
The hash is calculated by using SHA256-update with each field separately, followed by global constant:
- AccountId
- ServerProfile
- 0x100-byte global constant
savedata
Used by nn::migration::savedata::*.
Offset | Size | Description |
---|---|---|
0x0 | 0x8 | AccountId |
0x8 | 0x8 | ApplicationId |
0x10 | 0x50 | Unused |
0x60 | 0x100 | ServerProfile |
0x160 | 0x20 | SHA256 hash |
The hash is calculated by using SHA256-update with each field separately, followed by global constant:
- AccountId
- ApplicationId
- ServerProfile
- 0x100-bytes global constant
[20.0.0+]:
Offset | Size | Description |
---|---|---|
0x0 | 0x10 | |
0x10 | 0x8 | AccountId |
0x18 | 0x8 | ApplicationId |
0x20 | 0x4 | ProductModel |
0x24 | 0x4 | Padding |
0x28 | 0x100 | ServerProfile |
0x128 | 0x20 | SHA256 hash |
The hash is calculated by using SHA256-update with each field separately, followed by global constant:
- +0x0 size 0x10
- AccountId
- ApplicationId
- ProductModel
- ServerProfile
- 0x100-bytes global constant
device
Used by nn::migration::device::*.
Offset | Size | Description |
---|---|---|
0x0 | 0x10 | |
0x10 | 0x40 (0x8*0x8) | Array of u64s with the below count. |
0x50 | 0x4 | Count for the above array. |
0x54 | 0xC | Unused |
0x60 | 0x100 | ServerProfile |
0x160 | 0x20 | SHA256 hash |
The hash is calculated by using SHA256-update with each field separately, followed by global constant:
- +0x0 size 0x10-bytes
- +0x10 size 0x40-bytes
- +0x50 size 0x4-bytes
- ServerProfile
- 0x100-bytes global constant
Notes
Savedata transfer ("nn::migration::savedata::IServer"/"nn::migration::savedata::IClient") requires that accounts are linked to the same network-account. acc:su IManagerForSystemService GetAccountId is used here. The server stores this Id into state, and also stores it in the ldn AdvertiseData. The client also verifies the Id in AdvertiseData against the Id from GetAccountId for the account(s) being used, during ScanServersAsync.
[20.0.0+] ISaveDataTransferManagerWithDivision is now used instead of ISaveDataTransferManager. Besides SetKeySeedPackage being used now as needed, SetLocalKeySeedPackage is now used by the relevant functionality in IClient TransferNextAsync.
[S2] qlaunch now has an additional menu once send-savedata is selected, for selecting whether to send to Nintendo Switch or Nintendo Switch 2. If Switch 2 is selected, and there's a S1 receiving, the S2 will display a message regarding wrong target system. The receiving system also displays an error. Note that savedata for S2-only applications is only listed with the dest-S2 option (S1-applications are also listed).