From 99cff6cb9ccb49ac78700f799a2b850b6132dda4 Mon Sep 17 00:00:00 2001 From: Zephyron Date: Sat, 5 Jul 2025 23:12:39 +1000 Subject: [PATCH] core/hle/service/bcat: Fix compilation errors and implement missing services - Fix CMIF serialization alignment error in RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName by reordering parameters (DirectoryName before u64) - Implement missing INotifierService and IDeliveryTaskSuspensionService classes with proper kernel event handling - Add missing source files to CMakeLists.txt to resolve linker errors - Update IServiceCreator to properly implement CreateDeliveryCacheProgressService methods instead of leaving them stubbed - Add ProgressServiceBackend support to IServiceCreator with proper friend class access - Fix kernel event creation by using KernelHelpers::ServiceContext instead of direct system calls - Add proper includes for kernel_helpers.h and event management Signed-off-by: Zephyron --- src/core/CMakeLists.txt | 4 + src/core/hle/service/bcat/backend/backend.h | 2 + src/core/hle/service/bcat/bcat_service.cpp | 171 ++++++++++++++-- src/core/hle/service/bcat/bcat_service.h | 26 +++ .../bcat/delivery_task_suspension_service.cpp | 38 ++++ .../bcat/delivery_task_suspension_service.h | 34 +++ .../service/bcat/news/news_data_service.cpp | 38 +++- .../hle/service/bcat/news/news_data_service.h | 8 + .../bcat/news/news_database_service.cpp | 41 +++- .../service/bcat/news/news_database_service.h | 12 ++ .../hle/service/bcat/news/news_service.cpp | 113 ++++++++-- src/core/hle/service/bcat/news/news_service.h | 18 ++ .../hle/service/bcat/notifier_service.cpp | 32 +++ src/core/hle/service/bcat/notifier_service.h | 33 +++ src/core/hle/service/bcat/service_creator.cpp | 31 ++- src/core/hle/service/bcat/service_creator.h | 11 + src/core/hle/service/mnpp/mnpp_app.cpp | 112 +++++++++- src/core/hle/service/prepo/prepo.cpp | 193 ++++++++++++++++-- src/video_core/buffer_cache/buffer_cache.h | 1 + 19 files changed, 850 insertions(+), 68 deletions(-) create mode 100644 src/core/hle/service/bcat/delivery_task_suspension_service.cpp create mode 100644 src/core/hle/service/bcat/delivery_task_suspension_service.h create mode 100644 src/core/hle/service/bcat/notifier_service.cpp create mode 100644 src/core/hle/service/bcat/notifier_service.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 01c9ae1a3..e12309cd2 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -569,6 +569,8 @@ add_library(core STATIC hle/service/bcat/delivery_cache_progress_service.h hle/service/bcat/delivery_cache_storage_service.cpp hle/service/bcat/delivery_cache_storage_service.h + hle/service/bcat/delivery_task_suspension_service.cpp + hle/service/bcat/delivery_task_suspension_service.h hle/service/bcat/news/newly_arrived_event_holder.cpp hle/service/bcat/news/newly_arrived_event_holder.h hle/service/bcat/news/news_data_service.cpp @@ -581,6 +583,8 @@ add_library(core STATIC hle/service/bcat/news/overwrite_event_holder.h hle/service/bcat/news/service_creator.cpp hle/service/bcat/news/service_creator.h + hle/service/bcat/notifier_service.cpp + hle/service/bcat/notifier_service.h hle/service/bcat/service_creator.cpp hle/service/bcat/service_creator.h hle/service/bpc/bpc.cpp diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index 3680f6c9c..54d8fb1a2 100644 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -29,6 +30,7 @@ namespace Service::BCAT { // Some of this class is implemented in module.cpp to avoid exposing the implementation structure. class ProgressServiceBackend { friend class IBcatService; + friend class IServiceCreator; public: ~ProgressServiceBackend(); diff --git a/src/core/hle/service/bcat/bcat_service.cpp b/src/core/hle/service/bcat/bcat_service.cpp index 63b1072d2..4908d1016 100644 --- a/src/core/hle/service/bcat/bcat_service.cpp +++ b/src/core/hle/service/bcat/bcat_service.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/hex_util.h" @@ -12,6 +13,8 @@ #include "core/hle/service/bcat/delivery_cache_progress_service.h" #include "core/hle/service/bcat/delivery_cache_storage_service.h" #include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/bcat/notifier_service.h" +#include "core/hle/service/bcat/delivery_task_suspension_service.h" namespace Service::BCAT { @@ -31,30 +34,30 @@ IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_) static const FunctionInfo functions[] = { {10100, D<&IBcatService::RequestSyncDeliveryCache>, "RequestSyncDeliveryCache"}, {10101, D<&IBcatService::RequestSyncDeliveryCacheWithDirectoryName>, "RequestSyncDeliveryCacheWithDirectoryName"}, - {10200, nullptr, "CancelSyncDeliveryCacheRequest"}, - {20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"}, - {20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"}, - {20300, nullptr, "GetDeliveryCacheStorageUpdateNotifier"}, - {20301, nullptr, "RequestSuspendDeliveryTask"}, - {20400, nullptr, "RegisterSystemApplicationDeliveryTask"}, - {20401, nullptr, "UnregisterSystemApplicationDeliveryTask"}, - {20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"}, + {10200, D<&IBcatService::CancelSyncDeliveryCacheRequest>, "CancelSyncDeliveryCacheRequest"}, + {20100, D<&IBcatService::RequestSyncDeliveryCacheWithApplicationId>, "RequestSyncDeliveryCacheWithApplicationId"}, + {20101, D<&IBcatService::RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName>, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"}, + {20300, D<&IBcatService::GetDeliveryCacheStorageUpdateNotifier>, "GetDeliveryCacheStorageUpdateNotifier"}, + {20301, D<&IBcatService::RequestSuspendDeliveryTask>, "RequestSuspendDeliveryTask"}, + {20400, D<&IBcatService::RegisterSystemApplicationDeliveryTask>, "RegisterSystemApplicationDeliveryTask"}, + {20401, D<&IBcatService::UnregisterSystemApplicationDeliveryTask>, "UnregisterSystemApplicationDeliveryTask"}, + {20410, D<&IBcatService::SetSystemApplicationDeliveryTaskTimer>, "SetSystemApplicationDeliveryTaskTimer"}, {30100, D<&IBcatService::SetPassphrase>, "SetPassphrase"}, - {30101, nullptr, "Unknown30101"}, - {30102, nullptr, "Unknown30102"}, - {30200, nullptr, "RegisterBackgroundDeliveryTask"}, - {30201, nullptr, "UnregisterBackgroundDeliveryTask"}, - {30202, nullptr, "BlockDeliveryTask"}, - {30203, nullptr, "UnblockDeliveryTask"}, - {30210, nullptr, "SetDeliveryTaskTimer"}, + {30101, D<&IBcatService::Unknown30101>, "Unknown30101"}, + {30102, D<&IBcatService::Unknown30102>, "Unknown30102"}, + {30200, D<&IBcatService::RegisterDeliveryTask>, "RegisterDeliveryTask"}, + {30201, D<&IBcatService::UnregisterDeliveryTask>, "UnregisterDeliveryTask"}, + {30202, D<&IBcatService::BlockDeliveryTask>, "BlockDeliveryTask"}, + {30203, D<&IBcatService::UnblockDeliveryTask>, "UnblockDeliveryTask"}, + {30210, D<&IBcatService::SetDeliveryTaskTimer>, "SetDeliveryTaskTimer"}, {30300, D<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"}, - {90100, nullptr, "EnumerateBackgroundDeliveryTask"}, - {90101, nullptr, "Unknown90101"}, - {90200, nullptr, "GetDeliveryList"}, + {90100, D<&IBcatService::GetDeliveryTaskList>, "GetDeliveryTaskList"}, + {90101, D<&IBcatService::GetDeliveryTaskListForSystem>, "GetDeliveryTaskListForSystem"}, + {90200, D<&IBcatService::GetDeliveryList>, "GetDeliveryList"}, {90201, D<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"}, - {90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"}, - {90300, nullptr, "GetPushNotificationLog"}, - {90301, nullptr, "Unknown90301"}, + {90202, D<&IBcatService::ClearDeliveryTaskSubscriptionStatus>, "ClearDeliveryTaskSubscriptionStatus"}, + {90300, D<&IBcatService::GetPushNotificationLog>, "GetPushNotificationLog"}, + {90301, D<&IBcatService::GetDeliveryCacheStorageUsage>, "GetDeliveryCacheStorageUsage"}, }; // clang-format on RegisterHandlers(functions); @@ -129,4 +132,130 @@ const ProgressServiceBackend& IBcatService::GetProgressBackend(SyncType type) co return progress.at(static_cast(type)); } +Result IBcatService::CancelSyncDeliveryCacheRequest() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IBcatService::RequestSyncDeliveryCacheWithApplicationId(u64 application_id, OutInterface out_interface) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id); + + auto& progress_backend{GetProgressBackend(SyncType::Normal)}; + + *out_interface = std::make_shared( + system, progress_backend.GetEvent(), progress_backend.GetImpl()); + R_SUCCEED(); +} + +Result IBcatService::RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName( + const DirectoryName& name_raw, u64 application_id, OutInterface out_interface) { + const auto name = Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size()); + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}, name={}", application_id, name); + + auto& progress_backend{GetProgressBackend(SyncType::Directory)}; + + *out_interface = std::make_shared( + system, progress_backend.GetEvent(), progress_backend.GetImpl()); + R_SUCCEED(); +} + +Result IBcatService::GetDeliveryCacheStorageUpdateNotifier(u64 application_id, OutInterface out_interface) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id); + + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result IBcatService::RequestSuspendDeliveryTask(u64 application_id, OutInterface out_interface) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id); + + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result IBcatService::RegisterSystemApplicationDeliveryTask(u64 application_id) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id); + R_SUCCEED(); +} + +Result IBcatService::UnregisterSystemApplicationDeliveryTask(u64 application_id) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id); + R_SUCCEED(); +} + +Result IBcatService::SetSystemApplicationDeliveryTaskTimer(u64 application_id, u64 timer_value) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}, timer_value={:016X}", application_id, timer_value); + R_SUCCEED(); +} + +Result IBcatService::Unknown30101() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IBcatService::Unknown30102() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IBcatService::RegisterDeliveryTask(InBuffer task_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size()); + R_SUCCEED(); +} + +Result IBcatService::UnregisterDeliveryTask(InBuffer task_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size()); + R_SUCCEED(); +} + +Result IBcatService::BlockDeliveryTask(InBuffer task_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size()); + R_SUCCEED(); +} + +Result IBcatService::UnblockDeliveryTask(InBuffer task_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size()); + R_SUCCEED(); +} + +Result IBcatService::SetDeliveryTaskTimer(InBuffer task_buffer, u64 timer_value) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}, timer_value={:016X}", task_buffer.size(), timer_value); + R_SUCCEED(); +} + +Result IBcatService::GetDeliveryTaskList(Out out_count, OutArray out_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + *out_count = 0; + R_SUCCEED(); +} + +Result IBcatService::GetDeliveryTaskListForSystem(Out out_count, OutArray out_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + *out_count = 0; + R_SUCCEED(); +} + +Result IBcatService::GetDeliveryList(Out out_count, OutArray out_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + *out_count = 0; + R_SUCCEED(); +} + +Result IBcatService::ClearDeliveryTaskSubscriptionStatus(u64 application_id) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id); + R_SUCCEED(); +} + +Result IBcatService::GetPushNotificationLog(Out out_count, OutArray out_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + *out_count = 0; + R_SUCCEED(); +} + +Result IBcatService::GetDeliveryCacheStorageUsage(u64 application_id, Out out_usage) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id); + *out_usage = 0; + R_SUCCEED(); +} + } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_service.h b/src/core/hle/service/bcat/bcat_service.h index dda5a2d5f..dbed77749 100644 --- a/src/core/hle/service/bcat/bcat_service.h +++ b/src/core/hle/service/bcat/bcat_service.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -16,6 +17,8 @@ namespace Service::BCAT { class BcatBackend; class IDeliveryCacheStorageService; class IDeliveryCacheProgressService; +class INotifierService; +class IDeliveryTaskSuspensionService; class IBcatService final : public ServiceFramework { public: @@ -34,6 +37,29 @@ private: Result ClearDeliveryCacheStorage(u64 application_id); + // Additional BCAT functions [2.0.0+] + Result CancelSyncDeliveryCacheRequest(); + Result RequestSyncDeliveryCacheWithApplicationId(u64 application_id, OutInterface out_interface); + Result RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName(const DirectoryName& name_raw, u64 application_id, OutInterface out_interface); + Result GetDeliveryCacheStorageUpdateNotifier(u64 application_id, OutInterface out_interface); + Result RequestSuspendDeliveryTask(u64 application_id, OutInterface out_interface); + Result RegisterSystemApplicationDeliveryTask(u64 application_id); + Result UnregisterSystemApplicationDeliveryTask(u64 application_id); + Result SetSystemApplicationDeliveryTaskTimer(u64 application_id, u64 timer_value); + Result Unknown30101(); + Result Unknown30102(); + Result RegisterDeliveryTask(InBuffer task_buffer); + Result UnregisterDeliveryTask(InBuffer task_buffer); + Result BlockDeliveryTask(InBuffer task_buffer); + Result UnblockDeliveryTask(InBuffer task_buffer); + Result SetDeliveryTaskTimer(InBuffer task_buffer, u64 timer_value); + Result GetDeliveryTaskList(Out out_count, OutArray out_buffer); + Result GetDeliveryTaskListForSystem(Out out_count, OutArray out_buffer); + Result GetDeliveryList(Out out_count, OutArray out_buffer); + Result ClearDeliveryTaskSubscriptionStatus(u64 application_id); + Result GetPushNotificationLog(Out out_count, OutArray out_buffer); + Result GetDeliveryCacheStorageUsage(u64 application_id, Out out_usage); + private: ProgressServiceBackend& GetProgressBackend(SyncType type); const ProgressServiceBackend& GetProgressBackend(SyncType type) const; diff --git a/src/core/hle/service/bcat/delivery_task_suspension_service.cpp b/src/core/hle/service/bcat/delivery_task_suspension_service.cpp new file mode 100644 index 000000000..1ef32daf4 --- /dev/null +++ b/src/core/hle/service/bcat/delivery_task_suspension_service.cpp @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/kernel/k_event.h" +#include "core/hle/service/bcat/delivery_task_suspension_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +IDeliveryTaskSuspensionService::IDeliveryTaskSuspensionService(Core::System& system_) + : ServiceFramework{system_, "IDeliveryTaskSuspensionService"}, service_context{system_, "IDeliveryTaskSuspensionService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&IDeliveryTaskSuspensionService::GetSuspensionCompletionEvent>, "GetSuspensionCompletionEvent"}, + {1, D<&IDeliveryTaskSuspensionService::Resume>, "Resume"}, + }; + // clang-format on + RegisterHandlers(functions); + suspension_completion_event = service_context.CreateEvent("IDeliveryTaskSuspensionService:Completion"); +} + +IDeliveryTaskSuspensionService::~IDeliveryTaskSuspensionService() { + service_context.CloseEvent(suspension_completion_event); +} + +Result IDeliveryTaskSuspensionService::GetSuspensionCompletionEvent(OutCopyHandle out_event) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + + *out_event = &suspension_completion_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IDeliveryTaskSuspensionService::Resume() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +} // namespace Service::BCAT \ No newline at end of file diff --git a/src/core/hle/service/bcat/delivery_task_suspension_service.h b/src/core/hle/service/bcat/delivery_task_suspension_service.h new file mode 100644 index 000000000..e14b8d995 --- /dev/null +++ b/src/core/hle/service/bcat/delivery_task_suspension_service.h @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Service::BCAT { + +class IDeliveryTaskSuspensionService final : public ServiceFramework { +public: + explicit IDeliveryTaskSuspensionService(Core::System& system_); + ~IDeliveryTaskSuspensionService() override; + +private: + Result GetSuspensionCompletionEvent(OutCopyHandle out_event); + Result Resume(); + + Kernel::KEvent* suspension_completion_event; + KernelHelpers::ServiceContext service_context; +}; + +} // namespace Service::BCAT \ No newline at end of file diff --git a/src/core/hle/service/bcat/news/news_data_service.cpp b/src/core/hle/service/bcat/news/news_data_service.cpp index 08103c9c3..bd3f511b4 100644 --- a/src/core/hle/service/bcat/news/news_data_service.cpp +++ b/src/core/hle/service/bcat/news/news_data_service.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "core/hle/service/bcat/news/news_data_service.h" +#include "core/hle/service/cmif_serialization.h" namespace Service::News { @@ -9,11 +10,11 @@ INewsDataService::INewsDataService(Core::System& system_) : ServiceFramework{system_, "INewsDataService"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "Open"}, - {1, nullptr, "OpenWithNewsRecordV1"}, - {2, nullptr, "Read"}, - {3, nullptr, "GetSize"}, - {1001, nullptr, "OpenWithNewsRecord"}, + {0, D<&INewsDataService::Open>, "Open"}, + {1, D<&INewsDataService::OpenWithNewsRecordV1>, "OpenWithNewsRecordV1"}, + {2, D<&INewsDataService::Read>, "Read"}, + {3, D<&INewsDataService::GetSize>, "GetSize"}, + {1001, D<&INewsDataService::OpenWithNewsRecord>, "OpenWithNewsRecord"}, }; // clang-format on @@ -22,4 +23,31 @@ INewsDataService::INewsDataService(Core::System& system_) INewsDataService::~INewsDataService() = default; +Result INewsDataService::Open(InBuffer news_id) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, news_id_size={}", news_id.size()); + R_SUCCEED(); +} + +Result INewsDataService::OpenWithNewsRecordV1(InBuffer news_record_v1) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, news_record_v1_size={}", news_record_v1.size()); + R_SUCCEED(); +} + +Result INewsDataService::Read(Out out_read_size, u64 offset, OutBuffer out_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, offset={:016X}, buffer_size={:016X}", offset, out_buffer.size()); + *out_read_size = 0; + R_SUCCEED(); +} + +Result INewsDataService::GetSize(Out out_size) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + *out_size = 0; + R_SUCCEED(); +} + +Result INewsDataService::OpenWithNewsRecord(InBuffer news_record) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, news_record_size={}", news_record.size()); + R_SUCCEED(); +} + } // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_data_service.h b/src/core/hle/service/bcat/news/news_data_service.h index 12082ada4..f5e7d5ccf 100644 --- a/src/core/hle/service/bcat/news/news_data_service.h +++ b/src/core/hle/service/bcat/news/news_data_service.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" namespace Core { @@ -15,6 +16,13 @@ class INewsDataService final : public ServiceFramework { public: explicit INewsDataService(Core::System& system_); ~INewsDataService() override; + +private: + Result Open(InBuffer news_id); + Result OpenWithNewsRecordV1(InBuffer news_record_v1); + Result Read(Out out_read_size, u64 offset, OutBuffer out_buffer); + Result GetSize(Out out_size); + Result OpenWithNewsRecord(InBuffer news_record); }; } // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_database_service.cpp b/src/core/hle/service/bcat/news/news_database_service.cpp index b94ef0636..23509113e 100644 --- a/src/core/hle/service/bcat/news/news_database_service.cpp +++ b/src/core/hle/service/bcat/news/news_database_service.cpp @@ -10,12 +10,12 @@ INewsDatabaseService::INewsDatabaseService(Core::System& system_) : ServiceFramework{system_, "INewsDatabaseService"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "GetListV1"}, + {0, D<&INewsDatabaseService::GetListV1>, "GetListV1"}, {1, D<&INewsDatabaseService::Count>, "Count"}, - {2, nullptr, "CountWithKey"}, - {3, nullptr, "UpdateIntegerValue"}, + {2, D<&INewsDatabaseService::CountWithKey>, "CountWithKey"}, + {3, D<&INewsDatabaseService::UpdateIntegerValue>, "UpdateIntegerValue"}, {4, D<&INewsDatabaseService::UpdateIntegerValueWithAddition>, "UpdateIntegerValueWithAddition"}, - {5, nullptr, "UpdateStringValue"}, + {5, D<&INewsDatabaseService::UpdateStringValue>, "UpdateStringValue"}, {1000, D<&INewsDatabaseService::GetList>, "GetList"}, }; // clang-format on @@ -50,4 +50,37 @@ Result INewsDatabaseService::GetList(Out out_count, u32 value, R_SUCCEED(); } +Result INewsDatabaseService::GetListV1(Out out_count, u32 value, + OutBuffer out_buffer_data, + InBuffer buffer_data_1, + InBuffer buffer_data_2) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, value={}, buffer_size_1={}, buffer_data_2={}", + value, buffer_data_1.size(), buffer_data_2.size()); + *out_count = 0; + R_SUCCEED(); +} + +Result INewsDatabaseService::CountWithKey(Out out_count, + InBuffer key_buffer) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, key_buffer_size={}", key_buffer.size()); + *out_count = 0; + R_SUCCEED(); +} + +Result INewsDatabaseService::UpdateIntegerValue(u32 value, + InBuffer buffer_data_1, + InBuffer buffer_data_2) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, value={}, buffer_size_1={}, buffer_data_2={}", + value, buffer_data_1.size(), buffer_data_2.size()); + R_SUCCEED(); +} + +Result INewsDatabaseService::UpdateStringValue(InBuffer buffer_data_1, + InBuffer buffer_data_2, + InBuffer buffer_data_3) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size_1={}, buffer_size_2={}, buffer_size_3={}", + buffer_data_1.size(), buffer_data_2.size(), buffer_data_3.size()); + R_SUCCEED(); +} + } // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_database_service.h b/src/core/hle/service/bcat/news/news_database_service.h index 860b7074c..7e0c07c2b 100644 --- a/src/core/hle/service/bcat/news/news_database_service.h +++ b/src/core/hle/service/bcat/news/news_database_service.h @@ -27,6 +27,18 @@ private: OutBuffer out_buffer_data, InBuffer buffer_data_1, InBuffer buffer_data_2); + + // Additional News Database functions + Result GetListV1(Out out_count, u32 value, + OutBuffer out_buffer_data, + InBuffer buffer_data_1, + InBuffer buffer_data_2); + Result CountWithKey(Out out_count, InBuffer key_buffer); + Result UpdateIntegerValue(u32 value, InBuffer buffer_data_1, + InBuffer buffer_data_2); + Result UpdateStringValue(InBuffer buffer_data_1, + InBuffer buffer_data_2, + InBuffer buffer_data_3); }; } // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_service.cpp b/src/core/hle/service/bcat/news/news_service.cpp index bc6c2afd2..9bd1f84e0 100644 --- a/src/core/hle/service/bcat/news/news_service.cpp +++ b/src/core/hle/service/bcat/news/news_service.cpp @@ -9,25 +9,25 @@ namespace Service::News { INewsService::INewsService(Core::System& system_) : ServiceFramework{system_, "INewsService"} { // clang-format off static const FunctionInfo functions[] = { - {10100, nullptr, "PostLocalNews"}, - {20100, nullptr, "SetPassphrase"}, + {10100, D<&INewsService::PostLocalNews>, "PostLocalNews"}, + {20100, D<&INewsService::SetPassphrase>, "SetPassphrase"}, {30100, D<&INewsService::GetSubscriptionStatus>, "GetSubscriptionStatus"}, - {30101, nullptr, "GetTopicList"}, - {30110, nullptr, "Unknown30110"}, + {30101, D<&INewsService::GetTopicList>, "GetTopicList"}, + {30110, D<&INewsService::Unknown30110>, "Unknown30110"}, {30200, D<&INewsService::IsSystemUpdateRequired>, "IsSystemUpdateRequired"}, - {30201, nullptr, "Unknown30201"}, - {30210, nullptr, "Unknown30210"}, - {30300, nullptr, "RequestImmediateReception"}, - {30400, nullptr, "DecodeArchiveFile"}, - {30500, nullptr, "Unknown30500"}, - {30900, nullptr, "Unknown30900"}, - {30901, nullptr, "Unknown30901"}, - {30902, nullptr, "Unknown30902"}, - {40100, nullptr, "SetSubscriptionStatus"}, + {30201, D<&INewsService::Unknown30201>, "Unknown30201"}, + {30210, D<&INewsService::Unknown30210>, "Unknown30210"}, + {30300, D<&INewsService::RequestImmediateReception>, "RequestImmediateReception"}, + {30400, D<&INewsService::DecodeArchiveFile>, "DecodeArchiveFile"}, + {30500, D<&INewsService::Unknown30500>, "Unknown30500"}, + {30900, D<&INewsService::Unknown30900>, "Unknown30900"}, + {30901, D<&INewsService::Unknown30901>, "Unknown30901"}, + {30902, D<&INewsService::Unknown30902>, "Unknown30902"}, + {40100, D<&INewsService::SetSubscriptionStatus>, "SetSubscriptionStatus"}, {40101, D<&INewsService::RequestAutoSubscription>, "RequestAutoSubscription"}, - {40200, nullptr, "ClearStorage"}, - {40201, nullptr, "ClearSubscriptionStatusAll"}, - {90100, nullptr, "GetNewsDatabaseDump"}, + {40200, D<&INewsService::ClearStorage>, "ClearStorage"}, + {40201, D<&INewsService::ClearSubscriptionStatusAll>, "ClearSubscriptionStatusAll"}, + {90100, D<&INewsService::GetNewsDatabaseDump>, "GetNewsDatabaseDump"}, }; // clang-format on @@ -54,4 +54,85 @@ Result INewsService::RequestAutoSubscription(u64 value) { R_SUCCEED(); } +Result INewsService::PostLocalNews(InBuffer news_data) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, news_data_size={}", news_data.size()); + R_SUCCEED(); +} + +Result INewsService::SetPassphrase(u64 application_id, InBuffer passphrase) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}, passphrase_size={}", application_id, passphrase.size()); + R_SUCCEED(); +} + +Result INewsService::GetTopicList(Out out_count, OutArray out_topics) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + *out_count = 0; + R_SUCCEED(); +} + +Result INewsService::Unknown30110() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::Unknown30201() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::Unknown30210() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::RequestImmediateReception() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::DecodeArchiveFile(InBuffer archive_data, OutBuffer out_decoded_data) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, archive_size={}", archive_data.size()); + R_SUCCEED(); +} + +Result INewsService::Unknown30500() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::Unknown30900() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::Unknown30901() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::Unknown30902() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::SetSubscriptionStatus(InBuffer subscription_data) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, subscription_data_size={}", subscription_data.size()); + R_SUCCEED(); +} + +Result INewsService::ClearStorage() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::ClearSubscriptionStatusAll() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result INewsService::GetNewsDatabaseDump(OutBuffer out_database_dump) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + } // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_service.h b/src/core/hle/service/bcat/news/news_service.h index f1716a302..317a437ee 100644 --- a/src/core/hle/service/bcat/news/news_service.h +++ b/src/core/hle/service/bcat/news/news_service.h @@ -23,6 +23,24 @@ private: Result IsSystemUpdateRequired(Out out_is_system_update_required); Result RequestAutoSubscription(u64 value); + + // Additional News service functions + Result PostLocalNews(InBuffer news_data); + Result SetPassphrase(u64 application_id, InBuffer passphrase); + Result GetTopicList(Out out_count, OutArray out_topics); + Result Unknown30110(); + Result Unknown30201(); + Result Unknown30210(); + Result RequestImmediateReception(); + Result DecodeArchiveFile(InBuffer archive_data, OutBuffer out_decoded_data); + Result Unknown30500(); + Result Unknown30900(); + Result Unknown30901(); + Result Unknown30902(); + Result SetSubscriptionStatus(InBuffer subscription_data); + Result ClearStorage(); + Result ClearSubscriptionStatusAll(); + Result GetNewsDatabaseDump(OutBuffer out_database_dump); }; } // namespace Service::News diff --git a/src/core/hle/service/bcat/notifier_service.cpp b/src/core/hle/service/bcat/notifier_service.cpp new file mode 100644 index 000000000..cd927dbd0 --- /dev/null +++ b/src/core/hle/service/bcat/notifier_service.cpp @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/kernel/k_event.h" +#include "core/hle/service/bcat/notifier_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +INotifierService::INotifierService(Core::System& system_) + : ServiceFramework{system_, "INotifierService"}, service_context{system_, "INotifierService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&INotifierService::GetNotificationEvent>, "GetNotificationEvent"}, + }; + // clang-format on + RegisterHandlers(functions); + notification_event = service_context.CreateEvent("INotifierService:Notification"); +} + +INotifierService::~INotifierService() { + service_context.CloseEvent(notification_event); +} + +Result INotifierService::GetNotificationEvent(OutCopyHandle out_event) { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + + *out_event = ¬ification_event->GetReadableEvent(); + R_SUCCEED(); +} + +} // namespace Service::BCAT \ No newline at end of file diff --git a/src/core/hle/service/bcat/notifier_service.h b/src/core/hle/service/bcat/notifier_service.h new file mode 100644 index 000000000..07a84b77d --- /dev/null +++ b/src/core/hle/service/bcat/notifier_service.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Service::BCAT { + +class INotifierService final : public ServiceFramework { +public: + explicit INotifierService(Core::System& system_); + ~INotifierService() override; + +private: + Result GetNotificationEvent(OutCopyHandle out_event); + + Kernel::KEvent* notification_event; + KernelHelpers::ServiceContext service_context; +}; + +} // namespace Service::BCAT \ No newline at end of file diff --git a/src/core/hle/service/bcat/service_creator.cpp b/src/core/hle/service/bcat/service_creator.cpp index ca339e5a6..15bb5cf9d 100644 --- a/src/core/hle/service/bcat/service_creator.cpp +++ b/src/core/hle/service/bcat/service_creator.cpp @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/bcat/bcat_service.h" +#include "core/hle/service/bcat/delivery_cache_progress_service.h" #include "core/hle/service/bcat/delivery_cache_storage_service.h" #include "core/hle/service/bcat/service_creator.h" #include "core/hle/service/cmif_serialization.h" @@ -15,14 +17,17 @@ std::unique_ptr CreateBackendFromSettings([[maybe_unused]] Core::Sy } IServiceCreator::IServiceCreator(Core::System& system_, const char* name_) - : ServiceFramework{system_, name_}, fsc{system.GetFileSystemController()} { + : ServiceFramework{system_, name_}, fsc{system.GetFileSystemController()}, progress{{ + ProgressServiceBackend{system_, "Normal"}, + ProgressServiceBackend{system_, "Directory"}, + }} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IServiceCreator::CreateBcatService>, "CreateBcatService"}, {1, D<&IServiceCreator::CreateDeliveryCacheStorageService>, "CreateDeliveryCacheStorageService"}, {2, D<&IServiceCreator::CreateDeliveryCacheStorageServiceWithApplicationId>, "CreateDeliveryCacheStorageServiceWithApplicationId"}, - {3, nullptr, "CreateDeliveryCacheProgressService"}, - {4, nullptr, "CreateDeliveryCacheProgressServiceWithApplicationId"}, + {3, D<&IServiceCreator::CreateDeliveryCacheProgressService>, "CreateDeliveryCacheProgressService"}, + {4, D<&IServiceCreator::CreateDeliveryCacheProgressServiceWithApplicationId>, "CreateDeliveryCacheProgressServiceWithApplicationId"}, }; // clang-format on @@ -59,4 +64,24 @@ Result IServiceCreator::CreateDeliveryCacheStorageServiceWithApplicationId( R_SUCCEED(); } +Result IServiceCreator::CreateDeliveryCacheProgressService( + ClientProcessId process_id, OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called, process_id={}", process_id.pid); + + auto& progress_backend = progress.at(static_cast(SyncType::Normal)); + *out_interface = std::make_shared( + system, progress_backend.GetEvent(), progress_backend.GetImpl()); + R_SUCCEED(); +} + +Result IServiceCreator::CreateDeliveryCacheProgressServiceWithApplicationId( + u64 application_id, OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called, application_id={:016X}", application_id); + + auto& progress_backend = progress.at(static_cast(SyncType::Normal)); + *out_interface = std::make_shared( + system, progress_backend.GetEvent(), progress_backend.GetImpl()); + R_SUCCEED(); +} + } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/service_creator.h b/src/core/hle/service/bcat/service_creator.h index 50e663324..ca6205c06 100644 --- a/src/core/hle/service/bcat/service_creator.h +++ b/src/core/hle/service/bcat/service_creator.h @@ -1,8 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once +#include "core/hle/service/bcat/backend/backend.h" +#include "core/hle/service/bcat/bcat_types.h" #include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" @@ -18,6 +21,7 @@ namespace Service::BCAT { class BcatBackend; class IBcatService; class IDeliveryCacheStorageService; +class IDeliveryCacheProgressService; class IServiceCreator final : public ServiceFramework { public: @@ -33,8 +37,15 @@ private: Result CreateDeliveryCacheStorageServiceWithApplicationId( u64 application_id, OutInterface out_interface); + Result CreateDeliveryCacheProgressService( + ClientProcessId process_id, OutInterface out_interface); + + Result CreateDeliveryCacheProgressServiceWithApplicationId( + u64 application_id, OutInterface out_interface); + std::unique_ptr backend; Service::FileSystem::FileSystemController& fsc; + std::array(SyncType::Count)> progress; }; } // namespace Service::BCAT diff --git a/src/core/hle/service/mnpp/mnpp_app.cpp b/src/core/hle/service/mnpp/mnpp_app.cpp index b11a92056..19ceb7457 100644 --- a/src/core/hle/service/mnpp/mnpp_app.cpp +++ b/src/core/hle/service/mnpp/mnpp_app.cpp @@ -14,8 +14,93 @@ public: explicit MNPP_APP(Core::System& system_) : ServiceFramework{system_, "mnpp:app"} { // clang-format off static const FunctionInfo functions[] = { - {0, &MNPP_APP::Unknown0, "unknown0"}, - {1, &MNPP_APP::Unknown1, "unknown1"}, + {0, &MNPP_APP::Initialize, "Initialize"}, + {1, &MNPP_APP::SubmitEvent, "SubmitEvent"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void Initialize(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void SubmitEvent(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } +}; + +class MNPP_SYS final : public ServiceFramework { +public: + explicit MNPP_SYS(Core::System& system_) : ServiceFramework{system_, "mnpp:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &MNPP_SYS::Unknown0, "Unknown0"}, + {100, &MNPP_SYS::Unknown100, "Unknown100"}, + {200, &MNPP_SYS::Unknown200, "Unknown200"}, // [13.1.0-13.2.1] + {300, &MNPP_SYS::Unknown300, "Unknown300"}, // [13.1.0-14.1.2] + {400, &MNPP_SYS::Unknown400, "Unknown400"}, // [14.0.0-14.1.2] + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void Unknown0(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown100(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown200(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown300(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown400(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } +}; + +class MNPP_WEB final : public ServiceFramework { +public: + explicit MNPP_WEB(Core::System& system_) : ServiceFramework{system_, "mnpp:web"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &MNPP_WEB::Unknown0, "Unknown0"}, + {1, &MNPP_WEB::Unknown1, "Unknown1"}, // [14.0.0+] + {10, &MNPP_WEB::Unknown10, "Unknown10"}, // [14.0.0+] + {20, &MNPP_WEB::Unknown20, "Unknown20"}, // [14.0.0+] + {100, &MNPP_WEB::Unknown100, "Unknown100"}, // [16.1.0+] }; // clang-format on @@ -36,12 +121,35 @@ private: IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } + + void Unknown10(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown20(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown100(HLERequestContext& ctx) { + LOG_WARNING(Service_MNPP, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } }; void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); server_manager->RegisterNamedService("mnpp:app", std::make_shared(system)); + server_manager->RegisterNamedService("mnpp:sys", std::make_shared(system)); + server_manager->RegisterNamedService("mnpp:web", std::make_shared(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 14e8df63a..fd4614298 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp @@ -27,25 +27,26 @@ public: {10200, &PlayReport::RequestImmediateTransmission, "RequestImmediateTransmission"}, {10300, &PlayReport::GetTransmissionStatus, "GetTransmissionStatus"}, {10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"}, + {10500, &PlayReport::SendReportWithUser, "SendReportWithUser"}, {20100, &PlayReport::SaveSystemReport, "SaveSystemReport"}, {20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"}, - {20200, nullptr, "SetOperationMode"}, - {30100, nullptr, "ClearStorage"}, - {30200, nullptr, "ClearStatistics"}, - {30300, nullptr, "GetStorageUsage"}, - {30400, nullptr, "GetStatistics"}, - {30401, nullptr, "GetThroughputHistory"}, - {30500, nullptr, "GetLastUploadError"}, - {30600, nullptr, "GetApplicationUploadSummary"}, - {40100, nullptr, "IsUserAgreementCheckEnabled"}, - {40101, nullptr, "SetUserAgreementCheckEnabled"}, - {50100, nullptr, "ReadAllApplicationReportFiles"}, - {90100, nullptr, "ReadAllReportFiles"}, - {90101, nullptr, "Unknown90101"}, - {90102, nullptr, "Unknown90102"}, - {90200, nullptr, "GetStatistics"}, - {90201, nullptr, "GetThroughputHistory"}, - {90300, nullptr, "GetLastUploadError"}, + {20200, &PlayReport::SetOperationMode, "SetOperationMode"}, + {30100, &PlayReport::ClearStorage, "ClearStorage"}, + {30200, &PlayReport::ClearStatistics, "ClearStatistics"}, + {30300, &PlayReport::GetStorageUsage, "GetStorageUsage"}, + {30400, &PlayReport::GetStatistics, "GetStatistics"}, + {30401, &PlayReport::GetThroughputHistory, "GetThroughputHistory"}, + {30500, &PlayReport::GetLastUploadError, "GetLastUploadError"}, + {30600, &PlayReport::GetApplicationUploadSummary, "GetApplicationUploadSummary"}, + {40100, &PlayReport::IsUserAgreementCheckEnabled, "IsUserAgreementCheckEnabled"}, + {40101, &PlayReport::SetUserAgreementCheckEnabled, "SetUserAgreementCheckEnabled"}, + {50100, &PlayReport::ReadAllApplicationReportFiles, "ReadAllApplicationReportFiles"}, + {90100, &PlayReport::ReadAllReportFiles, "ReadAllReportFiles"}, + {90101, &PlayReport::Unknown90101, "Unknown90101"}, + {90102, &PlayReport::Unknown90102, "Unknown90102"}, + {90200, &PlayReport::GetStatisticsLegacy, "GetStatistics"}, + {90201, &PlayReport::GetThroughputHistoryLegacy, "GetThroughputHistory"}, + {90300, &PlayReport::GetLastUploadErrorLegacy, "GetLastUploadError"}, }; // clang-format on @@ -158,6 +159,164 @@ private: IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } + + void SetOperationMode(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void ClearStorage(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void ClearStatistics(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void GetStorageUsage(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 storage_usage = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(storage_usage); + } + + void GetStatistics(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 statistics = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(statistics); + } + + void GetThroughputHistory(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 throughput_history = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(throughput_history); + } + + void GetLastUploadError(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 last_upload_error = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(last_upload_error); + } + + void GetApplicationUploadSummary(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 application_upload_summary = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(application_upload_summary); + } + + void IsUserAgreementCheckEnabled(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr bool is_user_agreement_check_enabled = false; + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + rb.Push(is_user_agreement_check_enabled); + } + + void SetUserAgreementCheckEnabled(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void ReadAllApplicationReportFiles(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void ReadAllReportFiles(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown90101(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Unknown90102(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void GetStatisticsLegacy(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 statistics = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(statistics); + } + + void GetThroughputHistoryLegacy(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 throughput_history = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(throughput_history); + } + + void GetLastUploadErrorLegacy(HLERequestContext& ctx) { + LOG_WARNING(Service_PREPO, "(STUBBED) called"); + + constexpr u64 last_upload_error = 0; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(last_upload_error); + } + + void SendReportWithUser(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto user_id = rp.PopRaw(); + const auto process_id = rp.PopRaw(); + + const auto data1 = ctx.ReadBufferA(0); + const auto data2 = ctx.ReadBufferX(0); + + LOG_DEBUG(Service_PREPO, + "called, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}, " + "data2_size={:016X}", + user_id[1], user_id[0], process_id, data1.size(), data2.size()); + + const auto& reporter{system.GetReporter()}; + reporter.SavePlayReport(Core::Reporter::PlayReportType::New, system.GetApplicationProcessProgramID(), {data1, data2}, + process_id, user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } }; void LoopProcess(Core::System& system) { diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index af237703d..0c230f1fc 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once