/* * 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 . */ #include #include "sm_tipc_server.hpp" #include "sm_user_service.hpp" #include "sm_manager_service.hpp" #include "sm_wait_list.hpp" #include "impl/sm_service_manager.hpp" namespace ams::sm { namespace { /* Server limit definitions. */ enum PortIndex : size_t { PortIndex_Manager, PortIndex_User, PortIndex_Count, }; constexpr inline size_t NumTipcPorts = static_cast(PortIndex_Count); constexpr inline size_t MaxSessionsManager = 1; constexpr inline size_t MaxSessionsUser = 0x50 + 8 - MaxSessionsManager; constexpr inline size_t MaxSessionsTotal = MaxSessionsManager + MaxSessionsUser; static_assert(MaxSessionsTotal % NumTipcPorts == 0); /* Define port metadata. */ using UserPortMeta = tipc::PortMeta; using ManagerPortMeta = tipc::PortMeta; /* Define server manager global. */ using ServerManager = tipc::ServerManager; ServerManager g_server_manager; } void InitializeTipcServer() { /* Initialize the server manager. */ g_server_manager.Initialize(); /* Create the handles for our ports. */ os::NativeHandle user_port_handle, manager_port_handle; { /* Create the user port handle. */ R_ABORT_UNLESS(svc::ManageNamedPort(std::addressof(user_port_handle), "sm:", MaxSessionsUser)); /* Create the manager port handle. */ R_ABORT_UNLESS(impl::RegisterServiceForSelf(std::addressof(manager_port_handle), sm::ServiceName::Encode("sm:m"), MaxSessionsManager)); } /* Register the ports. */ g_server_manager.RegisterPort(manager_port_handle); g_server_manager.RegisterPort(user_port_handle); } void LoopProcessTipcServer() { /* Loop processing the server on all threads. */ g_server_manager.LoopAuto(AMS_GET_SYSTEM_THREAD_PRIORITY(sm, DispatcherThread), AMS_GET_SYSTEM_THREAD_NAME(sm, DispatcherThread)); } void TriggerResume(sm::ServiceName service_name) { /* Trigger a resumption. */ g_server_manager.TriggerResume(service_name); } }