diff options
author | pineappleEA <pineaea@gmail.com> | 2024-02-09 22:10:54 +0100 |
---|---|---|
committer | pineappleEA <pineaea@gmail.com> | 2024-02-09 22:10:54 +0100 |
commit | 60f0c16bdf4b852d854d10b8448eaf675d2371a0 (patch) | |
tree | 424b7b8dbc91b6c2013c44c23d421decb0ae2319 | |
parent | b48b6e3b79c09c46384627ce7ae47a81f77187b8 (diff) |
early-access version 4126EA-4126
35 files changed, 1286 insertions, 85 deletions
@@ -1,7 +1,7 @@ | |||
1 | yuzu emulator early access | 1 | yuzu emulator early access |
2 | ============= | 2 | ============= |
3 | 3 | ||
4 | This is the source code for early-access 4125. | 4 | This 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}; | |||
91 | constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 6325}; | 91 | constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 6325}; |
92 | constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387}; | 92 | constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387}; |
93 | constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388}; | 93 | constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388}; |
94 | constexpr Result ResultPermissionDenied{ErrorModule::FS, 6400}; | ||
94 | constexpr Result ResultBufferAllocationFailed{ErrorModule::FS, 6705}; | 95 | constexpr 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 | ||
35 | void ProgressServiceBackend::StartConnecting() { | 35 | void ProgressServiceBackend::StartConnecting() { |
36 | impl.status = DeliveryCacheProgressImpl::Status::Connecting; | 36 | impl.status = DeliveryCacheProgressStatus::Connecting; |
37 | SignalUpdate(); | 37 | SignalUpdate(); |
38 | } | 38 | } |
39 | 39 | ||
40 | void ProgressServiceBackend::StartProcessingDataList() { | 40 | void ProgressServiceBackend::StartProcessingDataList() { |
41 | impl.status = DeliveryCacheProgressImpl::Status::ProcessingDataList; | 41 | impl.status = DeliveryCacheProgressStatus::ProcessingDataList; |
42 | SignalUpdate(); | 42 | SignalUpdate(); |
43 | } | 43 | } |
44 | 44 | ||
45 | void ProgressServiceBackend::StartDownloadingFile(std::string_view dir_name, | 45 | void 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 | ||
67 | void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) { | 67 | void 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 | ||
77 | void ProgressServiceBackend::FinishDownload(Result result) { | 77 | void 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 | ||
88 | Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} | 88 | BcatBackend::BcatBackend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} |
89 | 89 | ||
90 | Backend::~Backend() = default; | 90 | BcatBackend::~BcatBackend() = default; |
91 | 91 | ||
92 | NullBackend::NullBackend(DirectoryGetter getter) : Backend(std::move(getter)) {} | 92 | NullBcatBackend::NullBcatBackend(DirectoryGetter getter) : BcatBackend(std::move(getter)) {} |
93 | 93 | ||
94 | NullBackend::~NullBackend() = default; | 94 | NullBcatBackend::~NullBcatBackend() = default; |
95 | 95 | ||
96 | bool NullBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) { | 96 | bool 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 | ||
104 | bool NullBackend::SynchronizeDirectory(TitleIDVersion title, std::string name, | 104 | bool 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 | ||
113 | bool NullBackend::Clear(u64 title_id) { | 113 | bool 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 | ||
119 | void NullBackend::SetPassphrase(u64 title_id, const Passphrase& passphrase) { | 119 | void 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 | ||
124 | std::optional<std::vector<u8>> NullBackend::GetLaunchParameter(TitleIDVersion title) { | 124 | std::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 | ||
15 | namespace Core { | 16 | namespace Core { |
@@ -24,44 +25,6 @@ class KReadableEvent; | |||
24 | 25 | ||
25 | namespace Service::BCAT { | 26 | namespace Service::BCAT { |
26 | 27 | ||
27 | struct DeliveryCacheProgressImpl; | ||
28 | |||
29 | using DirectoryGetter = std::function<FileSys::VirtualDir(u64)>; | ||
30 | using Passphrase = std::array<u8, 0x20>; | ||
31 | |||
32 | struct TitleIDVersion { | ||
33 | u64 title_id; | ||
34 | u64 build_id; | ||
35 | }; | ||
36 | |||
37 | using DirectoryName = std::array<char, 0x20>; | ||
38 | using FileName = std::array<char, 0x20>; | ||
39 | |||
40 | struct 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 | }; | ||
62 | static_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. |
67 | class ProgressServiceBackend { | 30 | class 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. |
110 | class Backend { | 73 | class BcatBackend { |
111 | public: | 74 | public: |
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. |
138 | class NullBackend : public Backend { | 101 | class NullBcatBackend : public BcatBackend { |
139 | public: | 102 | public: |
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 | ||
154 | std::unique_ptr<Backend> CreateBackendFromSettings(Core::System& system, DirectoryGetter getter); | 117 | std::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 | ||
6 | namespace Service::BCAT { | 10 | namespace Service::BCAT { |
7 | 11 | ||
8 | BCAT::BCAT(Core::System& system_, std::shared_ptr<Module> module_, | 12 | void 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 | ||
23 | BCAT::~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 | ||
8 | namespace Core { | 8 | namespace Core { |
9 | class System; | 9 | class System; |
@@ -11,11 +11,6 @@ class System; | |||
11 | 11 | ||
12 | namespace Service::BCAT { | 12 | namespace Service::BCAT { |
13 | 13 | ||
14 | class BCAT final : public Module::Interface { | 14 | void LoopProcess(Core::System& system); |
15 | public: | ||
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 | |||
8 | namespace Service::BCAT { | ||
9 | |||
10 | constexpr Result ResultInvalidArgument{ErrorModule::BCAT, 1}; | ||
11 | constexpr Result ResultFailedOpenEntity{ErrorModule::BCAT, 2}; | ||
12 | constexpr Result ResultEntityAlreadyOpen{ErrorModule::BCAT, 6}; | ||
13 | constexpr 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 | |||
16 | namespace Service::BCAT { | ||
17 | |||
18 | static u64 GetCurrentBuildID(const Core::System::CurrentBuildProcessID& id) { | ||
19 | u64 out{}; | ||
20 | std::memcpy(&out, id.data(), sizeof(u64)); | ||
21 | return out; | ||
22 | } | ||
23 | |||
24 | IBcatService::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 | |||
63 | IBcatService::~IBcatService() = default; | ||
64 | |||
65 | Result 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 | |||
79 | Result 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 | |||
95 | Result 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 | |||
111 | Result IBcatService::RegisterSystemApplicationDeliveryTasks() { | ||
112 | LOG_WARNING(Service_BCAT, "(STUBBED) called"); | ||
113 | R_SUCCEED(); | ||
114 | } | ||
115 | |||
116 | Result 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 | |||
124 | ProgressServiceBackend& IBcatService::GetProgressBackend(SyncType type) { | ||
125 | return progress.at(static_cast<size_t>(type)); | ||
126 | } | ||
127 | |||
128 | const 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 | |||
11 | namespace Core { | ||
12 | class System; | ||
13 | } | ||
14 | |||
15 | namespace Service::BCAT { | ||
16 | class BcatBackend; | ||
17 | class IDeliveryCacheStorageService; | ||
18 | class IDeliveryCacheProgressService; | ||
19 | |||
20 | class IBcatService final : public ServiceFramework<IBcatService> { | ||
21 | public: | ||
22 | explicit IBcatService(Core::System& system_, BcatBackend& backend_); | ||
23 | ~IBcatService() override; | ||
24 | |||
25 | private: | ||
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 | |||
37 | private: | ||
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 | |||
14 | namespace Service::BCAT { | ||
15 | |||
16 | using DirectoryName = std::array<char, 0x20>; | ||
17 | using FileName = std::array<char, 0x20>; | ||
18 | using BcatDigest = std::array<u8, 0x10>; | ||
19 | using Passphrase = std::array<u8, 0x20>; | ||
20 | using DirectoryGetter = std::function<FileSys::VirtualDir(u64)>; | ||
21 | |||
22 | enum class SyncType { | ||
23 | Normal, | ||
24 | Directory, | ||
25 | Count, | ||
26 | }; | ||
27 | |||
28 | enum 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 | |||
38 | struct DeliveryCacheDirectoryEntry { | ||
39 | FileName name; | ||
40 | u64 size; | ||
41 | BcatDigest digest; | ||
42 | }; | ||
43 | |||
44 | struct TitleIDVersion { | ||
45 | u64 title_id; | ||
46 | u64 build_id; | ||
47 | }; | ||
48 | |||
49 | struct 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 | }; | ||
61 | static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200, | ||
62 | "DeliveryCacheProgressImpl has incorrect size."); | ||
63 | static_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 | |||
13 | namespace 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. | ||
18 | constexpr 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 | |||
31 | constexpr Result VerifyNameValidDir(DirectoryName name) { | ||
32 | return VerifyNameValidInternal(name, '-'); | ||
33 | } | ||
34 | |||
35 | constexpr 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 | |||
11 | namespace 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. | ||
15 | static 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 | |||
22 | IDeliveryCacheDirectoryService::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 | |||
36 | IDeliveryCacheDirectoryService::~IDeliveryCacheDirectoryService() = default; | ||
37 | |||
38 | Result 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 | |||
53 | Result 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 | |||
71 | Result 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 | |||
11 | namespace Core { | ||
12 | class System; | ||
13 | } | ||
14 | |||
15 | namespace Service::BCAT { | ||
16 | |||
17 | class IDeliveryCacheDirectoryService final | ||
18 | : public ServiceFramework<IDeliveryCacheDirectoryService> { | ||
19 | public: | ||
20 | explicit IDeliveryCacheDirectoryService(Core::System& system_, FileSys::VirtualDir root_); | ||
21 | ~IDeliveryCacheDirectoryService() override; | ||
22 | |||
23 | private: | ||
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 | |||
10 | namespace Service::BCAT { | ||
11 | |||
12 | IDeliveryCacheFileService::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 | |||
27 | IDeliveryCacheFileService::~IDeliveryCacheFileService() = default; | ||
28 | |||
29 | Result 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 | |||
51 | Result 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 | |||
64 | Result 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 | |||
73 | Result 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 | |||
11 | namespace Core { | ||
12 | class System; | ||
13 | } | ||
14 | |||
15 | namespace Service::BCAT { | ||
16 | |||
17 | class IDeliveryCacheFileService final : public ServiceFramework<IDeliveryCacheFileService> { | ||
18 | public: | ||
19 | explicit IDeliveryCacheFileService(Core::System& system_, FileSys::VirtualDir root_); | ||
20 | ~IDeliveryCacheFileService() override; | ||
21 | |||
22 | private: | ||
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 | |||
8 | namespace Service::BCAT { | ||
9 | |||
10 | IDeliveryCacheProgressService::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 | |||
24 | IDeliveryCacheProgressService::~IDeliveryCacheProgressService() = default; | ||
25 | |||
26 | Result IDeliveryCacheProgressService::GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
27 | LOG_DEBUG(Service_BCAT, "called"); | ||
28 | |||
29 | *out_event = &event; | ||
30 | R_SUCCEED(); | ||
31 | } | ||
32 | |||
33 | Result 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 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Kernel { | ||
14 | class KEvent; | ||
15 | class KReadableEvent; | ||
16 | } // namespace Kernel | ||
17 | |||
18 | namespace Service::BCAT { | ||
19 | struct DeliveryCacheProgressImpl; | ||
20 | |||
21 | class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> { | ||
22 | public: | ||
23 | explicit IDeliveryCacheProgressService(Core::System& system_, Kernel::KReadableEvent& event_, | ||
24 | const DeliveryCacheProgressImpl& impl_); | ||
25 | ~IDeliveryCacheProgressService() override; | ||
26 | |||
27 | private: | ||
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 | |||
10 | namespace Service::BCAT { | ||
11 | |||
12 | IDeliveryCacheStorageService::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 | |||
26 | IDeliveryCacheStorageService::~IDeliveryCacheStorageService() = default; | ||
27 | |||
28 | Result 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 | |||
36 | Result 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 | |||
44 | Result 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 | |||
11 | namespace Core { | ||
12 | class System; | ||
13 | } | ||
14 | |||
15 | namespace Service::BCAT { | ||
16 | class IDeliveryCacheFileService; | ||
17 | class IDeliveryCacheDirectoryService; | ||
18 | |||
19 | class IDeliveryCacheStorageService final : public ServiceFramework<IDeliveryCacheStorageService> { | ||
20 | public: | ||
21 | explicit IDeliveryCacheStorageService(Core::System& system_, FileSys::VirtualDir root_); | ||
22 | ~IDeliveryCacheStorageService() override; | ||
23 | |||
24 | private: | ||
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 | |||
7 | namespace Service::News { | ||
8 | |||
9 | INewlyArrivedEventHolder::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 | |||
23 | INewlyArrivedEventHolder::~INewlyArrivedEventHolder() { | ||
24 | service_context.CloseEvent(arrived_event); | ||
25 | } | ||
26 | |||
27 | Result 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 | |||
10 | namespace Core { | ||
11 | class System; | ||
12 | } | ||
13 | |||
14 | namespace Kernel { | ||
15 | class KEvent; | ||
16 | class KReadableEvent; | ||
17 | } // namespace Kernel | ||
18 | |||
19 | namespace Service::News { | ||
20 | |||
21 | class INewlyArrivedEventHolder final : public ServiceFramework<INewlyArrivedEventHolder> { | ||
22 | public: | ||
23 | explicit INewlyArrivedEventHolder(Core::System& system_); | ||
24 | ~INewlyArrivedEventHolder() override; | ||
25 | |||
26 | private: | ||
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 | |||
6 | namespace Service::News { | ||
7 | |||
8 | INewsDataService::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 | |||
23 | INewsDataService::~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 | |||
8 | namespace Core { | ||
9 | class System; | ||
10 | } | ||
11 | |||
12 | namespace Service::News { | ||
13 | |||
14 | class INewsDataService final : public ServiceFramework<INewsDataService> { | ||
15 | public: | ||
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 | |||
7 | namespace Service::News { | ||
8 | |||
9 | INewsDatabaseService::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 | |||
26 | INewsDatabaseService::~INewsDatabaseService() = default; | ||
27 | |||
28 | Result 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 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::News { | ||
14 | |||
15 | class INewsDatabaseService final : public ServiceFramework<INewsDatabaseService> { | ||
16 | public: | ||
17 | explicit INewsDatabaseService(Core::System& system_); | ||
18 | ~INewsDatabaseService() override; | ||
19 | |||
20 | private: | ||
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 | |||
7 | namespace Service::News { | ||
8 | |||
9 | INewsService::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 | |||
37 | INewsService::~INewsService() = default; | ||
38 | |||
39 | Result 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 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::News { | ||
14 | |||
15 | class INewsService final : public ServiceFramework<INewsService> { | ||
16 | public: | ||
17 | explicit INewsService(Core::System& system_); | ||
18 | ~INewsService() override; | ||
19 | |||
20 | private: | ||
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 | |||
7 | namespace Service::News { | ||
8 | |||
9 | IOverwriteEventHolder::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 | |||
22 | IOverwriteEventHolder::~IOverwriteEventHolder() { | ||
23 | service_context.CloseEvent(overwrite_event); | ||
24 | } | ||
25 | |||
26 | Result 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 | |||
10 | namespace Core { | ||
11 | class System; | ||
12 | } | ||
13 | |||
14 | namespace Kernel { | ||
15 | class KEvent; | ||
16 | class KReadableEvent; | ||
17 | } // namespace Kernel | ||
18 | |||
19 | namespace Service::News { | ||
20 | |||
21 | class IOverwriteEventHolder final : public ServiceFramework<IOverwriteEventHolder> { | ||
22 | public: | ||
23 | explicit IOverwriteEventHolder(Core::System& system_); | ||
24 | ~IOverwriteEventHolder() override; | ||
25 | |||
26 | private: | ||
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 | |||
12 | namespace Service::News { | ||
13 | |||
14 | IServiceCreator::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 | |||
29 | IServiceCreator::~IServiceCreator() = default; | ||
30 | |||
31 | Result 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 | |||
37 | Result 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 | |||
44 | Result 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 | |||
50 | Result 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 | |||
57 | Result 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 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::News { | ||
14 | class INewsService; | ||
15 | class INewlyArrivedEventHolder; | ||
16 | class INewsDataService; | ||
17 | class INewsDatabaseService; | ||
18 | class IOverwriteEventHolder; | ||
19 | |||
20 | class IServiceCreator final : public ServiceFramework<IServiceCreator> { | ||
21 | public: | ||
22 | explicit IServiceCreator(Core::System& system_, u32 permissions_, const char* name_); | ||
23 | ~IServiceCreator() override; | ||
24 | |||
25 | private: | ||
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 | |||
10 | namespace Service::BCAT { | ||
11 | |||
12 | std::unique_ptr<BcatBackend> CreateBackendFromSettings([[maybe_unused]] Core::System& system, | ||
13 | DirectoryGetter getter) { | ||
14 | return std::make_unique<NullBcatBackend>(std::move(getter)); | ||
15 | } | ||
16 | |||
17 | IServiceCreator::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 | |||
35 | IServiceCreator::~IServiceCreator() = default; | ||
36 | |||
37 | Result 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 | |||
44 | Result 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 | |||
54 | Result 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 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::FileSystem { | ||
14 | class FileSystemController; | ||
15 | } | ||
16 | |||
17 | namespace Service::BCAT { | ||
18 | class BcatBackend; | ||
19 | class IBcatService; | ||
20 | class IDeliveryCacheStorageService; | ||
21 | |||
22 | class IServiceCreator final : public ServiceFramework<IServiceCreator> { | ||
23 | public: | ||
24 | explicit IServiceCreator(Core::System& system_, const char* name_); | ||
25 | ~IServiceCreator() override; | ||
26 | |||
27 | private: | ||
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" |