diff --git a/.clang-format b/.clang-format index 7a5d829..77be22e 100644 --- a/.clang-format +++ b/.clang-format @@ -3,4 +3,4 @@ BasedOnStyle: Google ColumnLimit: 119 IndentWidth: 4 DerivePointerAlignment: false -NamespaceIndentation: Inner +NamespaceIndentation: All diff --git a/libeiffel b/libeiffel index fefa49b..c7ad1cb 160000 --- a/libeiffel +++ b/libeiffel @@ -1 +1 @@ -Subproject commit fefa49b63cc8a88175097ef999426101897fe892 +Subproject commit c7ad1cb13c54bdb7e279675042afbfede44a024a diff --git a/source/core/plugin_handler.cpp b/source/core/plugin_handler.cpp new file mode 100644 index 0000000..451591b --- /dev/null +++ b/source/core/plugin_handler.cpp @@ -0,0 +1,33 @@ +#include "plugin_handler.hpp" + +#include + +namespace efl::core { + + PluginHandler::PluginHandler() {} + + PluginHandler::~PluginHandler() {} + + ams::Result PluginHandler::GetPluginMeta(SlPluginMeta* out_pluginMeta, PluginName& name) { + auto& activePluginMetas = GetInstance().m_ActivePluginMetas; + auto foundPluginEntry = activePluginMetas.find(name.data()); + if (foundPluginEntry != activePluginMetas.end()) { + *out_pluginMeta = foundPluginEntry->second; + } else { + return EFL_U_RESULT_PLUGIN_NOT_ACTIVE; + } + return 0; + } + + ams::Result PluginHandler::GetPluginSharedMemInfo(SlPluginSharedMemInfo* out_sharedMemInfo, PluginName& name) { + auto& activePluginSharedMemInfos = GetInstance().m_ActivePluginSharedMemInfos; + auto foundPluginEntry = activePluginSharedMemInfos.find(name.data()); + if (foundPluginEntry == activePluginSharedMemInfos.end()) { + return EFL_U_RESULT_SHARED_MEM_NOT_REGISTERED; + } + *out_sharedMemInfo = foundPluginEntry->second; + activePluginSharedMemInfos.erase(foundPluginEntry); // temp: keep it after proper cleanup impl + return 0; + } + +} // namespace efl::core diff --git a/source/core/plugin_handler.hpp b/source/core/plugin_handler.hpp new file mode 100644 index 0000000..067c8e0 --- /dev/null +++ b/source/core/plugin_handler.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include + +#include +#include +#include + +namespace efl::core { + + using PluginName = std::array; + + class PluginHandler { + private: + PluginHandler(); + PluginHandler(const PluginHandler&) = delete; + ~PluginHandler(); + static inline auto& GetInstance() { + static PluginHandler s_Instance; + return s_Instance; + } + + std::map m_ActivePluginMetas; + std::map m_ActivePluginSharedMemInfos; + + // TODO: need to clean everything when game is closed + + public: + static inline void SetPluginMeta(SlPluginMeta& pluginMeta) { + GetInstance().m_ActivePluginMetas[pluginMeta.name] = pluginMeta; + } + + static inline void SetPluginSharedMem(SlPluginName name, SlPluginSharedMemInfo& sharedMemInfo) { + GetInstance().m_ActivePluginSharedMemInfos[name] = sharedMemInfo; + } + + static ams::Result GetPluginMeta(SlPluginMeta* out_pluginMeta, PluginName& name); + static ams::Result GetPluginSharedMemInfo(SlPluginSharedMemInfo* out_sharedMemInfo, PluginName& name); + }; + +} // namespace efl::core diff --git a/source/ipc/server.cpp b/source/ipc/server.cpp index 2ed28b2..61e0bc9 100644 --- a/source/ipc/server.cpp +++ b/source/ipc/server.cpp @@ -1,14 +1,15 @@ #include "server.hpp" #include "sl_service.hpp" +#include "user_service.hpp" -namespace efl { -namespace ipc { +namespace efl::ipc { Server::Server() { R_ABORT_UNLESS( m_serverManager.RegisterServer(SlService::SERVICE_NAME, EIFFEL_SERVICE_MAX_SESSIONS)); + R_ABORT_UNLESS( + m_serverManager.RegisterServer(UserService::SERVICE_NAME, EIFFEL_SERVICE_MAX_SESSIONS)); } -}; // namespace ipc -}; // namespace efl +}; // namespace efl::ipc diff --git a/source/ipc/server.hpp b/source/ipc/server.hpp index 2610afd..9897a24 100644 --- a/source/ipc/server.hpp +++ b/source/ipc/server.hpp @@ -2,12 +2,11 @@ #include -namespace efl { -namespace ipc { +namespace efl::ipc { class Server { private: - static constexpr auto NUM_SERVERS = 1; + static constexpr auto NUM_SERVERS = 2; static constexpr auto EIFFEL_SERVICE_MAX_SESSIONS = 5; Server(); @@ -23,5 +22,4 @@ namespace ipc { static inline void Loop() { GetInstance().m_serverManager.LoopProcess(); } }; -} // namespace ipc -} // namespace efl +} // namespace efl::ipc diff --git a/source/ipc/sl_service.cpp b/source/ipc/sl_service.cpp index 0003c63..3f558b9 100644 --- a/source/ipc/sl_service.cpp +++ b/source/ipc/sl_service.cpp @@ -2,8 +2,7 @@ #include "../util.hpp" -namespace efl { -namespace ipc { +namespace efl::ipc { SlService::SlService() {} @@ -11,9 +10,23 @@ namespace ipc { ams::Result SlService::Log(const ams::sf::InBuffer& module_name, efl::logger::LogLevel level, const ams::sf::InBuffer& buf) { - LOG("[%s][%s] %s", module_name.GetPointer(), logger::GetLogLevelString(level), buf.GetPointer()); + // TODO: impl proper handling of logs + printf("LOG: [%s][%s] %s", module_name.GetPointer(), logger::GetLogLevelString(level), + buf.GetPointer()); // this is just for debug return 0; }; -}; // namespace ipc -}; // namespace efl + ams::Result SlService::RegisterPlugin(SlPluginMeta meta) { + core::PluginHandler::SetPluginMeta(meta); + LOG("%s", meta.name); + return 0; + }; + + ams::Result SlService::RegisterSharedMem(EiffelSlRegisterSharedMemIn in, ams::sf::CopyHandle handle) { + auto sharedMemInfo = SlPluginSharedMemInfo{handle.GetValue(), in.size, in.perm}; + core::PluginHandler::SetPluginSharedMem(in.name, sharedMemInfo); + LOG("%s - size 0x%lx perm: %x", in.name, in.size, in.perm); + return 0; + }; + +}; // namespace efl::ipc diff --git a/source/ipc/sl_service.hpp b/source/ipc/sl_service.hpp index 9fa38d3..b61627f 100644 --- a/source/ipc/sl_service.hpp +++ b/source/ipc/sl_service.hpp @@ -4,15 +4,17 @@ #include +#include "../core/plugin_handler.hpp" #include "../logger/types.hpp" -namespace efl { -namespace ipc { +namespace efl::ipc { class SlService final : public ams::sf::IServiceObject { protected: enum class CommandId { Log = EFL_SL_CMD_LOG, + RegisterPlugin = EFL_SL_CMD_REGISTER_PLUGIN, + RegisterSharedMem = EFL_SL_CMD_REGISTER_SHARED_MEM, }; public: @@ -20,15 +22,19 @@ namespace ipc { virtual ~SlService(); private: - ams::Result Log(const ams::sf::InBuffer&, efl::logger::LogLevel, const ams::sf::InBuffer&); + ams::Result Log(const ams::sf::InBuffer& module_name, efl::logger::LogLevel level, + const ams::sf::InBuffer& buf); + ams::Result RegisterPlugin(SlPluginMeta meta); + ams::Result RegisterSharedMem(EiffelSlRegisterSharedMemIn in, ams::sf::CopyHandle handle); public: DEFINE_SERVICE_DISPATCH_TABLE{ MAKE_SERVICE_COMMAND_META(Log), + MAKE_SERVICE_COMMAND_META(RegisterPlugin), + MAKE_SERVICE_COMMAND_META(RegisterSharedMem), }; static constexpr auto SERVICE_NAME = ams::sm::ServiceName::Encode(EIFFEL_SKYLINE_SERVICE_NAME); }; -}; // namespace ipc -}; // namespace efl +}; // namespace efl::ipc diff --git a/source/ipc/user_service.cpp b/source/ipc/user_service.cpp new file mode 100644 index 0000000..d75ea37 --- /dev/null +++ b/source/ipc/user_service.cpp @@ -0,0 +1,28 @@ +#include "user_service.hpp" + +#include "../util.hpp" + +namespace efl::ipc { + + UserService::UserService() {} + + UserService::~UserService() {} + + ams::Result UserService::GetPluginMeta(ams::sf::Out out, core::PluginName name) { + LOG("%s", name.data()); + return core::PluginHandler::GetPluginMeta(out.GetPointer(), name); + }; + + // TODO: use copy handle instead when cleaning up handles is implemented + ams::Result UserService::GetPluginSharedMem(ams::sf::OutMoveHandle out_handle, + ams::sf::Out out, core::PluginName name) { + LOG("%s", name.data()); + auto rc = core::PluginHandler::GetPluginSharedMemInfo(out.GetPointer(), name); + if (R_SUCCEEDED(rc)) { + *(out_handle.GetHandlePointer()) = out.GetPointer()->handle; + } + out.GetPointer()->handle = INVALID_HANDLE; // for libeiffel to fill in + return rc; + }; + +}; // namespace efl::ipc diff --git a/source/ipc/user_service.hpp b/source/ipc/user_service.hpp new file mode 100644 index 0000000..73ad06a --- /dev/null +++ b/source/ipc/user_service.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +#include + +#include "../core/plugin_handler.hpp" + +namespace efl::ipc { + + class UserService final : public ams::sf::IServiceObject { + protected: + enum class CommandId { + GetPluginMeta = EFL_U_CMD_GET_PLUGIN_META, + GetPluginSharedMem = EFL_U_CMD_GET_PLUGIN_SHARED_MEM, + }; + + public: + explicit UserService(); + virtual ~UserService(); + + private: + ams::Result GetPluginMeta(ams::sf::Out out, core::PluginName name); + ams::Result GetPluginSharedMem(ams::sf::OutMoveHandle out_handle, ams::sf::Out out, + core::PluginName name); + + public: + DEFINE_SERVICE_DISPATCH_TABLE{ + MAKE_SERVICE_COMMAND_META(GetPluginMeta), + MAKE_SERVICE_COMMAND_META(GetPluginSharedMem), + }; + + static constexpr auto SERVICE_NAME = ams::sm::ServiceName::Encode(EIFFEL_USER_SERVICE_NAME); + }; + +}; // namespace efl::ipc