aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpineappleEA <pineaea@gmail.com>2024-02-09 22:10:54 +0100
committerpineappleEA <pineaea@gmail.com>2024-02-09 22:10:54 +0100
commit60f0c16bdf4b852d854d10b8448eaf675d2371a0 (patch)
tree424b7b8dbc91b6c2013c44c23d421decb0ae2319
parentb48b6e3b79c09c46384627ce7ae47a81f77187b8 (diff)
early-access version 4126EA-4126
-rwxr-xr-xREADME.md2
-rwxr-xr-xsrc/core/CMakeLists.txt29
-rwxr-xr-xsrc/core/file_sys/errors.h1
-rwxr-xr-xsrc/core/hle/service/bcat/backend/backend.cpp30
-rwxr-xr-xsrc/core/hle/service/bcat/backend/backend.h54
-rwxr-xr-xsrc/core/hle/service/bcat/bcat.cpp42
-rwxr-xr-xsrc/core/hle/service/bcat/bcat.h9
-rwxr-xr-xsrc/core/hle/service/bcat/bcat_result.h15
-rwxr-xr-xsrc/core/hle/service/bcat/bcat_service.cpp132
-rwxr-xr-xsrc/core/hle/service/bcat/bcat_service.h45
-rwxr-xr-xsrc/core/hle/service/bcat/bcat_types.h66
-rwxr-xr-xsrc/core/hle/service/bcat/bcat_util.h39
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_directory_service.cpp80
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_directory_service.h33
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_file_service.cpp82
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_file_service.h33
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_progress_service.cpp41
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_progress_service.h35
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_storage_service.cpp57
-rwxr-xr-xsrc/core/hle/service/bcat/delivery_cache_storage_service.h36
-rwxr-xr-xsrc/core/hle/service/bcat/news/newly_arrived_event_holder.cpp34
-rwxr-xr-xsrc/core/hle/service/bcat/news/newly_arrived_event_holder.h33
-rwxr-xr-xsrc/core/hle/service/bcat/news/news_data_service.cpp25
-rwxr-xr-xsrc/core/hle/service/bcat/news/news_data_service.h20
-rwxr-xr-xsrc/core/hle/service/bcat/news/news_database_service.cpp35
-rwxr-xr-xsrc/core/hle/service/bcat/news/news_database_service.h24
-rwxr-xr-xsrc/core/hle/service/bcat/news/news_service.cpp46
-rwxr-xr-xsrc/core/hle/service/bcat/news/news_service.h24
-rwxr-xr-xsrc/core/hle/service/bcat/news/overwrite_event_holder.cpp33
-rwxr-xr-xsrc/core/hle/service/bcat/news/overwrite_event_holder.h33
-rwxr-xr-xsrc/core/hle/service/bcat/news/service_creator.cpp64
-rwxr-xr-xsrc/core/hle/service/bcat/news/service_creator.h35
-rwxr-xr-xsrc/core/hle/service/bcat/service_creator.cpp62
-rwxr-xr-xsrc/core/hle/service/bcat/service_creator.h40
-rwxr-xr-xsrc/core/hle/service/service.cpp2
35 files changed, 1286 insertions, 85 deletions
diff --git a/README.md b/README.md
index 2950656e4..14c8e422e 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
1yuzu emulator early access 1yuzu emulator early access
2============= 2=============
3 3
4This is the source code for early-access 4125. 4This is the source code for early-access 4126.
5 5
6## Legal Notice 6## Legal Notice
7 7
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 5b2de4ab7..8c74878ab 100755
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -512,10 +512,35 @@ add_library(core STATIC
512 hle/service/audio/hwopus.h 512 hle/service/audio/hwopus.h
513 hle/service/bcat/backend/backend.cpp 513 hle/service/bcat/backend/backend.cpp
514 hle/service/bcat/backend/backend.h 514 hle/service/bcat/backend/backend.h
515 hle/service/bcat/news/newly_arrived_event_holder.cpp
516 hle/service/bcat/news/newly_arrived_event_holder.h
517 hle/service/bcat/news/news_data_service.cpp
518 hle/service/bcat/news/news_data_service.h
519 hle/service/bcat/news/news_database_service.cpp
520 hle/service/bcat/news/news_database_service.h
521 hle/service/bcat/news/news_service.cpp
522 hle/service/bcat/news/news_service.h
523 hle/service/bcat/news/overwrite_event_holder.cpp
524 hle/service/bcat/news/overwrite_event_holder.h
525 hle/service/bcat/news/service_creator.cpp
526 hle/service/bcat/news/service_creator.h
515 hle/service/bcat/bcat.cpp 527 hle/service/bcat/bcat.cpp
516 hle/service/bcat/bcat.h 528 hle/service/bcat/bcat.h
517 hle/service/bcat/bcat_module.cpp 529 hle/service/bcat/bcat_result.h
518 hle/service/bcat/bcat_module.h 530 hle/service/bcat/bcat_service.cpp
531 hle/service/bcat/bcat_service.h
532 hle/service/bcat/bcat_types.h
533 hle/service/bcat/bcat_util.h
534 hle/service/bcat/delivery_cache_directory_service.cpp
535 hle/service/bcat/delivery_cache_directory_service.h
536 hle/service/bcat/delivery_cache_file_service.cpp
537 hle/service/bcat/delivery_cache_file_service.h
538 hle/service/bcat/delivery_cache_progress_service.cpp
539 hle/service/bcat/delivery_cache_progress_service.h
540 hle/service/bcat/delivery_cache_storage_service.cpp
541 hle/service/bcat/delivery_cache_storage_service.h
542 hle/service/bcat/service_creator.cpp
543 hle/service/bcat/service_creator.h
519 hle/service/bpc/bpc.cpp 544 hle/service/bpc/bpc.cpp
520 hle/service/bpc/bpc.h 545 hle/service/bpc/bpc.h
521 hle/service/btdrv/btdrv.cpp 546 hle/service/btdrv/btdrv.cpp
diff --git a/src/core/file_sys/errors.h b/src/core/file_sys/errors.h
index 50f65cc5f..1e9489701 100755
--- a/src/core/file_sys/errors.h
+++ b/src/core/file_sys/errors.h
@@ -91,6 +91,7 @@ constexpr Result ResultWriteNotPermitted{ErrorModule::FS, 6203};
91constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 6325}; 91constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 6325};
92constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387}; 92constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387};
93constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388}; 93constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388};
94constexpr Result ResultPermissionDenied{ErrorModule::FS, 6400};
94constexpr Result ResultBufferAllocationFailed{ErrorModule::FS, 6705}; 95constexpr Result ResultBufferAllocationFailed{ErrorModule::FS, 6705};
95 96
96} // namespace FileSys 97} // namespace FileSys
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index 0d9cf9914..b21589031 100755
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -33,18 +33,18 @@ void ProgressServiceBackend::SetTotalSize(u64 size) {
33} 33}
34 34
35void ProgressServiceBackend::StartConnecting() { 35void ProgressServiceBackend::StartConnecting() {
36 impl.status = DeliveryCacheProgressImpl::Status::Connecting; 36 impl.status = DeliveryCacheProgressStatus::Connecting;
37 SignalUpdate(); 37 SignalUpdate();
38} 38}
39 39
40void ProgressServiceBackend::StartProcessingDataList() { 40void ProgressServiceBackend::StartProcessingDataList() {
41 impl.status = DeliveryCacheProgressImpl::Status::ProcessingDataList; 41 impl.status = DeliveryCacheProgressStatus::ProcessingDataList;
42 SignalUpdate(); 42 SignalUpdate();
43} 43}
44 44
45void ProgressServiceBackend::StartDownloadingFile(std::string_view dir_name, 45void ProgressServiceBackend::StartDownloadingFile(std::string_view dir_name,
46 std::string_view file_name, u64 file_size) { 46 std::string_view file_name, u64 file_size) {
47 impl.status = DeliveryCacheProgressImpl::Status::Downloading; 47 impl.status = DeliveryCacheProgressStatus::Downloading;
48 impl.current_downloaded_bytes = 0; 48 impl.current_downloaded_bytes = 0;
49 impl.current_total_bytes = file_size; 49 impl.current_total_bytes = file_size;
50 std::memcpy(impl.current_directory.data(), dir_name.data(), 50 std::memcpy(impl.current_directory.data(), dir_name.data(),
@@ -65,7 +65,7 @@ void ProgressServiceBackend::FinishDownloadingFile() {
65} 65}
66 66
67void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) { 67void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) {
68 impl.status = DeliveryCacheProgressImpl::Status::Committing; 68 impl.status = DeliveryCacheProgressStatus::Committing;
69 impl.current_file.fill(0); 69 impl.current_file.fill(0);
70 impl.current_downloaded_bytes = 0; 70 impl.current_downloaded_bytes = 0;
71 impl.current_total_bytes = 0; 71 impl.current_total_bytes = 0;
@@ -76,7 +76,7 @@ void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) {
76 76
77void ProgressServiceBackend::FinishDownload(Result result) { 77void ProgressServiceBackend::FinishDownload(Result result) {
78 impl.total_downloaded_bytes = impl.total_bytes; 78 impl.total_downloaded_bytes = impl.total_bytes;
79 impl.status = DeliveryCacheProgressImpl::Status::Done; 79 impl.status = DeliveryCacheProgressStatus::Done;
80 impl.result = result; 80 impl.result = result;
81 SignalUpdate(); 81 SignalUpdate();
82} 82}
@@ -85,15 +85,15 @@ void ProgressServiceBackend::SignalUpdate() {
85 update_event->Signal(); 85 update_event->Signal();
86} 86}
87 87
88Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} 88BcatBackend::BcatBackend(DirectoryGetter getter) : dir_getter(std::move(getter)) {}
89 89
90Backend::~Backend() = default; 90BcatBackend::~BcatBackend() = default;
91 91
92NullBackend::NullBackend(DirectoryGetter getter) : Backend(std::move(getter)) {} 92NullBcatBackend::NullBcatBackend(DirectoryGetter getter) : BcatBackend(std::move(getter)) {}
93 93
94NullBackend::~NullBackend() = default; 94NullBcatBackend::~NullBcatBackend() = default;
95 95
96bool NullBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) { 96bool NullBcatBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) {
97 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, 97 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id,
98 title.build_id); 98 title.build_id);
99 99
@@ -101,8 +101,8 @@ bool NullBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& prog
101 return true; 101 return true;
102} 102}
103 103
104bool NullBackend::SynchronizeDirectory(TitleIDVersion title, std::string name, 104bool NullBcatBackend::SynchronizeDirectory(TitleIDVersion title, std::string name,
105 ProgressServiceBackend& progress) { 105 ProgressServiceBackend& progress) {
106 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}, name={}", title.title_id, 106 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}, name={}", title.title_id,
107 title.build_id, name); 107 title.build_id, name);
108 108
@@ -110,18 +110,18 @@ bool NullBackend::SynchronizeDirectory(TitleIDVersion title, std::string name,
110 return true; 110 return true;
111} 111}
112 112
113bool NullBackend::Clear(u64 title_id) { 113bool NullBcatBackend::Clear(u64 title_id) {
114 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); 114 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id);
115 115
116 return true; 116 return true;
117} 117}
118 118
119void NullBackend::SetPassphrase(u64 title_id, const Passphrase& passphrase) { 119void NullBcatBackend::SetPassphrase(u64 title_id, const Passphrase& passphrase) {
120 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id, 120 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id,
121 Common::HexToString(passphrase)); 121 Common::HexToString(passphrase));
122} 122}
123 123
124std::optional<std::vector<u8>> NullBackend::GetLaunchParameter(TitleIDVersion title) { 124std::optional<std::vector<u8>> NullBcatBackend::GetLaunchParameter(TitleIDVersion title) {
125 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, 125 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id,
126 title.build_id); 126 title.build_id);
127 return std::nullopt; 127 return std::nullopt;
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h
index 50cc630ec..06962430f 100755
--- a/src/core/hle/service/bcat/backend/backend.h
+++ b/src/core/hle/service/bcat/backend/backend.h
@@ -10,6 +10,7 @@
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/file_sys/vfs/vfs_types.h" 11#include "core/file_sys/vfs/vfs_types.h"
12#include "core/hle/result.h" 12#include "core/hle/result.h"
13#include "core/hle/service/bcat/bcat_types.h"
13#include "core/hle/service/kernel_helpers.h" 14#include "core/hle/service/kernel_helpers.h"
14 15
15namespace Core { 16namespace Core {
@@ -24,44 +25,6 @@ class KReadableEvent;
24 25
25namespace Service::BCAT { 26namespace Service::BCAT {
26 27
27struct DeliveryCacheProgressImpl;
28
29using DirectoryGetter = std::function<FileSys::VirtualDir(u64)>;
30using Passphrase = std::array<u8, 0x20>;
31
32struct TitleIDVersion {
33 u64 title_id;
34 u64 build_id;
35};
36
37using DirectoryName = std::array<char, 0x20>;
38using FileName = std::array<char, 0x20>;
39
40struct DeliveryCacheProgressImpl {
41 enum class Status : s32 {
42 None = 0x0,
43 Queued = 0x1,
44 Connecting = 0x2,
45 ProcessingDataList = 0x3,
46 Downloading = 0x4,
47 Committing = 0x5,
48 Done = 0x9,
49 };
50
51 Status status;
52 Result result = ResultSuccess;
53 DirectoryName current_directory;
54 FileName current_file;
55 s64 current_downloaded_bytes; ///< Bytes downloaded on current file.
56 s64 current_total_bytes; ///< Bytes total on current file.
57 s64 total_downloaded_bytes; ///< Bytes downloaded on overall download.
58 s64 total_bytes; ///< Bytes total on overall download.
59 INSERT_PADDING_BYTES(
60 0x198); ///< Appears to be unused in official code, possibly reserved for future use.
61};
62static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200,
63 "DeliveryCacheProgressImpl has incorrect size.");
64
65// A class to manage the signalling to the game about BCAT download progress. 28// A class to manage the signalling to the game about BCAT download progress.
66// Some of this class is implemented in module.cpp to avoid exposing the implementation structure. 29// Some of this class is implemented in module.cpp to avoid exposing the implementation structure.
67class ProgressServiceBackend { 30class ProgressServiceBackend {
@@ -107,10 +70,10 @@ private:
107}; 70};
108 71
109// A class representing an abstract backend for BCAT functionality. 72// A class representing an abstract backend for BCAT functionality.
110class Backend { 73class BcatBackend {
111public: 74public:
112 explicit Backend(DirectoryGetter getter); 75 explicit BcatBackend(DirectoryGetter getter);
113 virtual ~Backend(); 76 virtual ~BcatBackend();
114 77
115 // Called when the backend is needed to synchronize the data for the game with title ID and 78 // Called when the backend is needed to synchronize the data for the game with title ID and
116 // version in title. A ProgressServiceBackend object is provided to alert the application of 79 // version in title. A ProgressServiceBackend object is provided to alert the application of
@@ -135,10 +98,10 @@ protected:
135}; 98};
136 99
137// A backend of BCAT that provides no operation. 100// A backend of BCAT that provides no operation.
138class NullBackend : public Backend { 101class NullBcatBackend : public BcatBackend {
139public: 102public:
140 explicit NullBackend(DirectoryGetter getter); 103 explicit NullBcatBackend(DirectoryGetter getter);
141 ~NullBackend() override; 104 ~NullBcatBackend() override;
142 105
143 bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override; 106 bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override;
144 bool SynchronizeDirectory(TitleIDVersion title, std::string name, 107 bool SynchronizeDirectory(TitleIDVersion title, std::string name,
@@ -151,6 +114,7 @@ public:
151 std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) override; 114 std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) override;
152}; 115};
153 116
154std::unique_ptr<Backend> CreateBackendFromSettings(Core::System& system, DirectoryGetter getter); 117std::unique_ptr<BcatBackend> CreateBackendFromSettings(Core::System& system,
118 DirectoryGetter getter);
155 119
156} // namespace Service::BCAT 120} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat.cpp b/src/core/hle/service/bcat/bcat.cpp
index 1189cef88..352d411f3 100755
--- a/src/core/hle/service/bcat/bcat.cpp
+++ b/src/core/hle/service/bcat/bcat.cpp
@@ -1,24 +1,38 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/bcat/backend/backend.h"
4#include "core/hle/service/bcat/bcat.h" 5#include "core/hle/service/bcat/bcat.h"
6#include "core/hle/service/bcat/news/service_creator.h"
7#include "core/hle/service/bcat/service_creator.h"
8#include "core/hle/service/server_manager.h"
5 9
6namespace Service::BCAT { 10namespace Service::BCAT {
7 11
8BCAT::BCAT(Core::System& system_, std::shared_ptr<Module> module_, 12void LoopProcess(Core::System& system) {
9 FileSystem::FileSystemController& fsc_, const char* name_) 13 auto server_manager = std::make_unique<ServerManager>(system);
10 : Interface(system_, std::move(module_), fsc_, name_) { 14
11 // clang-format off 15 server_manager->RegisterNamedService("bcat:a",
12 static const FunctionInfo functions[] = { 16 std::make_shared<IServiceCreator>(system, "bcat:a"));
13 {0, &BCAT::CreateBcatService, "CreateBcatService"}, 17 server_manager->RegisterNamedService("bcat:m",
14 {1, &BCAT::CreateDeliveryCacheStorageService, "CreateDeliveryCacheStorageService"}, 18 std::make_shared<IServiceCreator>(system, "bcat:m"));
15 {2, &BCAT::CreateDeliveryCacheStorageServiceWithApplicationId, "CreateDeliveryCacheStorageServiceWithApplicationId"}, 19 server_manager->RegisterNamedService("bcat:u",
16 {3, nullptr, "CreateDeliveryCacheProgressService"}, 20 std::make_shared<IServiceCreator>(system, "bcat:u"));
17 {4, nullptr, "CreateDeliveryCacheProgressServiceWithApplicationId"}, 21 server_manager->RegisterNamedService("bcat:s",
18 }; 22 std::make_shared<IServiceCreator>(system, "bcat:s"));
19 // clang-format on 23
20 RegisterHandlers(functions); 24 server_manager->RegisterNamedService(
25 "news:a", std::make_shared<News::IServiceCreator>(system, 0xffffffff, "news:a"));
26 server_manager->RegisterNamedService(
27 "news:p", std::make_shared<News::IServiceCreator>(system, 0x1, "news:p"));
28 server_manager->RegisterNamedService(
29 "news:c", std::make_shared<News::IServiceCreator>(system, 0x2, "news:c"));
30 server_manager->RegisterNamedService(
31 "news:v", std::make_shared<News::IServiceCreator>(system, 0x4, "news:v"));
32 server_manager->RegisterNamedService(
33 "news:m", std::make_shared<News::IServiceCreator>(system, 0xd, "news:m"));
34
35 ServerManager::RunServer(std::move(server_manager));
21} 36}
22 37
23BCAT::~BCAT() = default;
24} // namespace Service::BCAT 38} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat.h b/src/core/hle/service/bcat/bcat.h
index 7de66ced4..fb0999f04 100755
--- a/src/core/hle/service/bcat/bcat.h
+++ b/src/core/hle/service/bcat/bcat.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/bcat/bcat_module.h" 6#include "core/hle/service/service.h"
7 7
8namespace Core { 8namespace Core {
9class System; 9class System;
@@ -11,11 +11,6 @@ class System;
11 11
12namespace Service::BCAT { 12namespace Service::BCAT {
13 13
14class BCAT final : public Module::Interface { 14void LoopProcess(Core::System& system);
15public:
16 explicit BCAT(Core::System& system_, std::shared_ptr<Module> module_,
17 FileSystem::FileSystemController& fsc_, const char* name_);
18 ~BCAT() override;
19};
20 15
21} // namespace Service::BCAT 16} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat_result.h b/src/core/hle/service/bcat/bcat_result.h
new file mode 100755
index 000000000..edf8a6564
--- /dev/null
+++ b/src/core/hle/service/bcat/bcat_result.h
@@ -0,0 +1,15 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/result.h"
7
8namespace Service::BCAT {
9
10constexpr Result ResultInvalidArgument{ErrorModule::BCAT, 1};
11constexpr Result ResultFailedOpenEntity{ErrorModule::BCAT, 2};
12constexpr Result ResultEntityAlreadyOpen{ErrorModule::BCAT, 6};
13constexpr Result ResultNoOpenEntry{ErrorModule::BCAT, 7};
14
15} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat_service.cpp b/src/core/hle/service/bcat/bcat_service.cpp
new file mode 100755
index 000000000..6e1ea43ac
--- /dev/null
+++ b/src/core/hle/service/bcat/bcat_service.cpp
@@ -0,0 +1,132 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/hex_util.h"
5#include "common/string_util.h"
6#include "core/core.h"
7#include "core/file_sys/errors.h"
8#include "core/hle/service/bcat/backend/backend.h"
9#include "core/hle/service/bcat/bcat_result.h"
10#include "core/hle/service/bcat/bcat_service.h"
11#include "core/hle/service/bcat/bcat_util.h"
12#include "core/hle/service/bcat/delivery_cache_progress_service.h"
13#include "core/hle/service/bcat/delivery_cache_storage_service.h"
14#include "core/hle/service/cmif_serialization.h"
15
16namespace Service::BCAT {
17
18static u64 GetCurrentBuildID(const Core::System::CurrentBuildProcessID& id) {
19 u64 out{};
20 std::memcpy(&out, id.data(), sizeof(u64));
21 return out;
22}
23
24IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_)
25 : ServiceFramework{system_, "IBcatService"}, backend{backend_},
26 progress{{
27 ProgressServiceBackend{system_, "Normal"},
28 ProgressServiceBackend{system_, "Directory"},
29 }} {
30 // clang-format off
31 static const FunctionInfo functions[] = {
32 {10100, C<&IBcatService::RequestSyncDeliveryCache>, "RequestSyncDeliveryCache"},
33 {10101, C<&IBcatService::RequestSyncDeliveryCacheWithDirectoryName>, "RequestSyncDeliveryCacheWithDirectoryName"},
34 {10200, nullptr, "CancelSyncDeliveryCacheRequest"},
35 {20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"},
36 {20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"},
37 {20300, nullptr, "GetDeliveryCacheStorageUpdateNotifier"},
38 {20301, nullptr, "RequestSuspendDeliveryTask"},
39 {20400, nullptr, "RegisterSystemApplicationDeliveryTask"},
40 {20401, nullptr, "UnregisterSystemApplicationDeliveryTask"},
41 {20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"},
42 {30100, C<&IBcatService::SetPassphrase>, "SetPassphrase"},
43 {30101, nullptr, "Unknown30101"},
44 {30102, nullptr, "Unknown30102"},
45 {30200, nullptr, "RegisterBackgroundDeliveryTask"},
46 {30201, nullptr, "UnregisterBackgroundDeliveryTask"},
47 {30202, nullptr, "BlockDeliveryTask"},
48 {30203, nullptr, "UnblockDeliveryTask"},
49 {30210, nullptr, "SetDeliveryTaskTimer"},
50 {30300, C<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"},
51 {90100, nullptr, "EnumerateBackgroundDeliveryTask"},
52 {90101, nullptr, "Unknown90101"},
53 {90200, nullptr, "GetDeliveryList"},
54 {90201, C<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"},
55 {90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
56 {90300, nullptr, "GetPushNotificationLog"},
57 {90301, nullptr, "Unknown90301"},
58 };
59 // clang-format on
60 RegisterHandlers(functions);
61}
62
63IBcatService::~IBcatService() = default;
64
65Result IBcatService::RequestSyncDeliveryCache(
66 OutInterface<IDeliveryCacheProgressService> out_interface) {
67 LOG_DEBUG(Service_BCAT, "called");
68
69 auto& progress_backend{GetProgressBackend(SyncType::Normal)};
70 backend.Synchronize({system.GetApplicationProcessProgramID(),
71 GetCurrentBuildID(system.GetApplicationProcessBuildID())},
72 GetProgressBackend(SyncType::Normal));
73
74 *out_interface = std::make_shared<IDeliveryCacheProgressService>(
75 system, progress_backend.GetEvent(), progress_backend.GetImpl());
76 R_SUCCEED();
77}
78
79Result IBcatService::RequestSyncDeliveryCacheWithDirectoryName(
80 const DirectoryName& name_raw, OutInterface<IDeliveryCacheProgressService> out_interface) {
81 const auto name = Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size());
82
83 LOG_DEBUG(Service_BCAT, "called, name={}", name);
84
85 auto& progress_backend{GetProgressBackend(SyncType::Directory)};
86 backend.SynchronizeDirectory({system.GetApplicationProcessProgramID(),
87 GetCurrentBuildID(system.GetApplicationProcessBuildID())},
88 name, progress_backend);
89
90 *out_interface = std::make_shared<IDeliveryCacheProgressService>(
91 system, progress_backend.GetEvent(), progress_backend.GetImpl());
92 R_SUCCEED();
93}
94
95Result IBcatService::SetPassphrase(u64 application_id,
96 InBuffer<BufferAttr_HipcPointer> passphrase_buffer) {
97 LOG_DEBUG(Service_BCAT, "called, application_id={:016X}, passphrase={}", application_id,
98 Common::HexToString(passphrase_buffer));
99
100 R_UNLESS(application_id != 0, ResultInvalidArgument);
101 R_UNLESS(passphrase_buffer.size() <= 0x40, ResultInvalidArgument);
102
103 Passphrase passphrase{};
104 std::memcpy(passphrase.data(), passphrase_buffer.data(),
105 std::min(passphrase.size(), passphrase_buffer.size()));
106
107 backend.SetPassphrase(application_id, passphrase);
108 R_SUCCEED();
109}
110
111Result IBcatService::RegisterSystemApplicationDeliveryTasks() {
112 LOG_WARNING(Service_BCAT, "(STUBBED) called");
113 R_SUCCEED();
114}
115
116Result IBcatService::ClearDeliveryCacheStorage(u64 application_id) {
117 LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", application_id);
118
119 R_UNLESS(application_id != 0, ResultInvalidArgument);
120 R_UNLESS(backend.Clear(application_id), FileSys::ResultPermissionDenied);
121 R_SUCCEED();
122}
123
124ProgressServiceBackend& IBcatService::GetProgressBackend(SyncType type) {
125 return progress.at(static_cast<size_t>(type));
126}
127
128const ProgressServiceBackend& IBcatService::GetProgressBackend(SyncType type) const {
129 return progress.at(static_cast<size_t>(type));
130}
131
132} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat_service.h b/src/core/hle/service/bcat/bcat_service.h
new file mode 100755
index 000000000..dda5a2d5f
--- /dev/null
+++ b/src/core/hle/service/bcat/bcat_service.h
@@ -0,0 +1,45 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/bcat/backend/backend.h"
7#include "core/hle/service/bcat/bcat_types.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Core {
12class System;
13}
14
15namespace Service::BCAT {
16class BcatBackend;
17class IDeliveryCacheStorageService;
18class IDeliveryCacheProgressService;
19
20class IBcatService final : public ServiceFramework<IBcatService> {
21public:
22 explicit IBcatService(Core::System& system_, BcatBackend& backend_);
23 ~IBcatService() override;
24
25private:
26 Result RequestSyncDeliveryCache(OutInterface<IDeliveryCacheProgressService> out_interface);
27
28 Result RequestSyncDeliveryCacheWithDirectoryName(
29 const DirectoryName& name, OutInterface<IDeliveryCacheProgressService> out_interface);
30
31 Result SetPassphrase(u64 application_id, InBuffer<BufferAttr_HipcPointer> passphrase_buffer);
32
33 Result RegisterSystemApplicationDeliveryTasks();
34
35 Result ClearDeliveryCacheStorage(u64 application_id);
36
37private:
38 ProgressServiceBackend& GetProgressBackend(SyncType type);
39 const ProgressServiceBackend& GetProgressBackend(SyncType type) const;
40
41 BcatBackend& backend;
42 std::array<ProgressServiceBackend, static_cast<size_t>(SyncType::Count)> progress;
43};
44
45} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat_types.h b/src/core/hle/service/bcat/bcat_types.h
new file mode 100755
index 000000000..b35dab7c5
--- /dev/null
+++ b/src/core/hle/service/bcat/bcat_types.h
@@ -0,0 +1,66 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7#include <functional>
8
9#include "common/common_funcs.h"
10#include "common/common_types.h"
11#include "core/file_sys/vfs/vfs_types.h"
12#include "core/hle/result.h"
13
14namespace Service::BCAT {
15
16using DirectoryName = std::array<char, 0x20>;
17using FileName = std::array<char, 0x20>;
18using BcatDigest = std::array<u8, 0x10>;
19using Passphrase = std::array<u8, 0x20>;
20using DirectoryGetter = std::function<FileSys::VirtualDir(u64)>;
21
22enum class SyncType {
23 Normal,
24 Directory,
25 Count,
26};
27
28enum class DeliveryCacheProgressStatus : s32 {
29 None = 0x0,
30 Queued = 0x1,
31 Connecting = 0x2,
32 ProcessingDataList = 0x3,
33 Downloading = 0x4,
34 Committing = 0x5,
35 Done = 0x9,
36};
37
38struct DeliveryCacheDirectoryEntry {
39 FileName name;
40 u64 size;
41 BcatDigest digest;
42};
43
44struct TitleIDVersion {
45 u64 title_id;
46 u64 build_id;
47};
48
49struct DeliveryCacheProgressImpl {
50 DeliveryCacheProgressStatus status;
51 Result result;
52 DirectoryName current_directory;
53 FileName current_file;
54 s64 current_downloaded_bytes; ///< Bytes downloaded on current file.
55 s64 current_total_bytes; ///< Bytes total on current file.
56 s64 total_downloaded_bytes; ///< Bytes downloaded on overall download.
57 s64 total_bytes; ///< Bytes total on overall download.
58 INSERT_PADDING_BYTES_NOINIT(
59 0x198); ///< Appears to be unused in official code, possibly reserved for future use.
60};
61static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200,
62 "DeliveryCacheProgressImpl has incorrect size.");
63static_assert(std::is_trivial_v<DeliveryCacheProgressImpl>,
64 "DeliveryCacheProgressImpl type must be trivially copyable.");
65
66} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat_util.h b/src/core/hle/service/bcat/bcat_util.h
new file mode 100755
index 000000000..6bf2657ee
--- /dev/null
+++ b/src/core/hle/service/bcat/bcat_util.h
@@ -0,0 +1,39 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7#include <cctype>
8#include <mbedtls/md5.h>
9
10#include "core/hle/service/bcat/bcat_result.h"
11#include "core/hle/service/bcat/bcat_types.h"
12
13namespace Service::BCAT {
14
15// For a name to be valid it must be non-empty, must have a null terminating character as the final
16// char, can only contain numbers, letters, underscores and a hyphen if directory and a period if
17// file.
18constexpr Result VerifyNameValidInternal(std::array<char, 0x20> name, char match_char) {
19 const auto null_chars = std::count(name.begin(), name.end(), 0);
20 const auto bad_chars = std::count_if(name.begin(), name.end(), [match_char](char c) {
21 return !std::isalnum(static_cast<u8>(c)) && c != '_' && c != match_char && c != '\0';
22 });
23 if (null_chars == 0x20 || null_chars == 0 || bad_chars != 0 || name[0x1F] != '\0') {
24 LOG_ERROR(Service_BCAT, "Name passed was invalid!");
25 return ResultInvalidArgument;
26 }
27
28 return ResultSuccess;
29}
30
31constexpr Result VerifyNameValidDir(DirectoryName name) {
32 return VerifyNameValidInternal(name, '-');
33}
34
35constexpr Result VerifyNameValidFile(FileName name) {
36 return VerifyNameValidInternal(name, '.');
37}
38
39} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_directory_service.cpp b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp
new file mode 100755
index 000000000..af47a3426
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp
@@ -0,0 +1,80 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "common/string_util.h"
5#include "core/file_sys/vfs/vfs_types.h"
6#include "core/hle/service/bcat/bcat_result.h"
7#include "core/hle/service/bcat/bcat_util.h"
8#include "core/hle/service/bcat/delivery_cache_directory_service.h"
9#include "core/hle/service/cmif_serialization.h"
10
11namespace Service::BCAT {
12
13// The digest is only used to determine if a file is unique compared to others of the same name.
14// Since the algorithm isn't ever checked in game, MD5 is safe.
15static BcatDigest DigestFile(const FileSys::VirtualFile& file) {
16 BcatDigest out{};
17 const auto bytes = file->ReadAllBytes();
18 mbedtls_md5_ret(bytes.data(), bytes.size(), out.data());
19 return out;
20}
21
22IDeliveryCacheDirectoryService::IDeliveryCacheDirectoryService(Core::System& system_,
23 FileSys::VirtualDir root_)
24 : ServiceFramework{system_, "IDeliveryCacheDirectoryService"}, root(std::move(root_)) {
25 // clang-format off
26 static const FunctionInfo functions[] = {
27 {0, C<&IDeliveryCacheDirectoryService::Open>, "Open"},
28 {1, C<&IDeliveryCacheDirectoryService::Read>, "Read"},
29 {2, C<&IDeliveryCacheDirectoryService::GetCount>, "GetCount"},
30 };
31 // clang-format on
32
33 RegisterHandlers(functions);
34}
35
36IDeliveryCacheDirectoryService::~IDeliveryCacheDirectoryService() = default;
37
38Result IDeliveryCacheDirectoryService::Open(const DirectoryName& dir_name_raw) {
39 const auto dir_name =
40 Common::StringFromFixedZeroTerminatedBuffer(dir_name_raw.data(), dir_name_raw.size());
41
42 LOG_DEBUG(Service_BCAT, "called, dir_name={}", dir_name);
43
44 R_TRY(VerifyNameValidDir(dir_name_raw));
45 R_UNLESS(current_dir == nullptr, ResultEntityAlreadyOpen);
46
47 const auto dir = root->GetSubdirectory(dir_name);
48 R_UNLESS(dir != nullptr, ResultFailedOpenEntity);
49
50 R_SUCCEED();
51}
52
53Result IDeliveryCacheDirectoryService::Read(
54 Out<s32> out_count, OutArray<DeliveryCacheDirectoryEntry, BufferAttr_HipcMapAlias> out_buffer) {
55 LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", out_buffer.size());
56
57 R_UNLESS(current_dir != nullptr, ResultNoOpenEntry);
58
59 const auto files = current_dir->GetFiles();
60 *out_count = static_cast<s32>(std::min(files.size(), out_buffer.size()));
61 std::transform(files.begin(), files.begin() + *out_count, out_buffer.begin(),
62 [](const auto& file) {
63 FileName name{};
64 std::memcpy(name.data(), file->GetName().data(),
65 std::min(file->GetName().size(), name.size()));
66 return DeliveryCacheDirectoryEntry{name, file->GetSize(), DigestFile(file)};
67 });
68 R_SUCCEED();
69}
70
71Result IDeliveryCacheDirectoryService::GetCount(Out<s32> out_count) {
72 LOG_DEBUG(Service_BCAT, "called");
73
74 R_UNLESS(current_dir != nullptr, ResultNoOpenEntry);
75
76 *out_count = static_cast<s32>(current_dir->GetFiles().size());
77 R_SUCCEED();
78}
79
80} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_directory_service.h b/src/core/hle/service/bcat/delivery_cache_directory_service.h
new file mode 100755
index 000000000..b902c6495
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_directory_service.h
@@ -0,0 +1,33 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/file_sys/vfs/vfs.h"
7#include "core/hle/service/bcat/bcat_types.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Core {
12class System;
13}
14
15namespace Service::BCAT {
16
17class IDeliveryCacheDirectoryService final
18 : public ServiceFramework<IDeliveryCacheDirectoryService> {
19public:
20 explicit IDeliveryCacheDirectoryService(Core::System& system_, FileSys::VirtualDir root_);
21 ~IDeliveryCacheDirectoryService() override;
22
23private:
24 Result Open(const DirectoryName& dir_name_raw);
25 Result Read(Out<s32> out_count,
26 OutArray<DeliveryCacheDirectoryEntry, BufferAttr_HipcMapAlias> out_buffer);
27 Result GetCount(Out<s32> out_count);
28
29 FileSys::VirtualDir root;
30 FileSys::VirtualDir current_dir;
31};
32
33} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_file_service.cpp b/src/core/hle/service/bcat/delivery_cache_file_service.cpp
new file mode 100755
index 000000000..f2f670494
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_file_service.cpp
@@ -0,0 +1,82 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "common/string_util.h"
5#include "core/hle/service/bcat/bcat_result.h"
6#include "core/hle/service/bcat/bcat_util.h"
7#include "core/hle/service/bcat/delivery_cache_file_service.h"
8#include "core/hle/service/cmif_serialization.h"
9
10namespace Service::BCAT {
11
12IDeliveryCacheFileService::IDeliveryCacheFileService(Core::System& system_,
13 FileSys::VirtualDir root_)
14 : ServiceFramework{system_, "IDeliveryCacheFileService"}, root(std::move(root_)) {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, C<&IDeliveryCacheFileService::Open>, "Open"},
18 {1, C<&IDeliveryCacheFileService::Read>, "Read"},
19 {2, C<&IDeliveryCacheFileService::GetSize>, "GetSize"},
20 {3, C<&IDeliveryCacheFileService::GetDigest>, "GetDigest"},
21 };
22 // clang-format on
23
24 RegisterHandlers(functions);
25}
26
27IDeliveryCacheFileService::~IDeliveryCacheFileService() = default;
28
29Result IDeliveryCacheFileService::Open(const DirectoryName& dir_name_raw,
30 const FileName& file_name_raw) {
31 const auto dir_name =
32 Common::StringFromFixedZeroTerminatedBuffer(dir_name_raw.data(), dir_name_raw.size());
33 const auto file_name =
34 Common::StringFromFixedZeroTerminatedBuffer(file_name_raw.data(), file_name_raw.size());
35
36 LOG_DEBUG(Service_BCAT, "called, dir_name={}, file_name={}", dir_name, file_name);
37
38 R_TRY(VerifyNameValidDir(dir_name_raw));
39 R_TRY(VerifyNameValidDir(file_name_raw));
40 R_UNLESS(current_file == nullptr, ResultEntityAlreadyOpen);
41
42 const auto dir = root->GetSubdirectory(dir_name);
43 R_UNLESS(dir != nullptr, ResultFailedOpenEntity);
44
45 current_file = dir->GetFile(file_name);
46 R_UNLESS(current_file != nullptr, ResultFailedOpenEntity);
47
48 R_SUCCEED();
49}
50
51Result IDeliveryCacheFileService::Read(Out<u64> out_buffer_size, u64 offset,
52 OutBuffer<BufferAttr_HipcMapAlias> out_buffer) {
53 LOG_DEBUG(Service_BCAT, "called, offset={:016X}, size={:016X}", offset, out_buffer.size());
54
55 R_UNLESS(current_file != nullptr, ResultNoOpenEntry);
56
57 *out_buffer_size = std::min<u64>(current_file->GetSize() - offset, out_buffer.size());
58 const auto buffer = current_file->ReadBytes(*out_buffer_size, offset);
59 memcpy(out_buffer.data(), buffer.data(), buffer.size());
60
61 R_SUCCEED();
62}
63
64Result IDeliveryCacheFileService::GetSize(Out<u64> out_size) {
65 LOG_DEBUG(Service_BCAT, "called");
66
67 R_UNLESS(current_file != nullptr, ResultNoOpenEntry);
68
69 *out_size = current_file->GetSize();
70 R_SUCCEED();
71}
72
73Result IDeliveryCacheFileService::GetDigest(Out<BcatDigest> out_digest) {
74 LOG_DEBUG(Service_BCAT, "called");
75
76 R_UNLESS(current_file != nullptr, ResultNoOpenEntry);
77
78 //*out_digest = DigestFile(current_file);
79 R_SUCCEED();
80}
81
82} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_file_service.h b/src/core/hle/service/bcat/delivery_cache_file_service.h
new file mode 100755
index 000000000..e1012e687
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_file_service.h
@@ -0,0 +1,33 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/file_sys/vfs/vfs.h"
7#include "core/hle/service/bcat/bcat_types.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Core {
12class System;
13}
14
15namespace Service::BCAT {
16
17class IDeliveryCacheFileService final : public ServiceFramework<IDeliveryCacheFileService> {
18public:
19 explicit IDeliveryCacheFileService(Core::System& system_, FileSys::VirtualDir root_);
20 ~IDeliveryCacheFileService() override;
21
22private:
23 Result Open(const DirectoryName& dir_name_raw, const FileName& file_name_raw);
24 Result Read(Out<u64> out_buffer_size, u64 offset,
25 OutBuffer<BufferAttr_HipcMapAlias> out_buffer);
26 Result GetSize(Out<u64> out_size);
27 Result GetDigest(Out<BcatDigest> out_digest);
28
29 FileSys::VirtualDir root;
30 FileSys::VirtualFile current_file;
31};
32
33} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_progress_service.cpp b/src/core/hle/service/bcat/delivery_cache_progress_service.cpp
new file mode 100755
index 000000000..94d341f7e
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_progress_service.cpp
@@ -0,0 +1,41 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/bcat_types.h"
5#include "core/hle/service/bcat/delivery_cache_progress_service.h"
6#include "core/hle/service/cmif_serialization.h"
7
8namespace Service::BCAT {
9
10IDeliveryCacheProgressService::IDeliveryCacheProgressService(Core::System& system_,
11 Kernel::KReadableEvent& event_,
12 const DeliveryCacheProgressImpl& impl_)
13 : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{event_}, impl{impl_} {
14 // clang-format off
15 static const FunctionInfo functions[] = {
16 {0, C<&IDeliveryCacheProgressService::GetEvent>, "Get"},
17 {0, C<&IDeliveryCacheProgressService::GetImpl>, "Get"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22}
23
24IDeliveryCacheProgressService::~IDeliveryCacheProgressService() = default;
25
26Result IDeliveryCacheProgressService::GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
27 LOG_DEBUG(Service_BCAT, "called");
28
29 *out_event = &event;
30 R_SUCCEED();
31}
32
33Result IDeliveryCacheProgressService::GetImpl(
34 OutLargeData<DeliveryCacheProgressImpl, BufferAttr_HipcPointer> out_impl) {
35 LOG_DEBUG(Service_BCAT, "called");
36
37 *out_impl = impl;
38 R_SUCCEED();
39}
40
41} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_progress_service.h b/src/core/hle/service/bcat/delivery_cache_progress_service.h
new file mode 100755
index 000000000..f81a13980
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_progress_service.h
@@ -0,0 +1,35 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Kernel {
14class KEvent;
15class KReadableEvent;
16} // namespace Kernel
17
18namespace Service::BCAT {
19struct DeliveryCacheProgressImpl;
20
21class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> {
22public:
23 explicit IDeliveryCacheProgressService(Core::System& system_, Kernel::KReadableEvent& event_,
24 const DeliveryCacheProgressImpl& impl_);
25 ~IDeliveryCacheProgressService() override;
26
27private:
28 Result GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
29 Result GetImpl(OutLargeData<DeliveryCacheProgressImpl, BufferAttr_HipcPointer> out_impl);
30
31 Kernel::KReadableEvent& event;
32 const DeliveryCacheProgressImpl& impl;
33};
34
35} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_storage_service.cpp b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp
new file mode 100755
index 000000000..ee4d02307
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp
@@ -0,0 +1,57 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/bcat_result.h"
5#include "core/hle/service/bcat/delivery_cache_directory_service.h"
6#include "core/hle/service/bcat/delivery_cache_file_service.h"
7#include "core/hle/service/bcat/delivery_cache_storage_service.h"
8#include "core/hle/service/cmif_serialization.h"
9
10namespace Service::BCAT {
11
12IDeliveryCacheStorageService::IDeliveryCacheStorageService(Core::System& system_,
13 FileSys::VirtualDir root_)
14 : ServiceFramework{system_, "IDeliveryCacheStorageService"}, root(std::move(root_)) {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, C<&IDeliveryCacheStorageService::CreateFileService>, "CreateFileService"},
18 {1, C<&IDeliveryCacheStorageService::CreateDirectoryService>, "CreateDirectoryService"},
19 {2, C<&IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory>, "EnumerateDeliveryCacheDirectory"},
20 };
21 // clang-format on
22
23 RegisterHandlers(functions);
24}
25
26IDeliveryCacheStorageService::~IDeliveryCacheStorageService() = default;
27
28Result IDeliveryCacheStorageService::CreateFileService(
29 OutInterface<IDeliveryCacheFileService> out_interface) {
30 LOG_DEBUG(Service_BCAT, "called");
31
32 *out_interface = std::make_shared<IDeliveryCacheFileService>(system, root);
33 R_SUCCEED();
34}
35
36Result IDeliveryCacheStorageService::CreateDirectoryService(
37 OutInterface<IDeliveryCacheDirectoryService> out_interface) {
38 LOG_DEBUG(Service_BCAT, "called");
39
40 *out_interface = std::make_shared<IDeliveryCacheDirectoryService>(system, root);
41 R_SUCCEED();
42}
43
44Result IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory(
45 Out<s32> out_directory_count,
46 OutArray<DirectoryName, BufferAttr_HipcMapAlias> out_directories) {
47 LOG_DEBUG(Service_BCAT, "called, size={:016X}", out_directories.size());
48
49 *out_directory_count =
50 static_cast<s32>(std::min(out_directories.size(), entries.size() - next_read_index));
51 memcpy(out_directories.data(), entries.data() + next_read_index,
52 *out_directory_count * sizeof(DirectoryName));
53 next_read_index += *out_directory_count;
54 R_SUCCEED();
55}
56
57} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/delivery_cache_storage_service.h b/src/core/hle/service/bcat/delivery_cache_storage_service.h
new file mode 100755
index 000000000..3b8dfb1a3
--- /dev/null
+++ b/src/core/hle/service/bcat/delivery_cache_storage_service.h
@@ -0,0 +1,36 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/file_sys/vfs/vfs.h"
7#include "core/hle/service/bcat/bcat_types.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Core {
12class System;
13}
14
15namespace Service::BCAT {
16class IDeliveryCacheFileService;
17class IDeliveryCacheDirectoryService;
18
19class IDeliveryCacheStorageService final : public ServiceFramework<IDeliveryCacheStorageService> {
20public:
21 explicit IDeliveryCacheStorageService(Core::System& system_, FileSys::VirtualDir root_);
22 ~IDeliveryCacheStorageService() override;
23
24private:
25 Result CreateFileService(OutInterface<IDeliveryCacheFileService> out_interface);
26 Result CreateDirectoryService(OutInterface<IDeliveryCacheDirectoryService> out_interface);
27 Result EnumerateDeliveryCacheDirectory(
28 Out<s32> out_directory_count,
29 OutArray<DirectoryName, BufferAttr_HipcMapAlias> out_directories);
30
31 FileSys::VirtualDir root;
32 std::vector<DirectoryName> entries;
33 std::size_t next_read_index = 0;
34};
35
36} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp
new file mode 100755
index 000000000..5be167fce
--- /dev/null
+++ b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp
@@ -0,0 +1,34 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/news/newly_arrived_event_holder.h"
5#include "core/hle/service/cmif_serialization.h"
6
7namespace Service::News {
8
9INewlyArrivedEventHolder::INewlyArrivedEventHolder(Core::System& system_)
10 : ServiceFramework{system_, "INewlyArrivedEventHolder"}, service_context{
11 system_,
12 "INewlyArrivedEventHolder"} {
13 // clang-format off
14 static const FunctionInfo functions[] = {
15 {0, C<&INewlyArrivedEventHolder::Get>, "Get"},
16 };
17 // clang-format on
18
19 RegisterHandlers(functions);
20 arrived_event = service_context.CreateEvent("INewlyArrivedEventHolder::ArrivedEvent");
21}
22
23INewlyArrivedEventHolder::~INewlyArrivedEventHolder() {
24 service_context.CloseEvent(arrived_event);
25}
26
27Result INewlyArrivedEventHolder::Get(OutCopyHandle<Kernel::KReadableEvent> out_event) {
28 LOG_INFO(Service_BCAT, "called");
29
30 *out_event = &arrived_event->GetReadableEvent();
31 R_SUCCEED();
32}
33
34} // namespace Service::News
diff --git a/src/core/hle/service/bcat/news/newly_arrived_event_holder.h b/src/core/hle/service/bcat/news/newly_arrived_event_holder.h
new file mode 100755
index 000000000..6cc9ae099
--- /dev/null
+++ b/src/core/hle/service/bcat/news/newly_arrived_event_holder.h
@@ -0,0 +1,33 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/service.h"
9
10namespace Core {
11class System;
12}
13
14namespace Kernel {
15class KEvent;
16class KReadableEvent;
17} // namespace Kernel
18
19namespace Service::News {
20
21class INewlyArrivedEventHolder final : public ServiceFramework<INewlyArrivedEventHolder> {
22public:
23 explicit INewlyArrivedEventHolder(Core::System& system_);
24 ~INewlyArrivedEventHolder() override;
25
26private:
27 Result Get(OutCopyHandle<Kernel::KReadableEvent> out_event);
28
29 Kernel::KEvent* arrived_event;
30 KernelHelpers::ServiceContext service_context;
31};
32
33} // namespace Service::News
diff --git a/src/core/hle/service/bcat/news/news_data_service.cpp b/src/core/hle/service/bcat/news/news_data_service.cpp
new file mode 100755
index 000000000..08103c9c3
--- /dev/null
+++ b/src/core/hle/service/bcat/news/news_data_service.cpp
@@ -0,0 +1,25 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/news/news_data_service.h"
5
6namespace Service::News {
7
8INewsDataService::INewsDataService(Core::System& system_)
9 : ServiceFramework{system_, "INewsDataService"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "Open"},
13 {1, nullptr, "OpenWithNewsRecordV1"},
14 {2, nullptr, "Read"},
15 {3, nullptr, "GetSize"},
16 {1001, nullptr, "OpenWithNewsRecord"},
17 };
18 // clang-format on
19
20 RegisterHandlers(functions);
21}
22
23INewsDataService::~INewsDataService() = default;
24
25} // 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
new file mode 100755
index 000000000..12082ada4
--- /dev/null
+++ b/src/core/hle/service/bcat/news/news_data_service.h
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::News {
13
14class INewsDataService final : public ServiceFramework<INewsDataService> {
15public:
16 explicit INewsDataService(Core::System& system_);
17 ~INewsDataService() override;
18};
19
20} // 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
new file mode 100755
index 000000000..18109f9b0
--- /dev/null
+++ b/src/core/hle/service/bcat/news/news_database_service.cpp
@@ -0,0 +1,35 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/news/news_database_service.h"
5#include "core/hle/service/cmif_serialization.h"
6
7namespace Service::News {
8
9INewsDatabaseService::INewsDatabaseService(Core::System& system_)
10 : ServiceFramework{system_, "INewsDatabaseService"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, nullptr, "GetListV1"},
14 {1, C<&INewsDatabaseService::Count>, "Count"},
15 {2, nullptr, "CountWithKey"},
16 {3, nullptr, "UpdateIntegerValue"},
17 {4, nullptr, "UpdateIntegerValueWithAddition"},
18 {5, nullptr, "UpdateStringValue"},
19 {1000, nullptr, "GetList"},
20 };
21 // clang-format on
22
23 RegisterHandlers(functions);
24}
25
26INewsDatabaseService::~INewsDatabaseService() = default;
27
28Result INewsDatabaseService::Count(Out<s32> out_count,
29 InBuffer<BufferAttr_HipcPointer> buffer_data) {
30 LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size={}", buffer_data.size());
31 *out_count = 0;
32 R_SUCCEED();
33}
34
35} // 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
new file mode 100755
index 000000000..f5916634b
--- /dev/null
+++ b/src/core/hle/service/bcat/news/news_database_service.h
@@ -0,0 +1,24 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Service::News {
14
15class INewsDatabaseService final : public ServiceFramework<INewsDatabaseService> {
16public:
17 explicit INewsDatabaseService(Core::System& system_);
18 ~INewsDatabaseService() override;
19
20private:
21 Result Count(Out<s32> out_count, InBuffer<BufferAttr_HipcPointer> buffer_data);
22};
23
24} // 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
new file mode 100755
index 000000000..e19cea7b5
--- /dev/null
+++ b/src/core/hle/service/bcat/news/news_service.cpp
@@ -0,0 +1,46 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/news/news_service.h"
5#include "core/hle/service/cmif_serialization.h"
6
7namespace Service::News {
8
9INewsService::INewsService(Core::System& system_) : ServiceFramework{system_, "INewsService"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {10100, nullptr, "PostLocalNews"},
13 {20100, nullptr, "SetPassphrase"},
14 {30100, C<&INewsService::GetSubscriptionStatus>, "GetSubscriptionStatus"},
15 {30101, nullptr, "GetTopicList"},
16 {30110, nullptr, "Unknown30110"},
17 {30200, nullptr, "IsSystemUpdateRequired"},
18 {30201, nullptr, "Unknown30201"},
19 {30210, nullptr, "Unknown30210"},
20 {30300, nullptr, "RequestImmediateReception"},
21 {30400, nullptr, "DecodeArchiveFile"},
22 {30500, nullptr, "Unknown30500"},
23 {30900, nullptr, "Unknown30900"},
24 {30901, nullptr, "Unknown30901"},
25 {30902, nullptr, "Unknown30902"},
26 {40100, nullptr, "SetSubscriptionStatus"},
27 {40101, nullptr, "RequestAutoSubscription"},
28 {40200, nullptr, "ClearStorage"},
29 {40201, nullptr, "ClearSubscriptionStatusAll"},
30 {90100, nullptr, "GetNewsDatabaseDump"},
31 };
32 // clang-format on
33
34 RegisterHandlers(functions);
35}
36
37INewsService::~INewsService() = default;
38
39Result INewsService::GetSubscriptionStatus(Out<u32> out_status,
40 InBuffer<BufferAttr_HipcPointer> buffer_data) {
41 LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size={}", buffer_data.size());
42 *out_status = 0;
43 R_SUCCEED();
44}
45
46} // 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
new file mode 100755
index 000000000..8d06be9d6
--- /dev/null
+++ b/src/core/hle/service/bcat/news/news_service.h
@@ -0,0 +1,24 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Service::News {
14
15class INewsService final : public ServiceFramework<INewsService> {
16public:
17 explicit INewsService(Core::System& system_);
18 ~INewsService() override;
19
20private:
21 Result GetSubscriptionStatus(Out<u32> out_status, InBuffer<BufferAttr_HipcPointer> buffer_data);
22};
23
24} // namespace Service::News
diff --git a/src/core/hle/service/bcat/news/overwrite_event_holder.cpp b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp
new file mode 100755
index 000000000..c32a5ca8f
--- /dev/null
+++ b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp
@@ -0,0 +1,33 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/news/overwrite_event_holder.h"
5#include "core/hle/service/cmif_serialization.h"
6
7namespace Service::News {
8
9IOverwriteEventHolder::IOverwriteEventHolder(Core::System& system_)
10 : ServiceFramework{system_, "IOverwriteEventHolder"}, service_context{system_,
11 "IOverwriteEventHolder"} {
12 // clang-format off
13 static const FunctionInfo functions[] = {
14 {0, C<&IOverwriteEventHolder::Get>, "Get"},
15 };
16 // clang-format on
17
18 RegisterHandlers(functions);
19 overwrite_event = service_context.CreateEvent("IOverwriteEventHolder::OverwriteEvent");
20}
21
22IOverwriteEventHolder::~IOverwriteEventHolder() {
23 service_context.CloseEvent(overwrite_event);
24}
25
26Result IOverwriteEventHolder::Get(OutCopyHandle<Kernel::KReadableEvent> out_event) {
27 LOG_INFO(Service_BCAT, "called");
28
29 *out_event = &overwrite_event->GetReadableEvent();
30 R_SUCCEED();
31}
32
33} // namespace Service::News
diff --git a/src/core/hle/service/bcat/news/overwrite_event_holder.h b/src/core/hle/service/bcat/news/overwrite_event_holder.h
new file mode 100755
index 000000000..cdc87d782
--- /dev/null
+++ b/src/core/hle/service/bcat/news/overwrite_event_holder.h
@@ -0,0 +1,33 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/service.h"
9
10namespace Core {
11class System;
12}
13
14namespace Kernel {
15class KEvent;
16class KReadableEvent;
17} // namespace Kernel
18
19namespace Service::News {
20
21class IOverwriteEventHolder final : public ServiceFramework<IOverwriteEventHolder> {
22public:
23 explicit IOverwriteEventHolder(Core::System& system_);
24 ~IOverwriteEventHolder() override;
25
26private:
27 Result Get(OutCopyHandle<Kernel::KReadableEvent> out_event);
28
29 Kernel::KEvent* overwrite_event;
30 KernelHelpers::ServiceContext service_context;
31};
32
33} // namespace Service::News
diff --git a/src/core/hle/service/bcat/news/service_creator.cpp b/src/core/hle/service/bcat/news/service_creator.cpp
new file mode 100755
index 000000000..d5ba5dff7
--- /dev/null
+++ b/src/core/hle/service/bcat/news/service_creator.cpp
@@ -0,0 +1,64 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/bcat/news/newly_arrived_event_holder.h"
5#include "core/hle/service/bcat/news/news_data_service.h"
6#include "core/hle/service/bcat/news/news_database_service.h"
7#include "core/hle/service/bcat/news/news_service.h"
8#include "core/hle/service/bcat/news/overwrite_event_holder.h"
9#include "core/hle/service/bcat/news/service_creator.h"
10#include "core/hle/service/cmif_serialization.h"
11
12namespace Service::News {
13
14IServiceCreator::IServiceCreator(Core::System& system_, u32 permissions_, const char* name_)
15 : ServiceFramework{system_, name_}, permissions{permissions_} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, C<&IServiceCreator::CreateNewsService>, "CreateNewsService"},
19 {1, C<&IServiceCreator::CreateNewlyArrivedEventHolder>, "CreateNewlyArrivedEventHolder"},
20 {2, C<&IServiceCreator::CreateNewsDataService>, "CreateNewsDataService"},
21 {3, C<&IServiceCreator::CreateNewsDatabaseService>, "CreateNewsDatabaseService"},
22 {4, C<&IServiceCreator::CreateOverwriteEventHolder>, "CreateOverwriteEventHolder"},
23 };
24 // clang-format on
25
26 RegisterHandlers(functions);
27}
28
29IServiceCreator::~IServiceCreator() = default;
30
31Result IServiceCreator::CreateNewsService(OutInterface<INewsService> out_interface) {
32 LOG_INFO(Service_BCAT, "called");
33 *out_interface = std::make_shared<INewsService>(system);
34 R_SUCCEED();
35}
36
37Result IServiceCreator::CreateNewlyArrivedEventHolder(
38 OutInterface<INewlyArrivedEventHolder> out_interface) {
39 LOG_INFO(Service_BCAT, "called");
40 *out_interface = std::make_shared<INewlyArrivedEventHolder>(system);
41 R_SUCCEED();
42}
43
44Result IServiceCreator::CreateNewsDataService(OutInterface<INewsDataService> out_interface) {
45 LOG_INFO(Service_BCAT, "called");
46 *out_interface = std::make_shared<INewsDataService>(system);
47 R_SUCCEED();
48}
49
50Result IServiceCreator::CreateNewsDatabaseService(
51 OutInterface<INewsDatabaseService> out_interface) {
52 LOG_INFO(Service_BCAT, "called");
53 *out_interface = std::make_shared<INewsDatabaseService>(system);
54 R_SUCCEED();
55}
56
57Result IServiceCreator::CreateOverwriteEventHolder(
58 OutInterface<IOverwriteEventHolder> out_interface) {
59 LOG_INFO(Service_BCAT, "called");
60 *out_interface = std::make_shared<IOverwriteEventHolder>(system);
61 R_SUCCEED();
62}
63
64} // namespace Service::News
diff --git a/src/core/hle/service/bcat/news/service_creator.h b/src/core/hle/service/bcat/news/service_creator.h
new file mode 100755
index 000000000..5a62e7c1a
--- /dev/null
+++ b/src/core/hle/service/bcat/news/service_creator.h
@@ -0,0 +1,35 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Service::News {
14class INewsService;
15class INewlyArrivedEventHolder;
16class INewsDataService;
17class INewsDatabaseService;
18class IOverwriteEventHolder;
19
20class IServiceCreator final : public ServiceFramework<IServiceCreator> {
21public:
22 explicit IServiceCreator(Core::System& system_, u32 permissions_, const char* name_);
23 ~IServiceCreator() override;
24
25private:
26 Result CreateNewsService(OutInterface<INewsService> out_interface);
27 Result CreateNewlyArrivedEventHolder(OutInterface<INewlyArrivedEventHolder> out_interface);
28 Result CreateNewsDataService(OutInterface<INewsDataService> out_interface);
29 Result CreateNewsDatabaseService(OutInterface<INewsDatabaseService> out_interface);
30 Result CreateOverwriteEventHolder(OutInterface<IOverwriteEventHolder> out_interface);
31
32 u32 permissions;
33};
34
35} // namespace Service::News
diff --git a/src/core/hle/service/bcat/service_creator.cpp b/src/core/hle/service/bcat/service_creator.cpp
new file mode 100755
index 000000000..a3c5eee04
--- /dev/null
+++ b/src/core/hle/service/bcat/service_creator.cpp
@@ -0,0 +1,62 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/bcat/bcat_service.h"
5#include "core/hle/service/bcat/delivery_cache_storage_service.h"
6#include "core/hle/service/bcat/service_creator.h"
7#include "core/hle/service/cmif_serialization.h"
8#include "core/hle/service/filesystem/filesystem.h"
9
10namespace Service::BCAT {
11
12std::unique_ptr<BcatBackend> CreateBackendFromSettings([[maybe_unused]] Core::System& system,
13 DirectoryGetter getter) {
14 return std::make_unique<NullBcatBackend>(std::move(getter));
15}
16
17IServiceCreator::IServiceCreator(Core::System& system_, const char* name_)
18 : ServiceFramework{system_, name_}, fsc{system.GetFileSystemController()} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, C<&IServiceCreator::CreateBcatService>, "CreateBcatService"},
22 {1, C<&IServiceCreator::CreateDeliveryCacheStorageService>, "CreateDeliveryCacheStorageService"},
23 {2, C<&IServiceCreator::CreateDeliveryCacheStorageServiceWithApplicationId>, "CreateDeliveryCacheStorageServiceWithApplicationId"},
24 {3, nullptr, "CreateDeliveryCacheProgressService"},
25 {4, nullptr, "CreateDeliveryCacheProgressServiceWithApplicationId"},
26 };
27 // clang-format on
28
29 RegisterHandlers(functions);
30
31 backend =
32 CreateBackendFromSettings(system_, [this](u64 tid) { return fsc.GetBCATDirectory(tid); });
33}
34
35IServiceCreator::~IServiceCreator() = default;
36
37Result IServiceCreator::CreateBcatService(ClientProcessId process_id,
38 OutInterface<IBcatService> out_interface) {
39 LOG_INFO(Service_BCAT, "called, process_id={}", process_id.pid);
40 *out_interface = std::make_shared<IBcatService>(system, *backend);
41 R_SUCCEED();
42}
43
44Result IServiceCreator::CreateDeliveryCacheStorageService(
45 ClientProcessId process_id, OutInterface<IDeliveryCacheStorageService> out_interface) {
46 LOG_INFO(Service_BCAT, "called, process_id={}", process_id.pid);
47
48 const auto title_id = system.GetApplicationProcessProgramID();
49 *out_interface =
50 std::make_shared<IDeliveryCacheStorageService>(system, fsc.GetBCATDirectory(title_id));
51 R_SUCCEED();
52}
53
54Result IServiceCreator::CreateDeliveryCacheStorageServiceWithApplicationId(
55 u64 application_id, OutInterface<IDeliveryCacheStorageService> out_interface) {
56 LOG_DEBUG(Service_BCAT, "called, application_id={:016X}", application_id);
57 *out_interface = std::make_shared<IDeliveryCacheStorageService>(
58 system, fsc.GetBCATDirectory(application_id));
59 R_SUCCEED();
60}
61
62} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/service_creator.h b/src/core/hle/service/bcat/service_creator.h
new file mode 100755
index 000000000..50e663324
--- /dev/null
+++ b/src/core/hle/service/bcat/service_creator.h
@@ -0,0 +1,40 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Service::FileSystem {
14class FileSystemController;
15}
16
17namespace Service::BCAT {
18class BcatBackend;
19class IBcatService;
20class IDeliveryCacheStorageService;
21
22class IServiceCreator final : public ServiceFramework<IServiceCreator> {
23public:
24 explicit IServiceCreator(Core::System& system_, const char* name_);
25 ~IServiceCreator() override;
26
27private:
28 Result CreateBcatService(ClientProcessId process_id, OutInterface<IBcatService> out_interface);
29
30 Result CreateDeliveryCacheStorageService(
31 ClientProcessId process_id, OutInterface<IDeliveryCacheStorageService> out_interface);
32
33 Result CreateDeliveryCacheStorageServiceWithApplicationId(
34 u64 application_id, OutInterface<IDeliveryCacheStorageService> out_interface);
35
36 std::unique_ptr<BcatBackend> backend;
37 Service::FileSystem::FileSystemController& fsc;
38};
39
40} // namespace Service::BCAT
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index e47929bf8..87e8eeed8 100755
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -15,7 +15,7 @@
15#include "core/hle/service/aoc/aoc_u.h" 15#include "core/hle/service/aoc/aoc_u.h"
16#include "core/hle/service/apm/apm.h" 16#include "core/hle/service/apm/apm.h"
17#include "core/hle/service/audio/audio.h" 17#include "core/hle/service/audio/audio.h"
18#include "core/hle/service/bcat/bcat_module.h" 18#include "core/hle/service/bcat/bcat.h"
19#include "core/hle/service/bpc/bpc.h" 19#include "core/hle/service/bpc/bpc.h"
20#include "core/hle/service/btdrv/btdrv.h" 20#include "core/hle/service/btdrv/btdrv.h"
21#include "core/hle/service/btm/btm.h" 21#include "core/hle/service/btm/btm.h"