Browse Source
Service: Make service registration part of the sm implementation
Service: Make service registration part of the sm implementation
Also enhances the GetServiceHandle implementation to be more accurate.pull/15/merge
6 changed files with 147 additions and 24 deletions
-
2src/core/CMakeLists.txt
-
15src/core/hle/service/service.cpp
-
2src/core/hle/service/service.h
-
58src/core/hle/service/sm/sm.cpp
-
49src/core/hle/service/sm/sm.h
-
45src/core/hle/service/sm/srv.cpp
@ -0,0 +1,58 @@ |
|||||
|
// Copyright 2017 Citra Emulator Project
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include <tuple>
|
||||
|
#include "core/hle/kernel/client_session.h"
|
||||
|
#include "core/hle/kernel/server_port.h"
|
||||
|
#include "core/hle/result.h"
|
||||
|
#include "core/hle/service/sm/sm.h"
|
||||
|
|
||||
|
namespace Service { |
||||
|
namespace SM { |
||||
|
|
||||
|
static ResultCode ValidateServiceName(const std::string& name) { |
||||
|
if (name.size() <= 0 || name.size() > 8) { |
||||
|
return ERR_INVALID_NAME_SIZE; |
||||
|
} |
||||
|
if (name.find('\0') != std::string::npos) { |
||||
|
return ERR_NAME_CONTAINS_NUL; |
||||
|
} |
||||
|
return RESULT_SUCCESS; |
||||
|
} |
||||
|
|
||||
|
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService( |
||||
|
std::string name, unsigned int max_sessions) { |
||||
|
|
||||
|
CASCADE_CODE(ValidateServiceName(name)); |
||||
|
Kernel::SharedPtr<Kernel::ServerPort> server_port; |
||||
|
Kernel::SharedPtr<Kernel::ClientPort> client_port; |
||||
|
std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, name); |
||||
|
|
||||
|
registered_services.emplace(name, std::move(client_port)); |
||||
|
return MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)); |
||||
|
} |
||||
|
|
||||
|
ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> ServiceManager::GetServicePort( |
||||
|
const std::string& name) { |
||||
|
|
||||
|
CASCADE_CODE(ValidateServiceName(name)); |
||||
|
auto it = registered_services.find(name); |
||||
|
if (it == registered_services.end()) { |
||||
|
return ERR_SERVICE_NOT_REGISTERED; |
||||
|
} |
||||
|
|
||||
|
return MakeResult<Kernel::SharedPtr<Kernel::ClientPort>>(it->second); |
||||
|
} |
||||
|
|
||||
|
ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ServiceManager::ConnectToService( |
||||
|
const std::string& name) { |
||||
|
|
||||
|
CASCADE_RESULT(auto client_port, GetServicePort(name)); |
||||
|
return client_port->Connect(); |
||||
|
} |
||||
|
|
||||
|
std::unique_ptr<ServiceManager> g_service_manager; |
||||
|
|
||||
|
} // namespace SM
|
||||
|
} // namespace Service
|
||||
@ -0,0 +1,49 @@ |
|||||
|
// Copyright 2017 Citra Emulator Project |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <string> |
||||
|
#include <unordered_map> |
||||
|
#include "core/hle/kernel/kernel.h" |
||||
|
#include "core/hle/result.h" |
||||
|
#include "core/hle/service/service.h" |
||||
|
|
||||
|
namespace Kernel { |
||||
|
class ClientPort; |
||||
|
class ClientSession; |
||||
|
class ServerPort; |
||||
|
class SessionRequestHandler; |
||||
|
} // namespace Kernel |
||||
|
|
||||
|
namespace Service { |
||||
|
namespace SM { |
||||
|
|
||||
|
constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(1, ErrorModule::SRV, ErrorSummary::WouldBlock, |
||||
|
ErrorLevel::Temporary); // 0xD0406401 |
||||
|
constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(2, ErrorModule::SRV, ErrorSummary::WouldBlock, |
||||
|
ErrorLevel::Temporary); // 0xD0406402 |
||||
|
constexpr ResultCode ERR_INVALID_NAME_SIZE(5, ErrorModule::SRV, ErrorSummary::WrongArgument, |
||||
|
ErrorLevel::Permanent); // 0xD9006405 |
||||
|
constexpr ResultCode ERR_ACCESS_DENIED(6, ErrorModule::SRV, ErrorSummary::InvalidArgument, |
||||
|
ErrorLevel::Permanent); // 0xD8E06406 |
||||
|
constexpr ResultCode ERR_NAME_CONTAINS_NUL(7, ErrorModule::SRV, ErrorSummary::WrongArgument, |
||||
|
ErrorLevel::Permanent); // 0xD9006407 |
||||
|
|
||||
|
class ServiceManager { |
||||
|
public: |
||||
|
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name, |
||||
|
unsigned int max_sessions); |
||||
|
ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> GetServicePort(const std::string& name); |
||||
|
ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ConnectToService(const std::string& name); |
||||
|
|
||||
|
private: |
||||
|
/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. |
||||
|
std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> registered_services; |
||||
|
}; |
||||
|
|
||||
|
extern std::unique_ptr<ServiceManager> g_service_manager; |
||||
|
|
||||
|
} // namespace SM |
||||
|
} // namespace Service |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue