Services are an abstraction of ports and are the commonly used way of inter-process communication outside of the kernel. While handles of regular ports are retrieved from SVC(svcConnectToPort), service handles are retrieved through the port srv: ("service manager").
When a service is registered, svcCreatePort is used without a port-name. This means that the port is inaccessible via the port SVCs outside of sm-module. See below for getting a session handle for sending commands to services.
Processes with PID less than or equal to the number of NATIVE_FIRM built-in modules (fs, sm, pm, pxi, ldr) have access to all services.
Service Manager Port "srv:"
|0x00020000||GetProcSemaphore() (the handle from this gets signaled when notifications for this process gets triggered)|
|0x00030100||RegisterService(8-byte servicename, u32 strlen, u32 max_sessions)|
|0x000400C0||UnregisterService(8-byte servicename, u32 strlen)|
|0x00050100||GetServiceSession(8-byte servicename, u32 strlen, u32 flags)
Flags bit0: if not set, return port-handle instead of session-handle(from svcCreateSessionToPort) when session-handle unavailable (max sessions/timeout?).
|0x000600C2||RegisterPort(8-byte servicename, u32 strlen, Handle client_port)|
|0x000700C0||UnregisterPort(8-byte servicename, u32 strlen)|
|0x00080100||GetPort(8-byte servicename, u32 strlen, u32 flags).
Flags bit0: return 0 instead of port handle if port was found.
|0x00090040||Subscribe(u32 notification_id). This enables the specified notificationID for the current process.|
|0x000A0040||Unsubscribe(u32 notification_id). This disables the specified notificationID for the current process.|
|0x000B0000||ReceiveNotification() This returns the notificationID which was triggered, if any(see GetProcSemaphore).|
|0x000C0080||PublishToSubscriber(u32 notification_id, u32 flag). This fires an notification. Bit0: only fire if not already fired, bit1: return error if error happens, else it always returns 0.|
|0x000D0040||This can fire notificationIDs and return the number of fired notificationID|
|0x000E00C0||HasAccessToService(8-byte servicename, u32 strlen). Returns 1 if your process has access to the service.|
Service Manager Process-Manager Port "srv:pm"
|Command Header, prior to 7.0.0-13||Description|
|0x04030082||RegisterProcess (u32 procid, u32 wordsz, ((wordsz<<16) | 2), serviceaccesscontrol*).|
|0x04040040||UnregisterProcess (u32 procid).|
The Register command registers a process with the service-manager, which includes registering the serviceaccesscontrol for the process which normally originates from the exheader.
Prior to to 7.0.0-13, the commands listed for "srv:" were also accessible under this port with the same command-headers. Starting with 7.0.0-13, the "srv:pm" port was changed to a service. With this change, commandIDs for these commands were changed. "srv:pm" was originally vulnerable, this was fixed with 7.0.0-13, see here. Originally any process could use "srv:pm", however starting with 7.0.0-13 only the built-in NATIVE_FIRM sysmodules have access to it. The only system title which uses "srv:pm" is the Process Manager.
|0x100||This indicates that all processes must terminate: power-off, reboot, or FIRM-launch.|
|0x108||error at boot?|
|0x202||POWER button pressed|
|0x204||This indicates that the HOME button was pressed.|
|0x205||HOME button pressed|
|0x207||SD card inserted|
|0x208||Game cartridge inserted|
|0x209||SD card removed|
|0x20A||Game cartridge removed|
|0x20B||Game cartridge inserted or removed|