#pragma once #include #include #include #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 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> vTable; //!< This holds the mapping from an object's CmdId to the actual function public: Service serviceType; //!< Which service this is const bool hasLoop; //> &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 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() {}; }; }