mirror of
https://git.citron-emu.org/Citron/Citron.git
synced 2025-01-31 21:26:57 +01:00
service: sm: Update to match official IPC interface
Updates the SM service implementation to better match the official "nn::sm::detail::IUserInterface" interface. Key changes include: - Replace Initialize with RegisterClient command (cmd 0) - Add DetachClient command implementation (cmd 4) - Update service name handling to use u64-encoded names - Add proper PID descriptor handling for RegisterClient/DetachClient - Add ResultNotAllowed error code - Update handler registration for both CMIF and TIPC This brings the implementation closer to the official documentation while maintaining compatibility with existing code. Refs: switchbrew.org/wiki/Services_API#sm:
This commit is contained in:
parent
58ed33dd9f
commit
5ba970b574
2 changed files with 36 additions and 6 deletions
|
@ -22,6 +22,7 @@ constexpr Result ResultInvalidClient(ErrorModule::SM, 2);
|
||||||
constexpr Result ResultAlreadyRegistered(ErrorModule::SM, 4);
|
constexpr Result ResultAlreadyRegistered(ErrorModule::SM, 4);
|
||||||
constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6);
|
constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6);
|
||||||
constexpr Result ResultNotRegistered(ErrorModule::SM, 7);
|
constexpr Result ResultNotRegistered(ErrorModule::SM, 7);
|
||||||
|
constexpr Result ResultNotAllowed(ErrorModule::SM, 1);
|
||||||
|
|
||||||
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
|
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
|
||||||
controller_interface = std::make_unique<Controller>(kernel.System());
|
controller_interface = std::make_unique<Controller>(kernel.System());
|
||||||
|
@ -157,9 +158,10 @@ void SM::GetServiceTipc(HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string PopServiceName(IPC::RequestParser& rp) {
|
static std::string PopServiceName(IPC::RequestParser& rp) {
|
||||||
auto name_buf = rp.PopRaw<std::array<char, 8>>();
|
const u64 name_encoded = rp.PopRaw<u64>();
|
||||||
std::string result;
|
std::string result;
|
||||||
for (const auto& c : name_buf) {
|
for (int i = 0; i < 8; i++) {
|
||||||
|
const char c = static_cast<char>((name_encoded >> (i * 8)) & 0xFF);
|
||||||
if (c >= ' ' && c <= '~') {
|
if (c >= ' ' && c <= '~') {
|
||||||
result.push_back(c);
|
result.push_back(c);
|
||||||
}
|
}
|
||||||
|
@ -250,22 +252,48 @@ void SM::UnregisterService(HLERequestContext& ctx) {
|
||||||
rb.Push(service_manager.UnregisterService(name));
|
rb.Push(service_manager.UnregisterService(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SM::RegisterClient(HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service_SM, "called");
|
||||||
|
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
// Read PID descriptor
|
||||||
|
rp.Skip(2, false); // Skip PID descriptor and reserved u64
|
||||||
|
|
||||||
|
ctx.GetManager()->SetIsInitializedForSm();
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SM::DetachClient(HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service_SM, "called");
|
||||||
|
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
rp.Skip(2, false); // Skip PID descriptor and reserved u64
|
||||||
|
|
||||||
|
ctx.GetManager()->SetIsInitializedForSm();
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
SM::SM(ServiceManager& service_manager_, Core::System& system_)
|
SM::SM(ServiceManager& service_manager_, Core::System& system_)
|
||||||
: ServiceFramework{system_, "sm:", 4},
|
: ServiceFramework{system_, "sm:", 4},
|
||||||
service_manager{service_manager_}, kernel{system_.Kernel()} {
|
service_manager{service_manager_}, kernel{system_.Kernel()} {
|
||||||
RegisterHandlers({
|
RegisterHandlers({
|
||||||
{0, &SM::Initialize, "Initialize"},
|
{0, &SM::RegisterClient, "RegisterClient"},
|
||||||
{1, &SM::GetServiceCmif, "GetService"},
|
{1, &SM::GetServiceCmif, "GetService"},
|
||||||
{2, &SM::RegisterServiceCmif, "RegisterService"},
|
{2, &SM::RegisterServiceCmif, "RegisterService"},
|
||||||
{3, &SM::UnregisterService, "UnregisterService"},
|
{3, &SM::UnregisterService, "UnregisterService"},
|
||||||
{4, nullptr, "DetachClient"},
|
{4, &SM::DetachClient, "DetachClient"},
|
||||||
});
|
});
|
||||||
RegisterHandlersTipc({
|
RegisterHandlersTipc({
|
||||||
{0, &SM::Initialize, "Initialize"},
|
{0, &SM::RegisterClient, "RegisterClient"},
|
||||||
{1, &SM::GetServiceTipc, "GetService"},
|
{1, &SM::GetServiceTipc, "GetService"},
|
||||||
{2, &SM::RegisterServiceTipc, "RegisterService"},
|
{2, &SM::RegisterServiceTipc, "RegisterService"},
|
||||||
{3, &SM::UnregisterService, "UnregisterService"},
|
{3, &SM::UnregisterService, "UnregisterService"},
|
||||||
{4, nullptr, "DetachClient"},
|
{4, &SM::DetachClient, "DetachClient"},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,14 @@ public:
|
||||||
~SM() override;
|
~SM() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void RegisterClient(HLERequestContext& ctx);
|
||||||
void Initialize(HLERequestContext& ctx);
|
void Initialize(HLERequestContext& ctx);
|
||||||
void GetServiceCmif(HLERequestContext& ctx);
|
void GetServiceCmif(HLERequestContext& ctx);
|
||||||
void GetServiceTipc(HLERequestContext& ctx);
|
void GetServiceTipc(HLERequestContext& ctx);
|
||||||
void RegisterServiceCmif(HLERequestContext& ctx);
|
void RegisterServiceCmif(HLERequestContext& ctx);
|
||||||
void RegisterServiceTipc(HLERequestContext& ctx);
|
void RegisterServiceTipc(HLERequestContext& ctx);
|
||||||
void UnregisterService(HLERequestContext& ctx);
|
void UnregisterService(HLERequestContext& ctx);
|
||||||
|
void DetachClient(HLERequestContext& ctx);
|
||||||
|
|
||||||
Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx);
|
Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx);
|
||||||
void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count,
|
void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count,
|
||||||
|
|
Loading…
Reference in a new issue