TMA services: Difference between revisions
Initial protocol stuff, HostIO, and Env as of ~1.0 |
mNo edit summary |
||
| Line 1,099: | Line 1,099: | ||
== DebugService == | == DebugService == | ||
Process debugger. | Process debugger. | ||
[[Category:Services]] | [[Category:Services]] | ||
Latest revision as of 08:00, 22 August 2026
TMA (Target Manager Agent) acts as a debugging sysmodule for development kits. This system module is loaded in retail units, but remains unused.
These services are inaccessible on retail units. However, all System Applets have permission to access them (see NPDM#Service_Access_Control).
TMA makes a few sets of services available. One set (the "htc" family), is aimed around managing Host/Target Connections. "htc" allows orchestrating the switch<->pc connection, "htc:tenv" allows retrieving information about the target's environment from the host, and "htcs" provides an interface for managing sockets on PC from the Switch. htcs is used primarily to host services on PC ports with actual management code running on Switch. The other service ("file_io") manages HostIO, a mechanism by which the Switch can read files present on the Host PC. When a host is connected, FS will attempt to read data via file_io when @Host:/ content paths are used, or when fsp-srv->OpenHostFileSystem() is used to open an IFileSystem to the Host PC. Nintendo's implementation only supports Windows, and FS will explicitly check for the presence of a "C:/" drive to detect this.
htc
This is "nn::tma::IHtcManager".
| Cmd | Name |
|---|---|
| 0 | GetEnvironmentVariable |
| 1 | GetEnvironmentVariableLength |
| 2 | BindHostConnectionEvent |
| 3 | BindHostDisconnectionEvent |
| 4 | BindHostConnectionEventForSystem |
| 5 | BindHostDisconnectionEventForSystem |
| 6 | [3.0.0+] GetBridgeIpAddress |
| 7 | [3.0.0+] GetBridgePort |
| 8 | [3.0.0+] SetCradleAttached |
| 9 | [4.0.0+] GetBridgeSubnetMask |
| 10 | [4.0.0+] GetBridgeMacAddress |
| 11 | [6.0.0+] GetWorkingDirectoryPath |
| 12 | [6.0.0+] GetWorkingDirectoryPathSize |
| 13 | [6.0.0+] RunOnHostStart |
| 14 | [9.0.0+] RunOnHostResults |
| 15 | [20.0.0+] SetBridgeIpAddress |
| 16 | [20.0.0+] SetBridgeSubnetMask |
| 17 | [20.0.0+] SetBridgePort |
| 18 | [20.0.0+] GetBridgeSerialNumber |
| 19 | [20.0.0+] GetBridgeFwVersion |
| 20 | [20.0.0+] ResetBridgeSettings |
| 21 | [19.0.0+] BeginUpdateBridge |
| 22 | [19.0.0+] ContinueUpdateBridge |
| 23 | [19.0.0+] EndUpdateBridge |
| 24 | [19.0.0+] GetBridgeType |
| 25 | [20.0.0+] GetBridgeDefaultGateway |
| 26 | [20.0.0+] SetBridgeDefaultGateway |
| 27 | [20.0.0+] GetBridgeDhcp |
| 28 | [20.0.0+] SetBridgeDhcp |
| 29 | [21.0.0+] GetBridgeProgramVersion |
htcs
This is "nn::tma::IHtcsManager".
| Cmd | Name |
|---|---|
| 0 | Socket |
| 1 | Close |
| 2 | Connect |
| 3 | Bind |
| 4 | Listen |
| 5 | Accept |
| 6 | Recv |
| 7 | Send |
| 8 | Shutdown |
| 9 | Fcntl |
| 10 | GetPeerNameAny |
| 11 | GetDefaultHostName |
| 12 | CreateSocketOld |
| 13 | CreateSocket |
| 100 | RegisterProcessId |
| 101 | MonitorManager |
ISocket
This is "nn::tma::ISocket".
| Cmd | Name |
|---|---|
| 0 | Close |
| 1 | Connect |
| 2 | Bind |
| 3 | Listen |
| 4 | Accept |
| 5 | Recv |
| 6 | Send |
| 7 | Shutdown |
| 8 | Fcntl |
htc:tenv
This is "nn::htc::tenv::IServiceManager".
| Cmd | Name |
|---|---|
| 0 | GetServiceInterface |
IService
This is "nn::htc::tenv::IService".
| Cmd | Name |
|---|---|
| 0 | GetVariable |
| 1 | GetVariableLength |
| 2 | WaitUntilVariableAvailable |
file_io
This is "nn::tma::IFileManager".
This service is not normally present on retail units.
| Cmd | Name |
|---|---|
| 0 | #OpenFile |
| 1 | #FileExists |
| 2 | #DeleteFile |
| 3 | #RenameFile |
| 4 | #GetIOType |
| 5 | #OpenDirectory |
| 6 | #DirectoryExists |
| 7 | #CreateDirectory |
| 8 | #DeleteDirectory |
| 9 | #RenameDirectory |
| 10 | #CreateFile |
| 11 | #GetFileTimeStamp |
| 12 | GetCaseSensitivePath |
OpenFile
Takes in an input X descriptor "Path" and a u32 "OpenMode", returns a #IFileAccessor interface.
FileExists
Takes in an input X descriptor "Path", and returns an output bool.
DeleteFile
Takes in an input X descriptor "Path".
RenameFile
Takes in an input X descriptor "SrcPath" and an input X descriptor "DstPath".
GetIOType
Takes in an input X descriptor "Path", returns an output int "EntryType".
OpenDirectory
Takes in an input X descriptor "Path" and a u32 "OpenMode", returns a #IDirectoryAccessor interface.
DirectoryExists
Takes in an input X descriptor "Path", and returns an output bool.
CreateDirectory
Takes in an input X descriptor "Path".
DeleteDirectory
Takes in an input X descriptor "Path" and an input bool "IsRecursive".
RenameDirectory
Takes in an input X descriptor "SrcPath" and an input X descriptor "DstPath".
CreateFile
Takes in an input X descriptor "Path" and an input s64 "Size".
GetFileTimeStamp
Takes in an input X descriptor "Path", and returns 3 output u64s ("CreatedTime", "AccessedTime", "ModifiedTime").
IFileAccessor
This is "nn::tma::IFileAccessor".
| Cmd | Name |
|---|---|
| 0 | ReadFile |
| 1 | WriteFile |
| 2 | GetFileSize |
| 3 | SetFileSize |
| 4 | FlushFile |
| 5 | SetPriorityForFile |
| 6 | GetPriorityForFile |
ReadFile
Takes in an input s64 "Offset", an input ReadOption, and a NonSecure B descriptor "OutBuffer", and returns a s64 "BytesRead".
WriteFile
Takes in an input s64 "Offset", an input WriteOption, and a NonSecure A descriptor "InBuffer".
GetFileSize
Takes no input, and returns a s64 "FileSize".
SetFileSize
Takes an s64 "FileSize".
FlushFile
Takes no input, returns no output.
SetPriorityForFile
Takes an input s32 "Priority".
GetPriorityForFile
Takes no input, returns an s32 "Priority".
IDirectoryAccessor
This is "nn::tma::IDirectoryAccessor".
| Cmd | Name |
|---|---|
| 0 | #GetEntryCount |
| 1 | #ReadDirectory |
| 2 | #SetPriorityForDirectory |
| 3 | #GetPriorityForDirectory |
GetEntryCount
Takes no input, returns an s64 "EntryCount".
ReadDirectory
Takes an input B descriptor "OutEntryBuffer", returns an s64 "NumEntriesRead"
SetPriorityForDirectory
Takes an input s32 "Priority".
GetPriorityForDirectory
Takes no input, returns an s32 "Priority".
Protocol (gen1)
PacketHeader
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x4 | #ServiceId |
| 0x4 | 0x4 | Task ID |
| 0x8 | 0x2 | #TaskType |
| 0xA | 0x1 | Initiate |
| 0xB | 0x1 | Padding |
| 0xC | 0x4 | Packet data size |
| 0x10 | 0x10 | Padding |
All packets sent and received by tma begin with this header, the data following the header is specific to each task type. Including the header, a packet can be up to 0xE020 bytes large
Initiate will be set to 1 on the first packet associated with an task/operation and cleared on any/all subsequent packets.
ServiceId
| Service ID | Service Name |
|---|---|
| 0x378D2DB4 | BenchmarkReportService |
| 0xBA2C1174 | BenchmarkService |
| 0xC191DAC9 | EnvService |
| 0x5FAE4D7E | HostIOService |
| 0xB04489F2 | HostDirectoryIOService |
| 0xB644D830 | HTCSService |
| 0xDDDE6636 | DebugService |
| 0x0955E925 | ControllerService |
This designates which tma "service" produced or will process a packet. These services are hosted over the host<->console interface, they are unrelated to hipc services.
The ServiceID values are derived from the Service Names strings using this hash:
uint tmipc::HashString(char *param_1)
{
uint uVar1;
long lVar2;
uint uVar3;
uVar1 = (uint)(byte)*param_1;
uVar3 = (uint)(byte)*param_1;
if (uVar3 == 0) {
lVar2 = 0;
}
else {
lVar2 = 0;
do {
uVar1 = uVar1 * 0xf4243 ^ uVar3;
uVar3 = (uint)(byte)param_1[lVar2 + 1];
lVar2 = lVar2 + 1;
} while (uVar3 != 0);
}
if (uVar1 != (uint)lVar2) {
return (uint)lVar2 ^ uVar1;
}
assertion_failure();
}TaskType
| Type | Name |
|---|---|
| 0x01 | OpenFile |
| 0x02 | GetFileSize |
| 0x03 | SetFileSize |
| 0x05 | FileExists |
| 0x06 | ReadFile |
| 0x07 | WriteFile |
| 0x08 | FlushFile |
| 0x09 | SetPriorityForFile |
| 0x0A | GetPriorityForFile |
| 0x0B | CloseFile |
| 0x0C | CreateFile |
| 0x0D | DeleteFile |
| 0x0E | RenameFile |
| 0x0F | GetIOType |
| 0x10 | DirectoryExists |
| 0x11 | OpenDirectory |
| 0x12 | GetDirectoryEntryCount |
| 0x13 | ReadDirectory |
| 0x14 | ReadDirectory |
| 0x15 | SetPriorityForDirectory |
| 0x16 | GetPriorityForDirectory |
| 0x17 | CreateDirectory |
| 0x18 | DeleteDirectory |
| 0x19 | RenameDirectory |
| 0x1A | Socket |
| 0x1B | Close |
| 0x1C | Connect |
| 0x1D | Bind |
| 0x1E | Listen |
| 0x1F | Accept |
| 0x20 | Recv |
| 0x21 | Send |
| 0x22 | Shutdown |
| 0x23 | Fcntl |
| 0x26 | Debug (Debugger) |
| 0x29 | GetVar (GetEnvironmentVariable) |
| 0x2B | GetFileTimeStamp |
Each task is associated with a specific Service, there seems to be no overlap in task type values between services.
EnvService
Creates tasks for requesting environment variables from host, it's used by #GetEnvironmentVariable and #GetEnvironmentVariableLength.
GetVar Task
This is used by #GetEnvironmentVariable and #GetEnvironmentVariableLength.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | variable | Environment variable name |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x4 | Result |
| 0x4 | variable | Null terminated environment variable string |
Up to <buffer size> bytes of the environment variable string are copied to a provided buffer and the length of string is counted. #GetEnvironmentVariableLength provides no buffer so the string is discarded completely, only the size is returned. #GetEnvironmentVariable provides its caller supplied hipc buffer.
HostIOService
Creates tasks for host file operations, it's used by all #file_io File commands and #GetIOType.
OpenFile Task
This is used by #OpenFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (always -1) |
| 0x8 | variable | File path |
| variable | 0x4 | Open mode |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
GetFileSize Task
This is used by #GetFileSize.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | File size |
SetFileSize Task
This is used by #SetFileSize.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x8 | File size |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
FileExists Task
This is used by #FileExists.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (always -1) |
| 0x8 | variable | File path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | File exists (cast to a bool) |
ReadFile Task
This is used by #ReadFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x8 | Read offset |
| 0x10 | 0x8 | Read size |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x4 | Sent size |
| 0x4 | 0x4 | Result |
| 0x8 | variable | <sent size> bytes |
tma will receive responses until <read size> bytes have been received, result>0 is received, or an empty packet (<sent size>=0) is received.
WriteFile Task
This is used by #WriteFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x8 | Read offset |
| 0x10 | 0x4 | Write size (of current packet) |
| 0x14 | 0x1 | End |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x4 | Total written size? (unused) |
| 0x4 | 0x4 | Result |
tma sends write requests containing up to 0xdfdf bytes of data until until all data has been sent. The last request will have End=1, prior requests will have End=0.
FlushFile Task
This is used by #FlushFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
SetPriorityForFile Task
This is used by #SetPriorityForFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Priority |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
GetPriorityForFile Task
This is used by #GetPriorityForFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Priority (cast to a u32/s32) |
CloseFile Task
This is sent when an #IFileAccessor session is closed. The result value is discarded.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
CreateFile Task
This is used by #CreateFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (always -1) |
| 0x8 | variable | File path |
| variable | 0x8 | File size |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
DeleteFile Task
This is used by #DeleteFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (always -1) |
| 0x8 | variable | File path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
RenameFile Task
This is used by #RenameFile.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (always -1) |
| 0x8 | variable | Source file path |
| variable | variable | Dest file path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
GetIOType Task
This is used by #GetIOType.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (always -1) |
| 0x8 | variable | File path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Entry type (cast to a u32/DirectoryEntryType) |
GetFileTimeStamp Task
This is used by #GetFileTimeStamp.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (always -1) |
| 0x8 | variable | File path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | File descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | CreatedTime |
| 0x14 | 0x8 | AccessTime |
| 0x2C | 0x8 | ModifiedTime |
HostDirectoryIOService
Creates tasks for host directory operations, it's used by all #file_io Directory commands.
DirectoryExists Task
This is used by #DirectoryExists.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (always -1) |
| 0x8 | variable | Directory path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Directory exists (cast to a bool) |
OpenDirectory Task
This is used by #OpenDirectory.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (always -1) |
| 0x8 | variable | Directory path |
| variable | 0x8 | Tag |
| variable | 0x4 | Open mode |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
| 0x24 | 0x8 | Tag (must be the same as Tag in request) |
GetDirectoryEntryCount Task
This is used by #GetDirectoryEntryCount.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Entry count |
ReadDirectory Task
This is used by #ReadDirectory.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x4 | Max out entry count |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x4 | Result |
| 0x8 | 0x1 | Entry type |
| 0x9 | variable | Entry path (up to FS_MAX_PATH chars) |
| variable | 0x8 | Entry size |
tma receives response packets until result>0 or it's received <max out entry count> entries. Entries with an empty path are ignored but still count toward <max out count>.
Response packets are converted to a Filesystem_services#DirectoryEntry. The path and size are copied directly and type is flipped (0->1 (File), 1->0 (Directory))
CloseDirectory Task
This is used when an #IDirectoryAccessor session is closed. The result value is discarded.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
SetPriorityForDirectory Task
This is used by #SetPriorityForDirectory.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x8 | Priority |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
GetPriorityForDirectory Task
This is used by #GetPriorityForDirectory.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Priority |
CreateDirectory Task
This is used by #CreateDirectory.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (always -1) |
| 0x8 | variable | Directory path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
DeleteDirectory Task
This is used by #DeleteDirectory.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (always -1) |
| 0x8 | variable | Directory path |
| variable | 0x1 | Is recursive (0=not, 1=recursive) |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
RenameDirectory Task
This is used by #RenameDirectory.
Console request:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (always -1) |
| 0x8 | variable | Src path |
| variable | variable | Dst path |
Host response:
| Offset | Size | Description |
|---|---|---|
| 0x0 | 0x8 | Directory descriptor? (unused) |
| 0x8 | 0x4 | Result |
| 0xC | 0x8 | Unused |
HTCSService
Creates tasks for htcs operations, it's used by all #htcs commands.
DebugService
Process debugger.