libnx/nx/include/switch/services/sm.h

158 lines
4.1 KiB
C

/**
* @file sm.h
* @brief Service manager (sm) IPC wrapper.
* @author plutoo
* @author yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../kernel/svc.h"
#include "../ipc.h"
/// Service type.
typedef enum {
ServiceType_Uninitialized, ///< Uninitialized service.
ServiceType_Normal, ///< Normal service.
ServiceType_Override ///< Service overriden in the homebrew environment.
} ServiceType;
/// Service object structure.
typedef struct {
Handle handle;
ServiceType type;
} Service;
/**
* @brief Returns whether a service is overriden in the homebrew environment.
* @param[in] s Service object.
* @return true if overriden.
*/
static inline bool serviceIsOverride(Service* s) {
return s->type == ServiceType_Override;
}
/**
* @brief Returns whether a service has been initialized.
* @param[in] s Service object.
* @return true if initialized.
*/
static inline bool serviceIsActive(Service* s) {
return s->type != ServiceType_Uninitialized;
}
/**
* @brief Dispatches an IPC request to a service.
* @param[in] s Service object.
* @return Result code
*/
static inline Result serviceIpcDispatch(Service* s) {
return ipcDispatch(s->handle);
}
/**
* @brief Creates a service object from an IPC session handle.
* @param[in] s Service object.
* @param[in] h IPC session handle.
*/
static inline void serviceCreate(Service* s, Handle h) {
s->handle = h;
s->type = ServiceType_Normal;
}
/**
* @brief Closes a service.
* @param[in] s Service object.
*/
static inline void serviceClose(Service* s) {
switch (s->type) {
case ServiceType_Normal:
svcCloseHandle(s->handle);
break;
case ServiceType_Override:
// Don't close because we don't own the overridden handle.
break;
case ServiceType_Uninitialized:
break;
}
s->type = ServiceType_Uninitialized;
}
/**
* @brief Initializes SM.
* @return Result code.
* @note This function is already called in the default application startup code (before main() is called).
*/
Result smInitialize(void);
/**
* @brief Uninitializes SM.
* @return Result code.
* @note This function is already handled in the default application exit code (after main() returns).
*/
void smExit(void);
/**
* @brief Requests a service from SM.
* @param[out] service_out Service structure which will be filled in.
* @param[in] name Name of the service to request.
* @return Result code.
*/
Result smGetService(Service* service_out, const char* name);
/**
* @brief Requests a service from SM, as an IPC session handle directly
* @param[out] handle_out Variable containing IPC session handle.
* @param[in] name Name of the service to request.
* @return Result code.
*/
Result smGetServiceOriginal(Handle* handle_out, u64 name);
/**
* @brief Retrieves an overriden service in the homebrew environment.
* @param[in] name Name of the service to request (as 64-bit integer).
* @return IPC session handle.
*/
Handle smGetServiceOverride(u64 name);
/**
* @brief Creates and registers a new service within SM.
* @param[out] handle_out Variable containing IPC port handle.
* @param[in] name Name of the service.
* @param[in] is_light "Is light"
* @param[in] max_sessions Maximum number of concurrent sessions that the service will accept.
* @return Result code.
*/
Result smRegisterService(Handle* handle_out, const char* name, bool is_light, int max_sessions);
/**
* @brief Unregisters a previously registered service in SM.
* @param[in] name Name of the service.
* @return Result code.
*/
Result smUnregisterService(const char* name);
/**
* @brief Check whether SM is initialized.
* @return true if initialized.
*/
bool smHasInitialized(void);
/**
* @brief Encodes a service name as a 64-bit integer.
* @param[in] name Name of the service.
* @return Encoded name.
*/
u64 smEncodeName(const char* name);
/**
* @brief Overrides a service with a custom IPC service handle.
* @param[in] name Name of the service (as 64-bit integer).
* @param[in] handle IPC session handle.
*/
void smAddOverrideHandle(u64 name, Handle handle);