Files
eden/src/core/hle/service/prepo/prepo.cpp
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

234 lines
9.9 KiB
C++
Raw Normal View History

// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
2018-09-11 20:46:49 -04:00
2019-05-17 21:49:21 -04:00
#include "common/hex_util.h"
#include "common/logging.h"
#include "common/uuid.h"
#include <cstring>
#include "core/core.h"
2019-05-17 21:49:21 -04:00
#include "core/hle/service/acc/profile_manager.h"
2023-02-19 14:42:12 -05:00
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/prepo/prepo.h"
2023-02-18 16:26:48 -05:00
#include "core/hle/service/server_manager.h"
2018-09-11 20:46:49 -04:00
#include "core/hle/service/service.h"
2019-05-17 21:49:21 -04:00
#include "core/reporter.h"
namespace Service::PlayReport {
2018-09-11 20:46:49 -04:00
class PlayReport final : public ServiceFramework<PlayReport> {
public:
2026-09-25 15:57:13 +00:00
explicit PlayReport(const char* name, Core::System& system_) : ServiceFramework{system_, name} {}
FunctionInfoBase const* FindRequest(u32 key) override {
return HandlerTableGenerateWithFind(key,
2026-09-25 15:53:30 +00:00
FunctionInfo{10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"},
FunctionInfo{10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"},
FunctionInfo{10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old2>, "SaveReportOld2"},
FunctionInfo{10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old2>, "SaveReportWithUserOld2"},
FunctionInfo{10104, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old3>, "SaveReportOld3"},
FunctionInfo{10105, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old3>, "SaveReportWithUserOld3"},
FunctionInfo{10106, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"},
FunctionInfo{10107, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
FunctionInfo{10200, &PlayReport::RequestImmediateTransmission, "RequestImmediateTransmission"},
FunctionInfo{10300, &PlayReport::GetTransmissionStatus, "GetTransmissionStatus"},
FunctionInfo{10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"},
FunctionInfo{20100, &PlayReport::SaveSystemReportOld, "SaveSystemReport"},
FunctionInfo{20101, &PlayReport::SaveSystemReportWithUserOld, "SaveSystemReportWithUser"},
FunctionInfo{20102, &PlayReport::SaveSystemReport, "SaveSystemReport"},
FunctionInfo{20103, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
FunctionInfo{20200, nullptr, "SetOperationMode"},
FunctionInfo{30100, nullptr, "ClearStorage"},
FunctionInfo{30200, nullptr, "ClearStatistics"},
FunctionInfo{30300, nullptr, "GetStorageUsage"},
FunctionInfo{30400, nullptr, "GetStatistics"},
FunctionInfo{30401, nullptr, "GetThroughputHistory"},
FunctionInfo{30500, nullptr, "GetLastUploadError"},
FunctionInfo{30600, nullptr, "GetApplicationUploadSummary"},
FunctionInfo{40100, nullptr, "IsUserAgreementCheckEnabled"},
FunctionInfo{40101, nullptr, "SetUserAgreementCheckEnabled"},
FunctionInfo{50100, nullptr, "ReadAllApplicationReportFiles"},
FunctionInfo{90100, nullptr, "ReadAllReportFiles"},
FunctionInfo{90101, nullptr, "Unknown90101"},
FunctionInfo{90102, nullptr, "Unknown90102"},
FunctionInfo{90200, nullptr, "GetStatistics"},
FunctionInfo{90201, nullptr, "GetThroughputHistory"},
FunctionInfo{90300, nullptr, "GetLastUploadError"}
2026-09-25 15:57:13 +00:00
);
2018-09-11 20:46:49 -04:00
}
private:
template <Core::Reporter::PlayReportType Type>
2023-02-19 14:42:12 -05:00
void SaveReport(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto process_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBufferA(0);
const auto data2 = ctx.ReadBufferX(0);
LOG_DEBUG(Service_PREPO,
"called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}",
Type, process_id, data1.size(), data2.size());
2019-09-21 19:14:15 -04:00
const auto& reporter{system.GetReporter()};
reporter.SavePlayReport(Type, system.ResolveCallerProgramId(process_id), {data1, data2},
process_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
template <Core::Reporter::PlayReportType Type>
2023-02-19 14:42:12 -05:00
void SaveReportWithUser(HLERequestContext& ctx) {
2019-05-17 21:49:21 -04:00
IPC::RequestParser rp{ctx};
const auto user_id = rp.PopRaw<u128>();
const auto process_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBufferA(0);
const auto data2 = ctx.ReadBufferX(0);
LOG_DEBUG(Service_PREPO,
"called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, "
"data1_size={:016X}, data2_size={:016X}",
Type, user_id[1], user_id[0], process_id, data1.size(), data2.size());
2019-09-21 19:14:15 -04:00
const auto& reporter{system.GetReporter()};
reporter.SavePlayReport(Type, system.ResolveCallerProgramId(process_id), {data1, data2},
process_id, user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
2023-02-19 14:42:12 -05:00
void RequestImmediateTransmission(HLERequestContext& ctx) {
2021-01-31 07:04:35 -05:00
LOG_WARNING(Service_PREPO, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
2021-01-31 07:04:35 -05:00
}
2023-02-19 14:42:12 -05:00
void GetTransmissionStatus(HLERequestContext& ctx) {
2021-01-31 07:06:48 -05:00
LOG_WARNING(Service_PREPO, "(STUBBED) called");
constexpr s32 status = 0;
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
2021-01-31 07:06:48 -05:00
rb.Push(status);
}
2023-02-19 14:42:12 -05:00
void GetSystemSessionId(HLERequestContext& ctx) {
2021-01-27 23:08:52 -06:00
LOG_WARNING(Service_PREPO, "(STUBBED) called");
constexpr u64 system_session_id = 0;
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
2021-01-27 23:08:52 -06:00
rb.Push(system_session_id);
}
void SaveSystemReportOld(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto title_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBufferA(0);
const auto data2 = ctx.ReadBufferX(0);
LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
title_id, data1.size(), data2.size());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SaveSystemReportWithUserOld(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto user_id = rp.PopRaw<u128>();
const auto title_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBufferA(0);
const auto data2 = ctx.ReadBufferX(0);
Common::UUID uuid{};
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
LOG_DEBUG(Service_PREPO,
"called, user_id={}, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
uuid.FormattedString(), title_id, data1.size(), data2.size());
2019-05-17 21:49:21 -04:00
2019-09-21 19:14:15 -04:00
const auto& reporter{system.GetReporter()};
reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2},
std::nullopt, user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
// (21.0.0+) buffers: [0x9 (X), 0x5 (A)], inbytes: 0x10
void SaveSystemReport(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto field0 = rp.PopRaw<u64>();
const auto title_id = rp.PopRaw<u64>();
const auto data_x = ctx.ReadBufferX(0);
const auto data_a = ctx.ReadBufferA(0);
LOG_DEBUG(Service_PREPO,
"called, field0={}, title_id={:016X}, data_a_size={}, data_x_size={}",
field0, title_id, data_a.size(), data_x.size());
const auto& reporter{system.GetReporter()};
reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data_a, data_x});
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
// (21.0.0+) buffers: [0x9 (X), 0x5 (A)], inbytes: 0x20
void SaveSystemReportWithUser(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
// 21.0.0+: field0 (u64), user_id (u128), title_id (u64)
const auto field0 = rp.PopRaw<u64>();
const auto user_id = rp.PopRaw<u128>();
const auto title_id = rp.PopRaw<u64>();
const auto data_x = ctx.ReadBufferX(0);
const auto data_a = ctx.ReadBufferA(0);
Common::UUID uuid{};
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
LOG_DEBUG(Service_PREPO,
"called, user_id={}, field0={:016X}, title_id={:016X}, data_a_size={}, data_x_size={}",
uuid.FormattedString(), field0, title_id, data_a.size(), data_x.size());
const auto& reporter{system.GetReporter()};
reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data_a, data_x},
std::nullopt, user_id);
2018-09-11 20:46:49 -04:00
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
2018-09-11 20:46:49 -04:00
}
};
2023-02-18 16:26:48 -05:00
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("prepo:a",
std::make_shared<PlayReport>("prepo:a", system));
server_manager->RegisterNamedService("prepo:a2",
std::make_shared<PlayReport>("prepo:a2", system));
server_manager->RegisterNamedService("prepo:m",
std::make_shared<PlayReport>("prepo:m", system));
server_manager->RegisterNamedService("prepo:s",
std::make_shared<PlayReport>("prepo:s", system));
server_manager->RegisterNamedService("prepo:u",
std::make_shared<PlayReport>("prepo:u", system));
ServerManager::RunServer(std::move(server_manager));
}
} // namespace Service::PlayReport