128 lines
4.8 KiB
C++
128 lines
4.8 KiB
C++
#pragma once
|
|
|
|
#include <common.h>
|
|
#include <kernel/ipc.h>
|
|
#include <functional>
|
|
|
|
#define SFunc(function) std::bind(&function, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)
|
|
|
|
namespace skyline::kernel::type {
|
|
class KSession;
|
|
}
|
|
namespace skyline::kernel::service {
|
|
/**
|
|
* @brief This contains an enum for every service that's present
|
|
*/
|
|
enum class Service {
|
|
sm,
|
|
fatal_u,
|
|
set_sys,
|
|
apm,
|
|
apm_ISession,
|
|
am_appletOE,
|
|
am_IApplicationProxy,
|
|
am_ICommonStateGetter,
|
|
am_IApplicationFunctions,
|
|
am_ISelfController,
|
|
am_IWindowController,
|
|
am_IAudioController,
|
|
am_IDisplayController,
|
|
am_ILibraryAppletCreator,
|
|
am_IDebugFunctions,
|
|
hid,
|
|
hid_IAppletResource,
|
|
time,
|
|
time_ISystemClock,
|
|
time_ITimeZoneService,
|
|
fs_fsp,
|
|
fs_IFileSystem,
|
|
};
|
|
|
|
/**
|
|
* @brief A map from every service's name as a std::string to the corresponding serviceEnum
|
|
*/
|
|
const static std::unordered_map<std::string, Service> ServiceString = {
|
|
{"sm:", Service::sm},
|
|
{"fatal:u", Service::fatal_u},
|
|
{"set:sys", Service::set_sys},
|
|
{"apm", Service::apm},
|
|
{"apm:ISession", Service::apm_ISession},
|
|
{"appletOE", Service::am_appletOE},
|
|
{"am:IApplicationProxy", Service::am_IApplicationProxy},
|
|
{"am:ICommonStateGetter", Service::am_ICommonStateGetter},
|
|
{"am:ISelfController", Service::am_ISelfController},
|
|
{"am:IWindowController", Service::am_IWindowController},
|
|
{"am:IAudioController", Service::am_IAudioController},
|
|
{"am:IDisplayController", Service::am_IDisplayController},
|
|
{"am:ILibraryAppletCreator", Service::am_ILibraryAppletCreator},
|
|
{"am:IApplicationFunctions", Service::am_IApplicationFunctions},
|
|
{"am:IDebugFunctions", Service::am_IDebugFunctions},
|
|
{"hid", Service::hid},
|
|
{"hid:IAppletResource", Service::hid_IAppletResource},
|
|
{"time:s", Service::time},
|
|
{"time:a", Service::time},
|
|
{"time:ISystemClock", Service::time_ISystemClock},
|
|
{"time:ITimeZoneService", Service::time_ITimeZoneService},
|
|
{"fsp-srv", Service::fs_fsp},
|
|
{"fs:IFileSystem", Service::fs_IFileSystem},
|
|
};
|
|
|
|
class ServiceManager;
|
|
|
|
/**
|
|
* @brief The BaseService class is a class for all Services to inherit from
|
|
*/
|
|
class BaseService {
|
|
protected:
|
|
const DeviceState &state; //!< The state of the device
|
|
ServiceManager& manager; //!< A pointer to the service manager
|
|
std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> vTable; //!< This holds the mapping from an object's CmdId to the actual function
|
|
|
|
public:
|
|
Service serviceType; //!< Which service this is
|
|
const bool hasLoop; //<! If the service has a loop or not
|
|
|
|
/**
|
|
* @param state The state of the device
|
|
* @param hasLoop If the service has a loop or not
|
|
* @param serviceType The type of the service
|
|
* @param serviceName The name of the service
|
|
* @param vTable The functions of the service
|
|
*/
|
|
BaseService(const DeviceState &state, ServiceManager& manager, bool hasLoop, Service serviceType, const std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : state(state), manager(manager), hasLoop(hasLoop), serviceType(serviceType), vTable(vTable) {}
|
|
|
|
std::string getName() {
|
|
std::string serviceName = "";
|
|
for (const auto& [name, type] : ServiceString)
|
|
if(type == serviceType)
|
|
serviceName = name;
|
|
return serviceName;
|
|
}
|
|
|
|
/**
|
|
* @brief This handles all IPC commands with type request to a service
|
|
* @param request The corresponding IpcRequest object
|
|
* @param response The corresponding IpcResponse object
|
|
*/
|
|
void HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
|
std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)> function;
|
|
try {
|
|
function = vTable.at(request.payload->value);
|
|
} catch (std::out_of_range&) {
|
|
state.logger->Write(Logger::Warn, "Cannot find function in service '{0}' (Type: {1}): 0x{2:X} ({2})", getName(), serviceType, u32(request.payload->value));
|
|
return;
|
|
}
|
|
try {
|
|
function(session, request, response);
|
|
} catch (std::exception& e) {
|
|
throw exception(e.what());
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief This is used by some services when they need to run some code at regular intervals
|
|
*/
|
|
virtual void Loop() {};
|
|
};
|
|
}
|