Merge branch 'bcat-add-new-functions-services' into 'master'

core/hle/service/bcat: Fix compilation errors and implement missing services

See merge request citron/rewrite!31
This commit is contained in:
Zephyron
2025-07-05 13:16:14 +00:00
19 changed files with 850 additions and 68 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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<size_t>(type));
}
Result IBcatService::CancelSyncDeliveryCacheRequest() {
LOG_WARNING(Service_BCAT, "(STUBBED) called");
R_SUCCEED();
}
Result IBcatService::RequestSyncDeliveryCacheWithApplicationId(u64 application_id, OutInterface<IDeliveryCacheProgressService> out_interface) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id);
auto& progress_backend{GetProgressBackend(SyncType::Normal)};
*out_interface = std::make_shared<IDeliveryCacheProgressService>(
system, progress_backend.GetEvent(), progress_backend.GetImpl());
R_SUCCEED();
}
Result IBcatService::RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName(
const DirectoryName& name_raw, u64 application_id, OutInterface<IDeliveryCacheProgressService> 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<IDeliveryCacheProgressService>(
system, progress_backend.GetEvent(), progress_backend.GetImpl());
R_SUCCEED();
}
Result IBcatService::GetDeliveryCacheStorageUpdateNotifier(u64 application_id, OutInterface<INotifierService> out_interface) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id);
*out_interface = std::make_shared<INotifierService>(system);
R_SUCCEED();
}
Result IBcatService::RequestSuspendDeliveryTask(u64 application_id, OutInterface<IDeliveryTaskSuspensionService> out_interface) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id);
*out_interface = std::make_shared<IDeliveryTaskSuspensionService>(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<BufferAttr_HipcPointer> task_buffer) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size());
R_SUCCEED();
}
Result IBcatService::UnregisterDeliveryTask(InBuffer<BufferAttr_HipcPointer> task_buffer) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size());
R_SUCCEED();
}
Result IBcatService::BlockDeliveryTask(InBuffer<BufferAttr_HipcPointer> task_buffer) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size());
R_SUCCEED();
}
Result IBcatService::UnblockDeliveryTask(InBuffer<BufferAttr_HipcPointer> task_buffer) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, task_buffer_size={}", task_buffer.size());
R_SUCCEED();
}
Result IBcatService::SetDeliveryTaskTimer(InBuffer<BufferAttr_HipcPointer> 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<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
LOG_WARNING(Service_BCAT, "(STUBBED) called");
*out_count = 0;
R_SUCCEED();
}
Result IBcatService::GetDeliveryTaskListForSystem(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
LOG_WARNING(Service_BCAT, "(STUBBED) called");
*out_count = 0;
R_SUCCEED();
}
Result IBcatService::GetDeliveryList(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> 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<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
LOG_WARNING(Service_BCAT, "(STUBBED) called");
*out_count = 0;
R_SUCCEED();
}
Result IBcatService::GetDeliveryCacheStorageUsage(u64 application_id, Out<u64> out_usage) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}", application_id);
*out_usage = 0;
R_SUCCEED();
}
} // namespace Service::BCAT

View File

@@ -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<IBcatService> {
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<IDeliveryCacheProgressService> out_interface);
Result RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName(const DirectoryName& name_raw, u64 application_id, OutInterface<IDeliveryCacheProgressService> out_interface);
Result GetDeliveryCacheStorageUpdateNotifier(u64 application_id, OutInterface<INotifierService> out_interface);
Result RequestSuspendDeliveryTask(u64 application_id, OutInterface<IDeliveryTaskSuspensionService> 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<BufferAttr_HipcPointer> task_buffer);
Result UnregisterDeliveryTask(InBuffer<BufferAttr_HipcPointer> task_buffer);
Result BlockDeliveryTask(InBuffer<BufferAttr_HipcPointer> task_buffer);
Result UnblockDeliveryTask(InBuffer<BufferAttr_HipcPointer> task_buffer);
Result SetDeliveryTaskTimer(InBuffer<BufferAttr_HipcPointer> task_buffer, u64 timer_value);
Result GetDeliveryTaskList(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
Result GetDeliveryTaskListForSystem(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
Result GetDeliveryList(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
Result ClearDeliveryTaskSubscriptionStatus(u64 application_id);
Result GetPushNotificationLog(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
Result GetDeliveryCacheStorageUsage(u64 application_id, Out<u64> out_usage);
private:
ProgressServiceBackend& GetProgressBackend(SyncType type);
const ProgressServiceBackend& GetProgressBackend(SyncType type) const;

View File

@@ -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<Kernel::KReadableEvent> 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

View File

@@ -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<IDeliveryTaskSuspensionService> {
public:
explicit IDeliveryTaskSuspensionService(Core::System& system_);
~IDeliveryTaskSuspensionService() override;
private:
Result GetSuspensionCompletionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result Resume();
Kernel::KEvent* suspension_completion_event;
KernelHelpers::ServiceContext service_context;
};
} // namespace Service::BCAT

View File

@@ -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<BufferAttr_HipcPointer> news_id) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, news_id_size={}", news_id.size());
R_SUCCEED();
}
Result INewsDataService::OpenWithNewsRecordV1(InBuffer<BufferAttr_HipcPointer> news_record_v1) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, news_record_v1_size={}", news_record_v1.size());
R_SUCCEED();
}
Result INewsDataService::Read(Out<u64> out_read_size, u64 offset, OutBuffer<BufferAttr_HipcMapAlias> 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<u64> out_size) {
LOG_WARNING(Service_BCAT, "(STUBBED) called");
*out_size = 0;
R_SUCCEED();
}
Result INewsDataService::OpenWithNewsRecord(InBuffer<BufferAttr_HipcPointer> news_record) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, news_record_size={}", news_record.size());
R_SUCCEED();
}
} // namespace Service::News

View File

@@ -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<INewsDataService> {
public:
explicit INewsDataService(Core::System& system_);
~INewsDataService() override;
private:
Result Open(InBuffer<BufferAttr_HipcPointer> news_id);
Result OpenWithNewsRecordV1(InBuffer<BufferAttr_HipcPointer> news_record_v1);
Result Read(Out<u64> out_read_size, u64 offset, OutBuffer<BufferAttr_HipcMapAlias> out_buffer);
Result GetSize(Out<u64> out_size);
Result OpenWithNewsRecord(InBuffer<BufferAttr_HipcPointer> news_record);
};
} // namespace Service::News

View File

@@ -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<s32> out_count, u32 value,
R_SUCCEED();
}
Result INewsDatabaseService::GetListV1(Out<s32> out_count, u32 value,
OutBuffer<BufferAttr_HipcMapAlias> out_buffer_data,
InBuffer<BufferAttr_HipcPointer> buffer_data_1,
InBuffer<BufferAttr_HipcPointer> 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<s32> out_count,
InBuffer<BufferAttr_HipcPointer> 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<BufferAttr_HipcPointer> buffer_data_1,
InBuffer<BufferAttr_HipcPointer> 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<BufferAttr_HipcPointer> buffer_data_1,
InBuffer<BufferAttr_HipcPointer> buffer_data_2,
InBuffer<BufferAttr_HipcPointer> 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

View File

@@ -27,6 +27,18 @@ private:
OutBuffer<BufferAttr_HipcMapAlias> out_buffer_data,
InBuffer<BufferAttr_HipcPointer> buffer_data_1,
InBuffer<BufferAttr_HipcPointer> buffer_data_2);
// Additional News Database functions
Result GetListV1(Out<s32> out_count, u32 value,
OutBuffer<BufferAttr_HipcMapAlias> out_buffer_data,
InBuffer<BufferAttr_HipcPointer> buffer_data_1,
InBuffer<BufferAttr_HipcPointer> buffer_data_2);
Result CountWithKey(Out<s32> out_count, InBuffer<BufferAttr_HipcPointer> key_buffer);
Result UpdateIntegerValue(u32 value, InBuffer<BufferAttr_HipcPointer> buffer_data_1,
InBuffer<BufferAttr_HipcPointer> buffer_data_2);
Result UpdateStringValue(InBuffer<BufferAttr_HipcPointer> buffer_data_1,
InBuffer<BufferAttr_HipcPointer> buffer_data_2,
InBuffer<BufferAttr_HipcPointer> buffer_data_3);
};
} // namespace Service::News

View File

@@ -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<BufferAttr_HipcPointer> news_data) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, news_data_size={}", news_data.size());
R_SUCCEED();
}
Result INewsService::SetPassphrase(u64 application_id, InBuffer<BufferAttr_HipcPointer> passphrase) {
LOG_WARNING(Service_BCAT, "(STUBBED) called, application_id={:016X}, passphrase_size={}", application_id, passphrase.size());
R_SUCCEED();
}
Result INewsService::GetTopicList(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> 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<BufferAttr_HipcPointer> archive_data, OutBuffer<BufferAttr_HipcMapAlias> 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<BufferAttr_HipcPointer> 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<BufferAttr_HipcMapAlias> out_database_dump) {
LOG_WARNING(Service_BCAT, "(STUBBED) called");
R_SUCCEED();
}
} // namespace Service::News

View File

@@ -23,6 +23,24 @@ private:
Result IsSystemUpdateRequired(Out<bool> out_is_system_update_required);
Result RequestAutoSubscription(u64 value);
// Additional News service functions
Result PostLocalNews(InBuffer<BufferAttr_HipcPointer> news_data);
Result SetPassphrase(u64 application_id, InBuffer<BufferAttr_HipcPointer> passphrase);
Result GetTopicList(Out<s32> out_count, OutArray<u8, BufferAttr_HipcMapAlias> out_topics);
Result Unknown30110();
Result Unknown30201();
Result Unknown30210();
Result RequestImmediateReception();
Result DecodeArchiveFile(InBuffer<BufferAttr_HipcPointer> archive_data, OutBuffer<BufferAttr_HipcMapAlias> out_decoded_data);
Result Unknown30500();
Result Unknown30900();
Result Unknown30901();
Result Unknown30902();
Result SetSubscriptionStatus(InBuffer<BufferAttr_HipcPointer> subscription_data);
Result ClearStorage();
Result ClearSubscriptionStatusAll();
Result GetNewsDatabaseDump(OutBuffer<BufferAttr_HipcMapAlias> out_database_dump);
};
} // namespace Service::News

View File

@@ -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<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BCAT, "(STUBBED) called");
*out_event = &notification_event->GetReadableEvent();
R_SUCCEED();
}
} // namespace Service::BCAT

View File

@@ -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<INotifierService> {
public:
explicit INotifierService(Core::System& system_);
~INotifierService() override;
private:
Result GetNotificationEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Kernel::KEvent* notification_event;
KernelHelpers::ServiceContext service_context;
};
} // namespace Service::BCAT

View File

@@ -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<BcatBackend> 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<IDeliveryCacheProgressService> out_interface) {
LOG_INFO(Service_BCAT, "called, process_id={}", process_id.pid);
auto& progress_backend = progress.at(static_cast<size_t>(SyncType::Normal));
*out_interface = std::make_shared<IDeliveryCacheProgressService>(
system, progress_backend.GetEvent(), progress_backend.GetImpl());
R_SUCCEED();
}
Result IServiceCreator::CreateDeliveryCacheProgressServiceWithApplicationId(
u64 application_id, OutInterface<IDeliveryCacheProgressService> out_interface) {
LOG_INFO(Service_BCAT, "called, application_id={:016X}", application_id);
auto& progress_backend = progress.at(static_cast<size_t>(SyncType::Normal));
*out_interface = std::make_shared<IDeliveryCacheProgressService>(
system, progress_backend.GetEvent(), progress_backend.GetImpl());
R_SUCCEED();
}
} // namespace Service::BCAT

View File

@@ -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<IServiceCreator> {
public:
@@ -33,8 +37,15 @@ private:
Result CreateDeliveryCacheStorageServiceWithApplicationId(
u64 application_id, OutInterface<IDeliveryCacheStorageService> out_interface);
Result CreateDeliveryCacheProgressService(
ClientProcessId process_id, OutInterface<IDeliveryCacheProgressService> out_interface);
Result CreateDeliveryCacheProgressServiceWithApplicationId(
u64 application_id, OutInterface<IDeliveryCacheProgressService> out_interface);
std::unique_ptr<BcatBackend> backend;
Service::FileSystem::FileSystemController& fsc;
std::array<ProgressServiceBackend, static_cast<size_t>(SyncType::Count)> progress;
};
} // namespace Service::BCAT

View File

@@ -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<MNPP_SYS> {
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<MNPP_WEB> {
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<ServerManager>(system);
server_manager->RegisterNamedService("mnpp:app", std::make_shared<MNPP_APP>(system));
server_manager->RegisterNamedService("mnpp:sys", std::make_shared<MNPP_SYS>(system));
server_manager->RegisterNamedService("mnpp:web", std::make_shared<MNPP_WEB>(system));
ServerManager::RunServer(std::move(server_manager));
}

View File

@@ -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<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, 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) {

View File

@@ -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