skyline/app/src/main/cpp/skyline/services/base_service.cpp
Billy Laws 51f4e7662e Add support for the TIPC protocol introduced in HOS 12.0.0
TIPC is a much lighter layer ontop of the Horizon IPC system than CMIF and is used by SM in 12.0.0+. This implementation is slightly hacky since it doesn't really keep a seperation between the underlying kernel IPC stuff and userspace like CMIF/TIPC, this should be fixed eventually, probably together with an IPC dispatch rewrite to avoid the mess of frozen maps.

Tested with Hentai Uni, which now crashes needing 'ldr:ro'.
2022-09-02 23:13:23 +01:00

44 lines
1.8 KiB
C++

// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <cxxabi.h>
#include <common/trace.h>
#include "base_service.h"
namespace skyline::service {
const std::string &BaseService::GetName() {
if (name.empty()) {
auto mangledName{typeid(*this).name()};
int status{};
size_t length{};
std::unique_ptr<char, decltype(&std::free)> demangled{abi::__cxa_demangle(mangledName, nullptr, &length, &status), std::free};
name = (status == 0) ? std::string(demangled.get() + std::char_traits<char>::length("skyline::service::")) : mangledName;
}
return name;
}
Result service::BaseService::HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
ServiceFunctionDescriptor function;
u32 functionId{request.isTipc ? static_cast<u32>(request.header->type) : request.payload->value};
try {
function = GetServiceFunction(functionId, request.isTipc);
Logger::DebugNoPrefix("Service: {}", function.name);
} catch (const std::out_of_range &) {
Logger::Warn("Cannot find {0} function in service '{1}': 0x{2:X} ({2})", request.isTipc ? "TIPC" : "HIPC", GetName(), static_cast<u32>(functionId));
return {};
}
TRACE_EVENT("service", perfetto::StaticString{function.name});
try {
return function(session, request, response);
} catch (exception &e) {
// We need to forward any skyline::exception objects without modification even though they inherit from std::exception
std::rethrow_exception(std::current_exception());
} catch (const std::exception &e) {
throw exception("{} (Service: {})", e.what(), function.name);
}
}
}