Revert "hoc-clk: add live vdd2, live boost clock and basic pwm dimming"

This reverts commit 15b7df8ef1.
This commit is contained in:
souldbminersmwc
2025-11-09 16:14:52 -05:00
parent 22ec140738
commit 21a3f953d7
3804 changed files with 435 additions and 570162 deletions

View File

@@ -1,49 +0,0 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/sf/sf_common.hpp>
#include <stratosphere/sf/cmif/sf_cmif_pointer_and_size.hpp>
namespace ams::sf::hipc {
void *GetMessageBufferOnTls();
constexpr size_t TlsMessageBufferSize = 0x100;
#if defined(ATMOSPHERE_OS_HORIZON)
ALWAYS_INLINE void *GetMessageBufferOnTls() {
return svc::GetThreadLocalRegion()->message_buffer;
}
#endif
enum class ReceiveResult {
Success,
Closed,
NeedsRetry,
};
void AttachMultiWaitHolderForAccept(os::MultiWaitHolderType *holder, os::NativeHandle port);
void AttachMultiWaitHolderForReply(os::MultiWaitHolderType *holder, os::NativeHandle request);
Result Receive(ReceiveResult *out_recv_result, os::NativeHandle session_handle, const cmif::PointerAndSize &message_buffer);
Result Receive(bool *out_closed, os::NativeHandle session_handle, const cmif::PointerAndSize &message_buffer);
Result Reply(os::NativeHandle session_handle, const cmif::PointerAndSize &message_buffer);
Result CreateSession(os::NativeHandle *out_server_handle, os::NativeHandle *out_client_handle);
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp>
#include <stratosphere/sf/cmif/sf_cmif_domain_manager.hpp>
namespace ams::sf::hipc {
class ServerDomainSessionManager : public ServerSessionManager, private cmif::ServerDomainManager {
protected:
using cmif::ServerDomainManager::DomainEntryStorage;
using cmif::ServerDomainManager::DomainStorage;
protected:
virtual Result DispatchManagerRequest(ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message) override final;
public:
ServerDomainSessionManager(DomainEntryStorage *entry_storage, size_t entry_count) : ServerDomainManager(entry_storage, entry_count) { /* ... */ }
inline cmif::DomainServiceObject *AllocateDomainServiceObject() {
return cmif::ServerDomainManager::AllocateDomainServiceObject();
}
};
}

View File

@@ -1,511 +0,0 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/sf/sf_mitm_config.hpp>
#include <stratosphere/sf/hipc/sf_hipc_server_domain_session_manager.hpp>
#include <stratosphere/sm.hpp>
namespace ams::sf::hipc {
struct DefaultServerManagerOptions {
static constexpr size_t PointerBufferSize = 0;
static constexpr size_t MaxDomains = 0;
static constexpr size_t MaxDomainObjects = 0;
static constexpr bool CanDeferInvokeRequest = false;
static constexpr bool CanManageMitmServers = false;
};
static constexpr size_t ServerSessionCountMax = 0x40;
static_assert(ServerSessionCountMax == 0x40, "ServerSessionCountMax isn't 0x40 somehow, this assert is a reminder that this will break lots of things");
template<size_t, typename, size_t>
class ServerManager;
class ServerManagerBase : public ServerDomainSessionManager {
NON_COPYABLE(ServerManagerBase);
NON_MOVEABLE(ServerManagerBase);
public:
#if AMS_SF_MITM_SUPPORTED
using MitmQueryFunction = bool (*)(const sm::MitmProcessInfo &);
#endif
private:
enum class UserDataTag : uintptr_t {
Server = 1,
Session = 2,
#if AMS_SF_MITM_SUPPORTED
MitmServer = 3,
#endif
};
protected:
using ServerDomainSessionManager::DomainEntryStorage;
using ServerDomainSessionManager::DomainStorage;
protected:
class Server : public os::MultiWaitHolderType {
friend class ServerManagerBase;
template<size_t, typename, size_t>
friend class ServerManager;
NON_COPYABLE(Server);
NON_MOVEABLE(Server);
private:
cmif::ServiceObjectHolder m_static_object;
os::NativeHandle m_port_handle;
sm::ServiceName m_service_name;
int m_index;
bool m_service_managed;
#if AMS_SF_MITM_SUPPORTED
bool m_is_mitm_server;
#endif
public:
#if AMS_SF_MITM_SUPPORTED
void AcknowledgeMitmSession(std::shared_ptr<::Service> *out_fsrv, sm::MitmProcessInfo *out_client_info) {
/* Check mitm server. */
AMS_ABORT_UNLESS(m_is_mitm_server);
/* Create forward service. */
*out_fsrv = ServerSession::CreateForwardService();
/* Get client info. */
R_ABORT_UNLESS(sm::mitm::AcknowledgeSession(out_fsrv->get(), out_client_info, m_service_name));
}
#endif
};
protected:
static constinit inline bool g_is_any_deferred_supported = false;
#if AMS_SF_MITM_SUPPORTED
static constinit inline bool g_is_any_mitm_supported = false;
#endif
private:
/* Multiple wait management. */
os::MultiWaitType m_multi_wait;
os::Event m_request_stop_event;
os::MultiWaitHolderType m_request_stop_event_holder;
os::Event m_notify_event;
os::MultiWaitHolderType m_notify_event_holder;
os::SdkMutex m_selection_mutex;
os::SdkMutex m_deferred_list_mutex;
os::MultiWaitType m_deferred_list;
/* Boolean values. */
const bool m_is_defer_supported;
const bool m_is_mitm_supported;
private:
virtual void RegisterServerSessionToWait(ServerSession *session) override final;
void LinkToDeferredList(os::MultiWaitHolderType *holder);
void LinkDeferred();
bool WaitAndProcessImpl();
Result ProcessForServer(os::MultiWaitHolderType *holder);
Result ProcessForSession(os::MultiWaitHolderType *holder);
#if AMS_SF_MITM_SUPPORTED
Result ProcessForMitmServer(os::MultiWaitHolderType *holder);
#endif
void RegisterServerImpl(Server *server, os::NativeHandle port_handle, bool is_mitm_server) {
server->m_port_handle = port_handle;
hipc::AttachMultiWaitHolderForAccept(server, port_handle);
#if AMS_SF_MITM_SUPPORTED
server->m_is_mitm_server = is_mitm_server;
if (is_mitm_server) {
/* Mitm server. */
AMS_ABORT_UNLESS(this->CanManageMitmServers());
os::SetMultiWaitHolderUserData(server, static_cast<uintptr_t>(UserDataTag::MitmServer));
} else {
/* Non-mitm server. */
os::SetMultiWaitHolderUserData(server, static_cast<uintptr_t>(UserDataTag::Server));
}
#else
AMS_UNUSED(is_mitm_server);
os::SetMultiWaitHolderUserData(server, static_cast<uintptr_t>(UserDataTag::Server));
#endif
os::LinkMultiWaitHolder(std::addressof(m_multi_wait), server);
}
void RegisterServerImpl(int index, cmif::ServiceObjectHolder &&static_holder, os::NativeHandle port_handle, bool is_mitm_server) {
/* Allocate server memory. */
auto *server = this->AllocateServer();
AMS_ABORT_UNLESS(server != nullptr);
server->m_service_managed = false;
if (static_holder) {
server->m_static_object = std::move(static_holder);
} else {
server->m_index = index;
}
this->RegisterServerImpl(server, port_handle, is_mitm_server);
}
Result RegisterServerImpl(int index, cmif::ServiceObjectHolder &&static_holder, sm::ServiceName service_name, size_t max_sessions) {
/* Register service. */
os::NativeHandle port_handle;
R_TRY(sm::RegisterService(&port_handle, service_name, max_sessions, false));
/* Allocate server memory. */
auto *server = this->AllocateServer();
AMS_ABORT_UNLESS(server != nullptr);
server->m_service_managed = true;
server->m_service_name = service_name;
if (static_holder) {
server->m_static_object = std::move(static_holder);
} else {
server->m_index = index;
}
this->RegisterServerImpl(server, port_handle, false);
R_SUCCEED();
}
#if AMS_SF_MITM_SUPPORTED
Result InstallMitmServerImpl(os::NativeHandle *out_port_handle, sm::ServiceName service_name, MitmQueryFunction query_func);
#endif
protected:
virtual Server *AllocateServer() = 0;
virtual void DestroyServer(Server *server) = 0;
virtual Result OnNeedsToAccept(int port_index, Server *server) {
AMS_UNUSED(port_index, server);
AMS_ABORT("OnNeedsToAccept must be overridden when using indexed ports");
}
template<typename Interface>
Result AcceptImpl(Server *server, SharedPointer<Interface> p) {
R_RETURN(ServerSessionManager::AcceptSession(server->m_port_handle, std::move(p)));
}
#if AMS_SF_MITM_SUPPORTED
template<typename Interface>
Result AcceptMitmImpl(Server *server, SharedPointer<Interface> p, std::shared_ptr<::Service> forward_service) {
AMS_ABORT_UNLESS(this->CanManageMitmServers());
R_RETURN(ServerSessionManager::AcceptMitmSession(server->m_port_handle, std::move(p), std::move(forward_service)));
}
template<typename Interface>
Result RegisterMitmServerImpl(int index, cmif::ServiceObjectHolder &&static_holder, sm::ServiceName service_name) {
/* Install mitm service. */
os::NativeHandle port_handle;
R_TRY(this->InstallMitmServerImpl(&port_handle, service_name, &Interface::ShouldMitm));
/* Allocate server memory. */
auto *server = this->AllocateServer();
AMS_ABORT_UNLESS(server != nullptr);
server->m_service_managed = true;
server->m_service_name = service_name;
if (static_holder) {
server->m_static_object = std::move(static_holder);
} else {
server->m_index = index;
}
this->RegisterServerImpl(server, port_handle, true);
R_SUCCEED();
}
#endif
public:
ServerManagerBase(DomainEntryStorage *entry_storage, size_t entry_count, bool defer_supported, bool mitm_supported) :
ServerDomainSessionManager(entry_storage, entry_count),
m_request_stop_event(os::EventClearMode_ManualClear), m_notify_event(os::EventClearMode_ManualClear),
m_selection_mutex(), m_deferred_list_mutex(), m_is_defer_supported(defer_supported), m_is_mitm_supported(mitm_supported)
{
/* Link multi-wait holders. */
os::InitializeMultiWait(std::addressof(m_multi_wait));
os::InitializeMultiWaitHolder(std::addressof(m_request_stop_event_holder), m_request_stop_event.GetBase());
os::LinkMultiWaitHolder(std::addressof(m_multi_wait), std::addressof(m_request_stop_event_holder));
os::InitializeMultiWaitHolder(std::addressof(m_notify_event_holder), m_notify_event.GetBase());
os::LinkMultiWaitHolder(std::addressof(m_multi_wait), std::addressof(m_notify_event_holder));
os::InitializeMultiWait(std::addressof(m_deferred_list));
}
virtual ~ServerManagerBase() = default;
static ALWAYS_INLINE bool CanAnyDeferInvokeRequest() {
return g_is_any_deferred_supported;
}
ALWAYS_INLINE bool CanDeferInvokeRequest() const {
return CanAnyDeferInvokeRequest() && m_is_defer_supported;
}
#if AMS_SF_MITM_SUPPORTED
static ALWAYS_INLINE bool CanAnyManageMitmServers() {
return g_is_any_mitm_supported;
}
ALWAYS_INLINE bool CanManageMitmServers() const {
return CanAnyManageMitmServers() && m_is_mitm_supported;
}
#else
static consteval bool CanAnyManageMitmServers() { return false; }
static consteval bool CanManageMitmServers() { return false; }
#endif
template<typename Interface>
void RegisterObjectForServer(SharedPointer<Interface> static_object, os::NativeHandle port_handle) {
this->RegisterServerImpl(0, cmif::ServiceObjectHolder(std::move(static_object)), port_handle, false);
}
template<typename Interface>
Result RegisterObjectForServer(SharedPointer<Interface> static_object, sm::ServiceName service_name, size_t max_sessions) {
R_RETURN(this->RegisterServerImpl(0, cmif::ServiceObjectHolder(std::move(static_object)), service_name, max_sessions));
}
void RegisterServer(int port_index, os::NativeHandle port_handle) {
this->RegisterServerImpl(port_index, cmif::ServiceObjectHolder(), port_handle, false);
}
Result RegisterServer(int port_index, sm::ServiceName service_name, size_t max_sessions) {
R_RETURN(this->RegisterServerImpl(port_index, cmif::ServiceObjectHolder(), service_name, max_sessions));
}
/* Processing. */
os::MultiWaitHolderType *WaitSignaled();
void ResumeProcessing();
void RequestStopProcessing();
void AddUserMultiWaitHolder(os::MultiWaitHolderType *holder);
Result Process(os::MultiWaitHolderType *holder);
void WaitAndProcess();
void LoopProcess();
};
template<size_t MaxServers, typename ManagerOptions = DefaultServerManagerOptions, size_t MaxSessions = ServerSessionCountMax - MaxServers>
class ServerManager : public ServerManagerBase {
NON_COPYABLE(ServerManager);
NON_MOVEABLE(ServerManager);
static_assert(MaxServers <= ServerSessionCountMax, "MaxServers can never be larger than ServerSessionCountMax (0x40).");
static_assert(MaxSessions <= ServerSessionCountMax, "MaxSessions can never be larger than ServerSessionCountMax (0x40).");
static_assert(MaxServers + MaxSessions <= ServerSessionCountMax, "MaxServers + MaxSessions can never be larger than ServerSessionCountMax (0x40).");
private:
static constexpr inline bool DomainCountsValid = [] {
if constexpr (ManagerOptions::MaxDomains > 0) {
return ManagerOptions::MaxDomainObjects > 0;
} else {
return ManagerOptions::MaxDomainObjects == 0;
}
}();
static_assert(DomainCountsValid, "Invalid Domain Counts");
#if !(AMS_SF_MITM_SUPPORTED)
static_assert(!ManagerOptions::CanManageMitmServers);
#endif
protected:
using ServerManagerBase::DomainEntryStorage;
using ServerManagerBase::DomainStorage;
private:
/* Resource storage. */
os::SdkMutex m_resource_mutex;
util::TypedStorage<Server> m_server_storages[MaxServers];
bool m_server_allocated[MaxServers];
util::TypedStorage<ServerSession> m_session_storages[MaxSessions];
bool m_session_allocated[MaxSessions];
u8 m_pointer_buffer_storage[0x10 + (MaxSessions * ManagerOptions::PointerBufferSize)];
#if AMS_SF_MITM_SUPPORTED
u8 m_saved_message_storage[0x10 + (MaxSessions * ((ManagerOptions::CanDeferInvokeRequest || ManagerOptions::CanManageMitmServers) ? hipc::TlsMessageBufferSize : 0))];
#else
u8 m_saved_message_storage[0x10 + (MaxSessions * ((ManagerOptions::CanDeferInvokeRequest) ? hipc::TlsMessageBufferSize : 0))];
#endif
uintptr_t m_pointer_buffers_start;
uintptr_t m_saved_messages_start;
/* Domain resources. */
DomainStorage m_domain_storages[ManagerOptions::MaxDomains];
bool m_domain_allocated[ManagerOptions::MaxDomains];
DomainEntryStorage m_domain_entry_storages[ManagerOptions::MaxDomainObjects];
private:
constexpr inline size_t GetServerIndex(const Server *server) const {
const size_t i = server - GetPointer(m_server_storages[0]);
AMS_ABORT_UNLESS(i < MaxServers);
return i;
}
constexpr inline size_t GetSessionIndex(const ServerSession *session) const {
const size_t i = session - GetPointer(m_session_storages[0]);
AMS_ABORT_UNLESS(i < MaxSessions);
return i;
}
constexpr inline cmif::PointerAndSize GetObjectBySessionIndex(const ServerSession *session, uintptr_t start, size_t size) const {
return cmif::PointerAndSize(start + this->GetSessionIndex(session) * size, size);
}
protected:
virtual ServerSession *AllocateSession() override final {
if constexpr (MaxSessions > 0) {
std::scoped_lock lk(m_resource_mutex);
for (size_t i = 0; i < MaxSessions; i++) {
if (!m_session_allocated[i]) {
m_session_allocated[i] = true;
return GetPointer(m_session_storages[i]);
}
}
}
return nullptr;
}
virtual void FreeSession(ServerSession *session) override final {
std::scoped_lock lk(m_resource_mutex);
const size_t index = this->GetSessionIndex(session);
AMS_ABORT_UNLESS(m_session_allocated[index]);
m_session_allocated[index] = false;
}
virtual Server *AllocateServer() override final {
if constexpr (MaxServers > 0) {
std::scoped_lock lk(m_resource_mutex);
for (size_t i = 0; i < MaxServers; i++) {
if (!m_server_allocated[i]) {
m_server_allocated[i] = true;
return GetPointer(m_server_storages[i]);
}
}
}
return nullptr;
}
virtual void DestroyServer(Server *server) override final {
std::scoped_lock lk(m_resource_mutex);
const size_t index = this->GetServerIndex(server);
AMS_ABORT_UNLESS(m_server_allocated[index]);
{
os::UnlinkMultiWaitHolder(server);
os::FinalizeMultiWaitHolder(server);
if (server->m_service_managed) {
#if AMS_SF_MITM_SUPPORTED
if constexpr (ManagerOptions::CanManageMitmServers) {
if (server->m_is_mitm_server) {
R_ABORT_UNLESS(sm::mitm::UninstallMitm(server->m_service_name));
} else {
R_ABORT_UNLESS(sm::UnregisterService(server->m_service_name));
}
} else {
R_ABORT_UNLESS(sm::UnregisterService(server->m_service_name));
}
#else
R_ABORT_UNLESS(sm::UnregisterService(server->m_service_name));
#endif
os::CloseNativeHandle(server->m_port_handle);
}
}
m_server_allocated[index] = false;
}
virtual void *AllocateDomain() override final {
std::scoped_lock lk(m_resource_mutex);
for (size_t i = 0; i < ManagerOptions::MaxDomains; i++) {
if (!m_domain_allocated[i]) {
m_domain_allocated[i] = true;
return GetPointer(m_domain_storages[i]);
}
}
return nullptr;
}
virtual void FreeDomain(void *domain) override final {
std::scoped_lock lk(m_resource_mutex);
DomainStorage *ptr = static_cast<DomainStorage *>(domain);
const size_t index = ptr - m_domain_storages;
AMS_ABORT_UNLESS(index < ManagerOptions::MaxDomains);
AMS_ABORT_UNLESS(m_domain_allocated[index]);
m_domain_allocated[index] = false;
}
virtual cmif::PointerAndSize GetSessionPointerBuffer(const ServerSession *session) const override final {
if constexpr (ManagerOptions::PointerBufferSize > 0) {
return this->GetObjectBySessionIndex(session, m_pointer_buffers_start, ManagerOptions::PointerBufferSize);
} else {
return cmif::PointerAndSize();
}
}
virtual cmif::PointerAndSize GetSessionSavedMessageBuffer(const ServerSession *session) const override final {
if constexpr (ManagerOptions::CanDeferInvokeRequest || ManagerOptions::CanManageMitmServers) {
return this->GetObjectBySessionIndex(session, m_saved_messages_start, hipc::TlsMessageBufferSize);
} else {
return cmif::PointerAndSize();
}
}
public:
ServerManager() : ServerManagerBase(m_domain_entry_storages, ManagerOptions::MaxDomainObjects, ManagerOptions::CanDeferInvokeRequest, ManagerOptions::CanManageMitmServers), m_resource_mutex() {
/* Clear storages. */
#define SF_SM_MEMCLEAR(obj) if constexpr (sizeof(obj) > 0) { std::memset(obj, 0, sizeof(obj)); }
SF_SM_MEMCLEAR(m_server_storages);
SF_SM_MEMCLEAR(m_server_allocated);
SF_SM_MEMCLEAR(m_session_storages);
SF_SM_MEMCLEAR(m_session_allocated);
SF_SM_MEMCLEAR(m_pointer_buffer_storage);
SF_SM_MEMCLEAR(m_saved_message_storage);
SF_SM_MEMCLEAR(m_domain_allocated);
#undef SF_SM_MEMCLEAR
/* Set resource starts. */
m_pointer_buffers_start = util::AlignUp(reinterpret_cast<uintptr_t>(m_pointer_buffer_storage), 0x10);
m_saved_messages_start = util::AlignUp(reinterpret_cast<uintptr_t>(m_saved_message_storage), 0x10);
/* Update globals. */
if constexpr (ManagerOptions::CanDeferInvokeRequest) {
ServerManagerBase::g_is_any_deferred_supported = true;
}
#if AMS_SF_MITM_SUPPORTED
if constexpr (ManagerOptions::CanManageMitmServers) {
ServerManagerBase::g_is_any_mitm_supported = true;
}
#endif
}
~ServerManager() {
/* Close all sessions. */
if constexpr (MaxSessions > 0) {
for (size_t i = 0; i < MaxSessions; i++) {
if (m_session_allocated[i]) {
this->CloseSessionImpl(GetPointer(m_session_storages[i]));
}
}
}
/* Close all servers. */
if constexpr (MaxServers > 0) {
for (size_t i = 0; i < MaxServers; i++) {
if (m_server_allocated[i]) {
this->DestroyServer(GetPointer(m_server_storages[i]));
}
}
}
}
public:
#if AMS_SF_MITM_SUPPORTED
template<typename Interface, bool Enable = ManagerOptions::CanManageMitmServers, typename = typename std::enable_if<Enable>::type>
Result RegisterMitmServer(int port_index, sm::ServiceName service_name) {
AMS_ABORT_UNLESS(this->CanManageMitmServers());
R_RETURN(this->template RegisterMitmServerImpl<Interface>(port_index, cmif::ServiceObjectHolder(), service_name));
}
#endif
};
}

View File

@@ -1,205 +0,0 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/sf/sf_common.hpp>
#include <stratosphere/sf/sf_mitm_config.hpp>
#include <stratosphere/sf/sf_service_object.hpp>
#include <stratosphere/sf/cmif/sf_cmif_pointer_and_size.hpp>
#include <stratosphere/sf/cmif/sf_cmif_service_object_holder.hpp>
#include <stratosphere/sf/hipc/sf_hipc_api.hpp>
namespace ams::sf::cmif {
struct ServiceDispatchContext;
}
namespace ams::sf::hipc {
class ServerSessionManager;
class ServerManagerBase;
namespace impl {
class HipcManagerImpl;
}
class ServerSession : public os::MultiWaitHolderType {
friend class ServerSessionManager;
friend class ServerManagerBase;
friend class impl::HipcManagerImpl;
NON_COPYABLE(ServerSession);
NON_MOVEABLE(ServerSession);
private:
cmif::ServiceObjectHolder m_srv_obj_holder;
cmif::PointerAndSize m_pointer_buffer;
cmif::PointerAndSize m_saved_message;
#if AMS_SF_MITM_SUPPORTED
util::TypedStorage<std::shared_ptr<::Service>> m_forward_service;
#endif
os::NativeHandle m_session_handle;
bool m_is_closed;
bool m_has_received;
const bool m_has_forward_service;
public:
ServerSession(os::NativeHandle h, cmif::ServiceObjectHolder &&obj) : m_srv_obj_holder(std::move(obj)), m_session_handle(h), m_has_forward_service(false) {
hipc::AttachMultiWaitHolderForReply(this, h);
m_is_closed = false;
m_has_received = false;
#if AMS_SF_MITM_SUPPORTED
AMS_ABORT_UNLESS(!this->IsMitmSession());
#endif
}
~ServerSession() {
#if AMS_SF_MITM_SUPPORTED
if (m_has_forward_service) {
util::DestroyAt(m_forward_service);
}
#endif
}
#if AMS_SF_MITM_SUPPORTED
ServerSession(os::NativeHandle h, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) : m_srv_obj_holder(std::move(obj)), m_session_handle(h), m_has_forward_service(true) {
hipc::AttachMultiWaitHolderForReply(this, h);
m_is_closed = false;
m_has_received = false;
util::ConstructAt(m_forward_service, std::move(fsrv));
AMS_ABORT_UNLESS(util::GetReference(m_forward_service) != nullptr);
}
ALWAYS_INLINE bool IsMitmSession() const {
return m_has_forward_service;
}
Result ForwardRequest(const cmif::ServiceDispatchContext &ctx) const;
static inline void ForwardServiceDeleter(Service *srv) {
serviceClose(srv);
delete srv;
}
static inline std::shared_ptr<::Service> CreateForwardService() {
return std::shared_ptr<::Service>(new ::Service(), ForwardServiceDeleter);
}
#endif
};
class ServerSessionManager {
private:
template<typename Constructor>
Result CreateSessionImpl(ServerSession **out, const Constructor &ctor) {
/* Allocate session. */
ServerSession *session_memory = this->AllocateSession();
R_UNLESS(session_memory != nullptr, sf::hipc::ResultOutOfSessionMemory());
ON_RESULT_FAILURE { this->DestroySession(session_memory); };
/* Register session. */
R_TRY(ctor(session_memory));
/* Save new session to output. */
*out = session_memory;
R_SUCCEED();
}
void DestroySession(ServerSession *session);
Result ProcessRequestImpl(ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message);
virtual void RegisterServerSessionToWait(ServerSession *session) = 0;
protected:
Result DispatchRequest(cmif::ServiceObjectHolder &&obj, ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message);
virtual Result DispatchManagerRequest(ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message);
protected:
virtual ServerSession *AllocateSession() = 0;
virtual void FreeSession(ServerSession *session) = 0;
virtual cmif::PointerAndSize GetSessionPointerBuffer(const ServerSession *session) const = 0;
virtual cmif::PointerAndSize GetSessionSavedMessageBuffer(const ServerSession *session) const = 0;
Result ReceiveRequestImpl(ServerSession *session, const cmif::PointerAndSize &message);
void CloseSessionImpl(ServerSession *session);
Result RegisterSessionImpl(ServerSession *session_memory, os::NativeHandle session_handle, cmif::ServiceObjectHolder &&obj);
Result AcceptSessionImpl(ServerSession *session_memory, os::NativeHandle port_handle, cmif::ServiceObjectHolder &&obj);
#if AMS_SF_MITM_SUPPORTED
Result RegisterMitmSessionImpl(ServerSession *session_memory, os::NativeHandle mitm_session_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv);
Result AcceptMitmSessionImpl(ServerSession *session_memory, os::NativeHandle mitm_port_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv);
#endif
Result ReceiveRequest(ServerSession *session, const cmif::PointerAndSize &message) {
R_RETURN(this->ReceiveRequestImpl(session, message));
}
Result RegisterSession(ServerSession **out, os::NativeHandle session_handle, cmif::ServiceObjectHolder &&obj) {
auto ctor = [&](ServerSession *session_memory) -> Result {
R_RETURN(this->RegisterSessionImpl(session_memory, session_handle, std::forward<cmif::ServiceObjectHolder>(obj)));
};
R_RETURN(this->CreateSessionImpl(out, ctor));
}
Result AcceptSession(ServerSession **out, os::NativeHandle port_handle, cmif::ServiceObjectHolder &&obj) {
auto ctor = [&](ServerSession *session_memory) -> Result {
R_RETURN(this->AcceptSessionImpl(session_memory, port_handle, std::forward<cmif::ServiceObjectHolder>(obj)));
};
R_RETURN(this->CreateSessionImpl(out, ctor));
}
#if AMS_SF_MITM_SUPPORTED
Result RegisterMitmSession(ServerSession **out, os::NativeHandle mitm_session_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) {
auto ctor = [&](ServerSession *session_memory) -> Result {
R_RETURN(this->RegisterMitmSessionImpl(session_memory, mitm_session_handle, std::forward<cmif::ServiceObjectHolder>(obj), std::forward<std::shared_ptr<::Service>>(fsrv)));
};
R_RETURN(this->CreateSessionImpl(out, ctor));
}
Result AcceptMitmSession(ServerSession **out, os::NativeHandle mitm_port_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) {
auto ctor = [&](ServerSession *session_memory) -> Result {
R_RETURN(this->AcceptMitmSessionImpl(session_memory, mitm_port_handle, std::forward<cmif::ServiceObjectHolder>(obj), std::forward<std::shared_ptr<::Service>>(fsrv)));
};
R_RETURN(this->CreateSessionImpl(out, ctor));
}
#endif
public:
Result RegisterSession(os::NativeHandle session_handle, cmif::ServiceObjectHolder &&obj);
Result AcceptSession(os::NativeHandle port_handle, cmif::ServiceObjectHolder &&obj);
#if AMS_SF_MITM_SUPPORTED
Result RegisterMitmSession(os::NativeHandle session_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv);
Result AcceptMitmSession(os::NativeHandle mitm_port_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv);
#endif
template<typename Interface>
Result AcceptSession(os::NativeHandle port_handle, SharedPointer<Interface> obj) {
R_RETURN(this->AcceptSession(port_handle, cmif::ServiceObjectHolder(std::move(obj))));
}
#if AMS_SF_MITM_SUPPORTED
template<typename Interface>
Result AcceptMitmSession(os::NativeHandle mitm_port_handle, SharedPointer<Interface> obj, std::shared_ptr<::Service> &&fsrv) {
R_RETURN(this->AcceptMitmSession(mitm_port_handle, cmif::ServiceObjectHolder(std::move(obj)), std::forward<std::shared_ptr<::Service>>(fsrv)));
}
#endif
Result ProcessRequest(ServerSession *session, const cmif::PointerAndSize &message);
virtual ServerSessionManager *GetSessionManagerByTag(u32 tag) {
/* This is unused. */
AMS_UNUSED(tag);
return this;
}
};
}