diff options
Diffstat (limited to 'src/core/hle')
42 files changed, 1129 insertions, 526 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index f21553644..fad111d44 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -25,8 +25,8 @@ | |||
| 25 | #include "core/hle/service/acc/async_context.h" | 25 | #include "core/hle/service/acc/async_context.h" |
| 26 | #include "core/hle/service/acc/errors.h" | 26 | #include "core/hle/service/acc/errors.h" |
| 27 | #include "core/hle/service/acc/profile_manager.h" | 27 | #include "core/hle/service/acc/profile_manager.h" |
| 28 | #include "core/hle/service/cmif_serialization.h" | ||
| 28 | #include "core/hle/service/glue/glue_manager.h" | 29 | #include "core/hle/service/glue/glue_manager.h" |
| 29 | #include "core/hle/service/ipc_helpers.h" | ||
| 30 | #include "core/hle/service/server_manager.h" | 30 | #include "core/hle/service/server_manager.h" |
| 31 | #include "core/loader/loader.h" | 31 | #include "core/loader/loader.h" |
| 32 | 32 | ||
| @@ -74,12 +74,12 @@ static void SanitizeJPEGImageSize(std::vector<u8>& image) { | |||
| 74 | 74 | ||
| 75 | class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> { | 75 | class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> { |
| 76 | public: | 76 | public: |
| 77 | explicit IManagerForSystemService(Core::System& system_, Common::UUID) | 77 | explicit IManagerForSystemService(Core::System& system_, Common::UUID uuid) |
| 78 | : ServiceFramework{system_, "IManagerForSystemService"} { | 78 | : ServiceFramework{system_, "IManagerForSystemService"}, account_id{uuid} { |
| 79 | // clang-format off | 79 | // clang-format off |
| 80 | static const FunctionInfo functions[] = { | 80 | static const FunctionInfo functions[] = { |
| 81 | {0, &IManagerForSystemService::CheckAvailability, "CheckAvailability"}, | 81 | {0, D<&IManagerForSystemService::CheckAvailability>, "CheckAvailability"}, |
| 82 | {1, nullptr, "GetAccountId"}, | 82 | {1, D<&IManagerForSystemService::GetAccountId>, "GetAccountId"}, |
| 83 | {2, nullptr, "EnsureIdTokenCacheAsync"}, | 83 | {2, nullptr, "EnsureIdTokenCacheAsync"}, |
| 84 | {3, nullptr, "LoadIdTokenCache"}, | 84 | {3, nullptr, "LoadIdTokenCache"}, |
| 85 | {100, nullptr, "SetSystemProgramIdentification"}, | 85 | {100, nullptr, "SetSystemProgramIdentification"}, |
| @@ -109,11 +109,18 @@ public: | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | private: | 111 | private: |
| 112 | void CheckAvailability(HLERequestContext& ctx) { | 112 | Result CheckAvailability() { |
| 113 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 113 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 114 | IPC::ResponseBuilder rb{ctx, 2}; | 114 | R_SUCCEED(); |
| 115 | rb.Push(ResultSuccess); | ||
| 116 | } | 115 | } |
| 116 | |||
| 117 | Result GetAccountId(Out<u64> out_account_id) { | ||
| 118 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | ||
| 119 | *out_account_id = account_id.Hash(); | ||
| 120 | R_SUCCEED(); | ||
| 121 | } | ||
| 122 | |||
| 123 | Common::UUID account_id; | ||
| 117 | }; | 124 | }; |
| 118 | 125 | ||
| 119 | // 3.0.0+ | 126 | // 3.0.0+ |
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 92f704c2f..eecc94387 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp | |||
| @@ -23,7 +23,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> | |||
| 23 | {99, nullptr, "DebugActivateOpenContextRetention"}, | 23 | {99, nullptr, "DebugActivateOpenContextRetention"}, |
| 24 | {100, nullptr, "GetUserRegistrationNotifier"}, | 24 | {100, nullptr, "GetUserRegistrationNotifier"}, |
| 25 | {101, nullptr, "GetUserStateChangeNotifier"}, | 25 | {101, nullptr, "GetUserStateChangeNotifier"}, |
| 26 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, | 26 | {102, &ACC_U1::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"}, |
| 27 | {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, | 27 | {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, |
| 28 | {104, nullptr, "GetProfileUpdateNotifier"}, | 28 | {104, nullptr, "GetProfileUpdateNotifier"}, |
| 29 | {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, | 29 | {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, |
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h index 46afb3996..a14defb40 100644 --- a/src/core/hle/service/am/am_types.h +++ b/src/core/hle/service/am/am_types.h | |||
| @@ -48,11 +48,6 @@ enum class SystemButtonType { | |||
| 48 | CaptureButtonLongPressing, | 48 | CaptureButtonLongPressing, |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | enum class SysPlatformRegion : s32 { | ||
| 52 | Global = 1, | ||
| 53 | Terra = 2, | ||
| 54 | }; | ||
| 55 | |||
| 56 | struct AppletProcessLaunchReason { | 51 | struct AppletProcessLaunchReason { |
| 57 | u8 flag; | 52 | u8 flag; |
| 58 | INSERT_PADDING_BYTES(3); | 53 | INSERT_PADDING_BYTES(3); |
diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp index 548498e83..a32855ffa 100644 --- a/src/core/hle/service/am/service/common_state_getter.cpp +++ b/src/core/hle/service/am/service/common_state_getter.cpp | |||
| @@ -260,9 +260,9 @@ Result ICommonStateGetter::GetAppletLaunchedHistory( | |||
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | Result ICommonStateGetter::GetSettingsPlatformRegion( | 262 | Result ICommonStateGetter::GetSettingsPlatformRegion( |
| 263 | Out<SysPlatformRegion> out_settings_platform_region) { | 263 | Out<Set::PlatformRegion> out_settings_platform_region) { |
| 264 | LOG_INFO(Service_AM, "called"); | 264 | LOG_INFO(Service_AM, "called"); |
| 265 | *out_settings_platform_region = SysPlatformRegion::Global; | 265 | *out_settings_platform_region = Set::PlatformRegion::Global; |
| 266 | R_SUCCEED(); | 266 | R_SUCCEED(); |
| 267 | } | 267 | } |
| 268 | 268 | ||
diff --git a/src/core/hle/service/am/service/common_state_getter.h b/src/core/hle/service/am/service/common_state_getter.h index 5a8dca3d6..59a46fa94 100644 --- a/src/core/hle/service/am/service/common_state_getter.h +++ b/src/core/hle/service/am/service/common_state_getter.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "core/hle/service/cmif_types.h" | 8 | #include "core/hle/service/cmif_types.h" |
| 9 | #include "core/hle/service/pm/pm.h" | 9 | #include "core/hle/service/pm/pm.h" |
| 10 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 11 | #include "core/hle/service/set/settings_types.h" | ||
| 11 | 12 | ||
| 12 | namespace Kernel { | 13 | namespace Kernel { |
| 13 | class KReadableEvent; | 14 | class KReadableEvent; |
| @@ -50,7 +51,7 @@ private: | |||
| 50 | Result GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info); | 51 | Result GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info); |
| 51 | Result GetAppletLaunchedHistory(Out<s32> out_count, | 52 | Result GetAppletLaunchedHistory(Out<s32> out_count, |
| 52 | OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids); | 53 | OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids); |
| 53 | Result GetSettingsPlatformRegion(Out<SysPlatformRegion> out_settings_platform_region); | 54 | Result GetSettingsPlatformRegion(Out<Set::PlatformRegion> out_settings_platform_region); |
| 54 | Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(); | 55 | Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(); |
| 55 | 56 | ||
| 56 | void SetCpuBoostMode(HLERequestContext& ctx); | 57 | void SetCpuBoostMode(HLERequestContext& ctx); |
diff --git a/src/core/hle/service/aoc/addon_content_manager.cpp b/src/core/hle/service/aoc/addon_content_manager.cpp new file mode 100644 index 000000000..d47f57d64 --- /dev/null +++ b/src/core/hle/service/aoc/addon_content_manager.cpp | |||
| @@ -0,0 +1,223 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <numeric> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "common/settings.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "core/file_sys/common_funcs.h" | ||
| 12 | #include "core/file_sys/content_archive.h" | ||
| 13 | #include "core/file_sys/control_metadata.h" | ||
| 14 | #include "core/file_sys/nca_metadata.h" | ||
| 15 | #include "core/file_sys/patch_manager.h" | ||
| 16 | #include "core/file_sys/registered_cache.h" | ||
| 17 | #include "core/hle/kernel/k_event.h" | ||
| 18 | #include "core/hle/service/aoc/addon_content_manager.h" | ||
| 19 | #include "core/hle/service/aoc/purchase_event_manager.h" | ||
| 20 | #include "core/hle/service/cmif_serialization.h" | ||
| 21 | #include "core/hle/service/ipc_helpers.h" | ||
| 22 | #include "core/hle/service/server_manager.h" | ||
| 23 | #include "core/loader/loader.h" | ||
| 24 | |||
| 25 | namespace Service::AOC { | ||
| 26 | |||
| 27 | static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) { | ||
| 28 | return FileSys::GetBaseTitleID(title_id) == base; | ||
| 29 | } | ||
| 30 | |||
| 31 | static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) { | ||
| 32 | std::vector<u64> add_on_content; | ||
| 33 | const auto& rcu = system.GetContentProvider(); | ||
| 34 | const auto list = | ||
| 35 | rcu.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); | ||
| 36 | std::transform(list.begin(), list.end(), std::back_inserter(add_on_content), | ||
| 37 | [](const FileSys::ContentProviderEntry& rce) { return rce.title_id; }); | ||
| 38 | add_on_content.erase( | ||
| 39 | std::remove_if( | ||
| 40 | add_on_content.begin(), add_on_content.end(), | ||
| 41 | [&rcu](u64 tid) { | ||
| 42 | return rcu.GetEntry(tid, FileSys::ContentRecordType::Data)->GetStatus() != | ||
| 43 | Loader::ResultStatus::Success; | ||
| 44 | }), | ||
| 45 | add_on_content.end()); | ||
| 46 | return add_on_content; | ||
| 47 | } | ||
| 48 | |||
| 49 | IAddOnContentManager::IAddOnContentManager(Core::System& system_) | ||
| 50 | : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)}, | ||
| 51 | service_context{system_, "aoc:u"} { | ||
| 52 | // clang-format off | ||
| 53 | static const FunctionInfo functions[] = { | ||
| 54 | {0, nullptr, "CountAddOnContentByApplicationId"}, | ||
| 55 | {1, nullptr, "ListAddOnContentByApplicationId"}, | ||
| 56 | {2, D<&IAddOnContentManager::CountAddOnContent>, "CountAddOnContent"}, | ||
| 57 | {3, D<&IAddOnContentManager::ListAddOnContent>, "ListAddOnContent"}, | ||
| 58 | {4, nullptr, "GetAddOnContentBaseIdByApplicationId"}, | ||
| 59 | {5, D<&IAddOnContentManager::GetAddOnContentBaseId>, "GetAddOnContentBaseId"}, | ||
| 60 | {6, nullptr, "PrepareAddOnContentByApplicationId"}, | ||
| 61 | {7, D<&IAddOnContentManager::PrepareAddOnContent>, "PrepareAddOnContent"}, | ||
| 62 | {8, D<&IAddOnContentManager::GetAddOnContentListChangedEvent>, "GetAddOnContentListChangedEvent"}, | ||
| 63 | {9, nullptr, "GetAddOnContentLostErrorCode"}, | ||
| 64 | {10, D<&IAddOnContentManager::GetAddOnContentListChangedEventWithProcessId>, "GetAddOnContentListChangedEventWithProcessId"}, | ||
| 65 | {11, D<&IAddOnContentManager::NotifyMountAddOnContent>, "NotifyMountAddOnContent"}, | ||
| 66 | {12, D<&IAddOnContentManager::NotifyUnmountAddOnContent>, "NotifyUnmountAddOnContent"}, | ||
| 67 | {13, nullptr, "IsAddOnContentMountedForDebug"}, | ||
| 68 | {50, D<&IAddOnContentManager::CheckAddOnContentMountStatus>, "CheckAddOnContentMountStatus"}, | ||
| 69 | {100, D<&IAddOnContentManager::CreateEcPurchasedEventManager>, "CreateEcPurchasedEventManager"}, | ||
| 70 | {101, D<&IAddOnContentManager::CreatePermanentEcPurchasedEventManager>, "CreatePermanentEcPurchasedEventManager"}, | ||
| 71 | {110, nullptr, "CreateContentsServiceManager"}, | ||
| 72 | {200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"}, | ||
| 73 | {300, nullptr, "SetupHostAddOnContent"}, | ||
| 74 | {301, nullptr, "GetRegisteredAddOnContentPath"}, | ||
| 75 | {302, nullptr, "UpdateCachedList"}, | ||
| 76 | }; | ||
| 77 | // clang-format on | ||
| 78 | |||
| 79 | RegisterHandlers(functions); | ||
| 80 | |||
| 81 | aoc_change_event = service_context.CreateEvent("GetAddOnContentListChanged:Event"); | ||
| 82 | } | ||
| 83 | |||
| 84 | IAddOnContentManager::~IAddOnContentManager() { | ||
| 85 | service_context.CloseEvent(aoc_change_event); | ||
| 86 | } | ||
| 87 | |||
| 88 | Result IAddOnContentManager::CountAddOnContent(Out<u32> out_count, ClientProcessId process_id) { | ||
| 89 | LOG_DEBUG(Service_AOC, "called. process_id={}", process_id.pid); | ||
| 90 | |||
| 91 | const auto current = system.GetApplicationProcessProgramID(); | ||
| 92 | |||
| 93 | const auto& disabled = Settings::values.disabled_addons[current]; | ||
| 94 | if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) { | ||
| 95 | *out_count = 0; | ||
| 96 | R_SUCCEED(); | ||
| 97 | } | ||
| 98 | |||
| 99 | *out_count = static_cast<u32>( | ||
| 100 | std::count_if(add_on_content.begin(), add_on_content.end(), | ||
| 101 | [current](u64 tid) { return CheckAOCTitleIDMatchesBase(tid, current); })); | ||
| 102 | |||
| 103 | R_SUCCEED(); | ||
| 104 | } | ||
| 105 | |||
| 106 | Result IAddOnContentManager::ListAddOnContent(Out<u32> out_count, | ||
| 107 | OutBuffer<BufferAttr_HipcMapAlias> out_addons, | ||
| 108 | u32 offset, u32 count, ClientProcessId process_id) { | ||
| 109 | LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count, | ||
| 110 | process_id.pid); | ||
| 111 | |||
| 112 | const auto current = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID()); | ||
| 113 | |||
| 114 | std::vector<u32> out; | ||
| 115 | const auto& disabled = Settings::values.disabled_addons[current]; | ||
| 116 | if (std::find(disabled.begin(), disabled.end(), "DLC") == disabled.end()) { | ||
| 117 | for (u64 content_id : add_on_content) { | ||
| 118 | if (FileSys::GetBaseTitleID(content_id) != current) { | ||
| 119 | continue; | ||
| 120 | } | ||
| 121 | |||
| 122 | out.push_back(static_cast<u32>(FileSys::GetAOCID(content_id))); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | // TODO(DarkLordZach): Find the correct error code. | ||
| 127 | R_UNLESS(out.size() >= offset, ResultUnknown); | ||
| 128 | |||
| 129 | *out_count = static_cast<u32>(std::min<size_t>(out.size() - offset, count)); | ||
| 130 | std::rotate(out.begin(), out.begin() + offset, out.end()); | ||
| 131 | |||
| 132 | std::memcpy(out_addons.data(), out.data(), *out_count * sizeof(u32)); | ||
| 133 | |||
| 134 | R_SUCCEED(); | ||
| 135 | } | ||
| 136 | |||
| 137 | Result IAddOnContentManager::GetAddOnContentBaseId(Out<u64> out_title_id, | ||
| 138 | ClientProcessId process_id) { | ||
| 139 | LOG_DEBUG(Service_AOC, "called. process_id={}", process_id.pid); | ||
| 140 | |||
| 141 | const auto title_id = system.GetApplicationProcessProgramID(); | ||
| 142 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), | ||
| 143 | system.GetContentProvider()}; | ||
| 144 | |||
| 145 | const auto res = pm.GetControlMetadata(); | ||
| 146 | if (res.first == nullptr) { | ||
| 147 | *out_title_id = FileSys::GetAOCBaseTitleID(title_id); | ||
| 148 | R_SUCCEED(); | ||
| 149 | } | ||
| 150 | |||
| 151 | *out_title_id = res.first->GetDLCBaseTitleId(); | ||
| 152 | |||
| 153 | R_SUCCEED(); | ||
| 154 | } | ||
| 155 | |||
| 156 | Result IAddOnContentManager::PrepareAddOnContent(s32 addon_index, ClientProcessId process_id) { | ||
| 157 | LOG_WARNING(Service_AOC, "(STUBBED) called with addon_index={}, process_id={}", addon_index, | ||
| 158 | process_id.pid); | ||
| 159 | |||
| 160 | R_SUCCEED(); | ||
| 161 | } | ||
| 162 | |||
| 163 | Result IAddOnContentManager::GetAddOnContentListChangedEvent( | ||
| 164 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 165 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 166 | |||
| 167 | *out_event = &aoc_change_event->GetReadableEvent(); | ||
| 168 | |||
| 169 | R_SUCCEED(); | ||
| 170 | } | ||
| 171 | |||
| 172 | Result IAddOnContentManager::GetAddOnContentListChangedEventWithProcessId( | ||
| 173 | OutCopyHandle<Kernel::KReadableEvent> out_event, ClientProcessId process_id) { | ||
| 174 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 175 | |||
| 176 | *out_event = &aoc_change_event->GetReadableEvent(); | ||
| 177 | |||
| 178 | R_SUCCEED(); | ||
| 179 | } | ||
| 180 | |||
| 181 | Result IAddOnContentManager::NotifyMountAddOnContent() { | ||
| 182 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 183 | |||
| 184 | R_SUCCEED(); | ||
| 185 | } | ||
| 186 | |||
| 187 | Result IAddOnContentManager::NotifyUnmountAddOnContent() { | ||
| 188 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 189 | |||
| 190 | R_SUCCEED(); | ||
| 191 | } | ||
| 192 | |||
| 193 | Result IAddOnContentManager::CheckAddOnContentMountStatus() { | ||
| 194 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 195 | |||
| 196 | R_SUCCEED(); | ||
| 197 | } | ||
| 198 | |||
| 199 | Result IAddOnContentManager::CreateEcPurchasedEventManager( | ||
| 200 | OutInterface<IPurchaseEventManager> out_interface) { | ||
| 201 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 202 | |||
| 203 | *out_interface = std::make_shared<IPurchaseEventManager>(system); | ||
| 204 | |||
| 205 | R_SUCCEED(); | ||
| 206 | } | ||
| 207 | |||
| 208 | Result IAddOnContentManager::CreatePermanentEcPurchasedEventManager( | ||
| 209 | OutInterface<IPurchaseEventManager> out_interface) { | ||
| 210 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 211 | |||
| 212 | *out_interface = std::make_shared<IPurchaseEventManager>(system); | ||
| 213 | |||
| 214 | R_SUCCEED(); | ||
| 215 | } | ||
| 216 | |||
| 217 | void LoopProcess(Core::System& system) { | ||
| 218 | auto server_manager = std::make_unique<ServerManager>(system); | ||
| 219 | server_manager->RegisterNamedService("aoc:u", std::make_shared<IAddOnContentManager>(system)); | ||
| 220 | ServerManager::RunServer(std::move(server_manager)); | ||
| 221 | } | ||
| 222 | |||
| 223 | } // namespace Service::AOC | ||
diff --git a/src/core/hle/service/aoc/addon_content_manager.h b/src/core/hle/service/aoc/addon_content_manager.h new file mode 100644 index 000000000..91857df4c --- /dev/null +++ b/src/core/hle/service/aoc/addon_content_manager.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.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 | } | ||
| 17 | |||
| 18 | namespace Service::AOC { | ||
| 19 | |||
| 20 | class IPurchaseEventManager; | ||
| 21 | |||
| 22 | class IAddOnContentManager final : public ServiceFramework<IAddOnContentManager> { | ||
| 23 | public: | ||
| 24 | explicit IAddOnContentManager(Core::System& system); | ||
| 25 | ~IAddOnContentManager() override; | ||
| 26 | |||
| 27 | Result CountAddOnContent(Out<u32> out_count, ClientProcessId process_id); | ||
| 28 | Result ListAddOnContent(Out<u32> out_count, OutBuffer<BufferAttr_HipcMapAlias> out_addons, | ||
| 29 | u32 offset, u32 count, ClientProcessId process_id); | ||
| 30 | Result GetAddOnContentBaseId(Out<u64> out_title_id, ClientProcessId process_id); | ||
| 31 | Result PrepareAddOnContent(s32 addon_index, ClientProcessId process_id); | ||
| 32 | Result GetAddOnContentListChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 33 | Result GetAddOnContentListChangedEventWithProcessId( | ||
| 34 | OutCopyHandle<Kernel::KReadableEvent> out_event, ClientProcessId process_id); | ||
| 35 | Result NotifyMountAddOnContent(); | ||
| 36 | Result NotifyUnmountAddOnContent(); | ||
| 37 | Result CheckAddOnContentMountStatus(); | ||
| 38 | Result CreateEcPurchasedEventManager(OutInterface<IPurchaseEventManager> out_interface); | ||
| 39 | Result CreatePermanentEcPurchasedEventManager( | ||
| 40 | OutInterface<IPurchaseEventManager> out_interface); | ||
| 41 | |||
| 42 | private: | ||
| 43 | std::vector<u64> add_on_content; | ||
| 44 | KernelHelpers::ServiceContext service_context; | ||
| 45 | |||
| 46 | Kernel::KEvent* aoc_change_event; | ||
| 47 | }; | ||
| 48 | |||
| 49 | void LoopProcess(Core::System& system); | ||
| 50 | |||
| 51 | } // namespace Service::AOC | ||
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp deleted file mode 100644 index 486719cc0..000000000 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ /dev/null | |||
| @@ -1,340 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <numeric> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "common/settings.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "core/file_sys/common_funcs.h" | ||
| 12 | #include "core/file_sys/content_archive.h" | ||
| 13 | #include "core/file_sys/control_metadata.h" | ||
| 14 | #include "core/file_sys/nca_metadata.h" | ||
| 15 | #include "core/file_sys/patch_manager.h" | ||
| 16 | #include "core/file_sys/registered_cache.h" | ||
| 17 | #include "core/hle/kernel/k_event.h" | ||
| 18 | #include "core/hle/service/aoc/aoc_u.h" | ||
| 19 | #include "core/hle/service/ipc_helpers.h" | ||
| 20 | #include "core/hle/service/server_manager.h" | ||
| 21 | #include "core/loader/loader.h" | ||
| 22 | |||
| 23 | namespace Service::AOC { | ||
| 24 | |||
| 25 | constexpr Result ResultNoPurchasedProductInfoAvailable{ErrorModule::NIMShop, 400}; | ||
| 26 | |||
| 27 | static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) { | ||
| 28 | return FileSys::GetBaseTitleID(title_id) == base; | ||
| 29 | } | ||
| 30 | |||
| 31 | static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) { | ||
| 32 | std::vector<u64> add_on_content; | ||
| 33 | const auto& rcu = system.GetContentProvider(); | ||
| 34 | const auto list = | ||
| 35 | rcu.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); | ||
| 36 | std::transform(list.begin(), list.end(), std::back_inserter(add_on_content), | ||
| 37 | [](const FileSys::ContentProviderEntry& rce) { return rce.title_id; }); | ||
| 38 | add_on_content.erase( | ||
| 39 | std::remove_if( | ||
| 40 | add_on_content.begin(), add_on_content.end(), | ||
| 41 | [&rcu](u64 tid) { | ||
| 42 | return rcu.GetEntry(tid, FileSys::ContentRecordType::Data)->GetStatus() != | ||
| 43 | Loader::ResultStatus::Success; | ||
| 44 | }), | ||
| 45 | add_on_content.end()); | ||
| 46 | return add_on_content; | ||
| 47 | } | ||
| 48 | |||
| 49 | class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> { | ||
| 50 | public: | ||
| 51 | explicit IPurchaseEventManager(Core::System& system_) | ||
| 52 | : ServiceFramework{system_, "IPurchaseEventManager"}, service_context{ | ||
| 53 | system, "IPurchaseEventManager"} { | ||
| 54 | // clang-format off | ||
| 55 | static const FunctionInfo functions[] = { | ||
| 56 | {0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"}, | ||
| 57 | {1, &IPurchaseEventManager::SetDeliveryTarget, "SetDeliveryTarget"}, | ||
| 58 | {2, &IPurchaseEventManager::GetPurchasedEventReadableHandle, "GetPurchasedEventReadableHandle"}, | ||
| 59 | {3, &IPurchaseEventManager::PopPurchasedProductInfo, "PopPurchasedProductInfo"}, | ||
| 60 | {4, &IPurchaseEventManager::PopPurchasedProductInfoWithUid, "PopPurchasedProductInfoWithUid"}, | ||
| 61 | }; | ||
| 62 | // clang-format on | ||
| 63 | |||
| 64 | RegisterHandlers(functions); | ||
| 65 | |||
| 66 | purchased_event = service_context.CreateEvent("IPurchaseEventManager:PurchasedEvent"); | ||
| 67 | } | ||
| 68 | |||
| 69 | ~IPurchaseEventManager() override { | ||
| 70 | service_context.CloseEvent(purchased_event); | ||
| 71 | } | ||
| 72 | |||
| 73 | private: | ||
| 74 | void SetDefaultDeliveryTarget(HLERequestContext& ctx) { | ||
| 75 | IPC::RequestParser rp{ctx}; | ||
| 76 | |||
| 77 | const auto unknown_1 = rp.Pop<u64>(); | ||
| 78 | [[maybe_unused]] const auto unknown_2 = ctx.ReadBuffer(); | ||
| 79 | |||
| 80 | LOG_WARNING(Service_AOC, "(STUBBED) called, unknown_1={}", unknown_1); | ||
| 81 | |||
| 82 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 83 | rb.Push(ResultSuccess); | ||
| 84 | } | ||
| 85 | |||
| 86 | void SetDeliveryTarget(HLERequestContext& ctx) { | ||
| 87 | IPC::RequestParser rp{ctx}; | ||
| 88 | |||
| 89 | const auto unknown_1 = rp.Pop<u64>(); | ||
| 90 | [[maybe_unused]] const auto unknown_2 = ctx.ReadBuffer(); | ||
| 91 | |||
| 92 | LOG_WARNING(Service_AOC, "(STUBBED) called, unknown_1={}", unknown_1); | ||
| 93 | |||
| 94 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 95 | rb.Push(ResultSuccess); | ||
| 96 | } | ||
| 97 | |||
| 98 | void GetPurchasedEventReadableHandle(HLERequestContext& ctx) { | ||
| 99 | LOG_WARNING(Service_AOC, "called"); | ||
| 100 | |||
| 101 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 102 | rb.Push(ResultSuccess); | ||
| 103 | rb.PushCopyObjects(purchased_event->GetReadableEvent()); | ||
| 104 | } | ||
| 105 | |||
| 106 | void PopPurchasedProductInfo(HLERequestContext& ctx) { | ||
| 107 | LOG_DEBUG(Service_AOC, "(STUBBED) called"); | ||
| 108 | |||
| 109 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 110 | rb.Push(ResultNoPurchasedProductInfoAvailable); | ||
| 111 | } | ||
| 112 | |||
| 113 | void PopPurchasedProductInfoWithUid(HLERequestContext& ctx) { | ||
| 114 | LOG_DEBUG(Service_AOC, "(STUBBED) called"); | ||
| 115 | |||
| 116 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 117 | rb.Push(ResultNoPurchasedProductInfoAvailable); | ||
| 118 | } | ||
| 119 | |||
| 120 | KernelHelpers::ServiceContext service_context; | ||
| 121 | |||
| 122 | Kernel::KEvent* purchased_event; | ||
| 123 | }; | ||
| 124 | |||
| 125 | AOC_U::AOC_U(Core::System& system_) | ||
| 126 | : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)}, | ||
| 127 | service_context{system_, "aoc:u"} { | ||
| 128 | // clang-format off | ||
| 129 | static const FunctionInfo functions[] = { | ||
| 130 | {0, nullptr, "CountAddOnContentByApplicationId"}, | ||
| 131 | {1, nullptr, "ListAddOnContentByApplicationId"}, | ||
| 132 | {2, &AOC_U::CountAddOnContent, "CountAddOnContent"}, | ||
| 133 | {3, &AOC_U::ListAddOnContent, "ListAddOnContent"}, | ||
| 134 | {4, nullptr, "GetAddOnContentBaseIdByApplicationId"}, | ||
| 135 | {5, &AOC_U::GetAddOnContentBaseId, "GetAddOnContentBaseId"}, | ||
| 136 | {6, nullptr, "PrepareAddOnContentByApplicationId"}, | ||
| 137 | {7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"}, | ||
| 138 | {8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"}, | ||
| 139 | {9, nullptr, "GetAddOnContentLostErrorCode"}, | ||
| 140 | {10, &AOC_U::GetAddOnContentListChangedEventWithProcessId, "GetAddOnContentListChangedEventWithProcessId"}, | ||
| 141 | {11, &AOC_U::NotifyMountAddOnContent, "NotifyMountAddOnContent"}, | ||
| 142 | {12, &AOC_U::NotifyUnmountAddOnContent, "NotifyUnmountAddOnContent"}, | ||
| 143 | {13, nullptr, "IsAddOnContentMountedForDebug"}, | ||
| 144 | {50, &AOC_U::CheckAddOnContentMountStatus, "CheckAddOnContentMountStatus"}, | ||
| 145 | {100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"}, | ||
| 146 | {101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"}, | ||
| 147 | {110, nullptr, "CreateContentsServiceManager"}, | ||
| 148 | {200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"}, | ||
| 149 | {300, nullptr, "SetupHostAddOnContent"}, | ||
| 150 | {301, nullptr, "GetRegisteredAddOnContentPath"}, | ||
| 151 | {302, nullptr, "UpdateCachedList"}, | ||
| 152 | }; | ||
| 153 | // clang-format on | ||
| 154 | |||
| 155 | RegisterHandlers(functions); | ||
| 156 | |||
| 157 | aoc_change_event = service_context.CreateEvent("GetAddOnContentListChanged:Event"); | ||
| 158 | } | ||
| 159 | |||
| 160 | AOC_U::~AOC_U() { | ||
| 161 | service_context.CloseEvent(aoc_change_event); | ||
| 162 | } | ||
| 163 | |||
| 164 | void AOC_U::CountAddOnContent(HLERequestContext& ctx) { | ||
| 165 | struct Parameters { | ||
| 166 | u64 process_id; | ||
| 167 | }; | ||
| 168 | static_assert(sizeof(Parameters) == 8); | ||
| 169 | |||
| 170 | IPC::RequestParser rp{ctx}; | ||
| 171 | const auto params = rp.PopRaw<Parameters>(); | ||
| 172 | |||
| 173 | LOG_DEBUG(Service_AOC, "called. process_id={}", params.process_id); | ||
| 174 | |||
| 175 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 176 | rb.Push(ResultSuccess); | ||
| 177 | |||
| 178 | const auto current = system.GetApplicationProcessProgramID(); | ||
| 179 | |||
| 180 | const auto& disabled = Settings::values.disabled_addons[current]; | ||
| 181 | if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) { | ||
| 182 | rb.Push<u32>(0); | ||
| 183 | return; | ||
| 184 | } | ||
| 185 | |||
| 186 | rb.Push<u32>(static_cast<u32>( | ||
| 187 | std::count_if(add_on_content.begin(), add_on_content.end(), | ||
| 188 | [current](u64 tid) { return CheckAOCTitleIDMatchesBase(tid, current); }))); | ||
| 189 | } | ||
| 190 | |||
| 191 | void AOC_U::ListAddOnContent(HLERequestContext& ctx) { | ||
| 192 | struct Parameters { | ||
| 193 | u32 offset; | ||
| 194 | u32 count; | ||
| 195 | u64 process_id; | ||
| 196 | }; | ||
| 197 | static_assert(sizeof(Parameters) == 16); | ||
| 198 | |||
| 199 | IPC::RequestParser rp{ctx}; | ||
| 200 | const auto [offset, count, process_id] = rp.PopRaw<Parameters>(); | ||
| 201 | |||
| 202 | LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count, | ||
| 203 | process_id); | ||
| 204 | |||
| 205 | const auto current = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID()); | ||
| 206 | |||
| 207 | std::vector<u32> out; | ||
| 208 | const auto& disabled = Settings::values.disabled_addons[current]; | ||
| 209 | if (std::find(disabled.begin(), disabled.end(), "DLC") == disabled.end()) { | ||
| 210 | for (u64 content_id : add_on_content) { | ||
| 211 | if (FileSys::GetBaseTitleID(content_id) != current) { | ||
| 212 | continue; | ||
| 213 | } | ||
| 214 | |||
| 215 | out.push_back(static_cast<u32>(FileSys::GetAOCID(content_id))); | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | if (out.size() < offset) { | ||
| 220 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 221 | // TODO(DarkLordZach): Find the correct error code. | ||
| 222 | rb.Push(ResultUnknown); | ||
| 223 | return; | ||
| 224 | } | ||
| 225 | |||
| 226 | const auto out_count = static_cast<u32>(std::min<size_t>(out.size() - offset, count)); | ||
| 227 | std::rotate(out.begin(), out.begin() + offset, out.end()); | ||
| 228 | out.resize(out_count); | ||
| 229 | |||
| 230 | ctx.WriteBuffer(out); | ||
| 231 | |||
| 232 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 233 | rb.Push(ResultSuccess); | ||
| 234 | rb.Push(out_count); | ||
| 235 | } | ||
| 236 | |||
| 237 | void AOC_U::GetAddOnContentBaseId(HLERequestContext& ctx) { | ||
| 238 | struct Parameters { | ||
| 239 | u64 process_id; | ||
| 240 | }; | ||
| 241 | static_assert(sizeof(Parameters) == 8); | ||
| 242 | |||
| 243 | IPC::RequestParser rp{ctx}; | ||
| 244 | const auto params = rp.PopRaw<Parameters>(); | ||
| 245 | |||
| 246 | LOG_DEBUG(Service_AOC, "called. process_id={}", params.process_id); | ||
| 247 | |||
| 248 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 249 | rb.Push(ResultSuccess); | ||
| 250 | |||
| 251 | const auto title_id = system.GetApplicationProcessProgramID(); | ||
| 252 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), | ||
| 253 | system.GetContentProvider()}; | ||
| 254 | |||
| 255 | const auto res = pm.GetControlMetadata(); | ||
| 256 | if (res.first == nullptr) { | ||
| 257 | rb.Push(FileSys::GetAOCBaseTitleID(title_id)); | ||
| 258 | return; | ||
| 259 | } | ||
| 260 | |||
| 261 | rb.Push(res.first->GetDLCBaseTitleId()); | ||
| 262 | } | ||
| 263 | |||
| 264 | void AOC_U::PrepareAddOnContent(HLERequestContext& ctx) { | ||
| 265 | struct Parameters { | ||
| 266 | s32 addon_index; | ||
| 267 | u64 process_id; | ||
| 268 | }; | ||
| 269 | static_assert(sizeof(Parameters) == 16); | ||
| 270 | |||
| 271 | IPC::RequestParser rp{ctx}; | ||
| 272 | const auto [addon_index, process_id] = rp.PopRaw<Parameters>(); | ||
| 273 | |||
| 274 | LOG_WARNING(Service_AOC, "(STUBBED) called with addon_index={}, process_id={}", addon_index, | ||
| 275 | process_id); | ||
| 276 | |||
| 277 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 278 | rb.Push(ResultSuccess); | ||
| 279 | } | ||
| 280 | |||
| 281 | void AOC_U::GetAddOnContentListChangedEvent(HLERequestContext& ctx) { | ||
| 282 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 283 | |||
| 284 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 285 | rb.Push(ResultSuccess); | ||
| 286 | rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); | ||
| 287 | } | ||
| 288 | |||
| 289 | void AOC_U::GetAddOnContentListChangedEventWithProcessId(HLERequestContext& ctx) { | ||
| 290 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 291 | |||
| 292 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 293 | rb.Push(ResultSuccess); | ||
| 294 | rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); | ||
| 295 | } | ||
| 296 | |||
| 297 | void AOC_U::NotifyMountAddOnContent(HLERequestContext& ctx) { | ||
| 298 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 299 | |||
| 300 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 301 | rb.Push(ResultSuccess); | ||
| 302 | } | ||
| 303 | |||
| 304 | void AOC_U::NotifyUnmountAddOnContent(HLERequestContext& ctx) { | ||
| 305 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 306 | |||
| 307 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 308 | rb.Push(ResultSuccess); | ||
| 309 | } | ||
| 310 | |||
| 311 | void AOC_U::CheckAddOnContentMountStatus(HLERequestContext& ctx) { | ||
| 312 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 313 | |||
| 314 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 315 | rb.Push(ResultSuccess); | ||
| 316 | } | ||
| 317 | |||
| 318 | void AOC_U::CreateEcPurchasedEventManager(HLERequestContext& ctx) { | ||
| 319 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 320 | |||
| 321 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 322 | rb.Push(ResultSuccess); | ||
| 323 | rb.PushIpcInterface<IPurchaseEventManager>(system); | ||
| 324 | } | ||
| 325 | |||
| 326 | void AOC_U::CreatePermanentEcPurchasedEventManager(HLERequestContext& ctx) { | ||
| 327 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | ||
| 328 | |||
| 329 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 330 | rb.Push(ResultSuccess); | ||
| 331 | rb.PushIpcInterface<IPurchaseEventManager>(system); | ||
| 332 | } | ||
| 333 | |||
| 334 | void LoopProcess(Core::System& system) { | ||
| 335 | auto server_manager = std::make_unique<ServerManager>(system); | ||
| 336 | server_manager->RegisterNamedService("aoc:u", std::make_shared<AOC_U>(system)); | ||
| 337 | ServerManager::RunServer(std::move(server_manager)); | ||
| 338 | } | ||
| 339 | |||
| 340 | } // namespace Service::AOC | ||
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h deleted file mode 100644 index 12ccfeb6a..000000000 --- a/src/core/hle/service/aoc/aoc_u.h +++ /dev/null | |||
| @@ -1,45 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/kernel_helpers.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | class KEvent; | ||
| 15 | } | ||
| 16 | |||
| 17 | namespace Service::AOC { | ||
| 18 | |||
| 19 | class AOC_U final : public ServiceFramework<AOC_U> { | ||
| 20 | public: | ||
| 21 | explicit AOC_U(Core::System& system); | ||
| 22 | ~AOC_U() override; | ||
| 23 | |||
| 24 | private: | ||
| 25 | void CountAddOnContent(HLERequestContext& ctx); | ||
| 26 | void ListAddOnContent(HLERequestContext& ctx); | ||
| 27 | void GetAddOnContentBaseId(HLERequestContext& ctx); | ||
| 28 | void PrepareAddOnContent(HLERequestContext& ctx); | ||
| 29 | void GetAddOnContentListChangedEvent(HLERequestContext& ctx); | ||
| 30 | void GetAddOnContentListChangedEventWithProcessId(HLERequestContext& ctx); | ||
| 31 | void NotifyMountAddOnContent(HLERequestContext& ctx); | ||
| 32 | void NotifyUnmountAddOnContent(HLERequestContext& ctx); | ||
| 33 | void CheckAddOnContentMountStatus(HLERequestContext& ctx); | ||
| 34 | void CreateEcPurchasedEventManager(HLERequestContext& ctx); | ||
| 35 | void CreatePermanentEcPurchasedEventManager(HLERequestContext& ctx); | ||
| 36 | |||
| 37 | std::vector<u64> add_on_content; | ||
| 38 | KernelHelpers::ServiceContext service_context; | ||
| 39 | |||
| 40 | Kernel::KEvent* aoc_change_event; | ||
| 41 | }; | ||
| 42 | |||
| 43 | void LoopProcess(Core::System& system); | ||
| 44 | |||
| 45 | } // namespace Service::AOC | ||
diff --git a/src/core/hle/service/aoc/purchase_event_manager.cpp b/src/core/hle/service/aoc/purchase_event_manager.cpp new file mode 100644 index 000000000..9e718510b --- /dev/null +++ b/src/core/hle/service/aoc/purchase_event_manager.cpp | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/aoc/purchase_event_manager.h" | ||
| 5 | #include "core/hle/service/cmif_serialization.h" | ||
| 6 | |||
| 7 | namespace Service::AOC { | ||
| 8 | |||
| 9 | constexpr Result ResultNoPurchasedProductInfoAvailable{ErrorModule::NIMShop, 400}; | ||
| 10 | |||
| 11 | IPurchaseEventManager::IPurchaseEventManager(Core::System& system_) | ||
| 12 | : ServiceFramework{system_, "IPurchaseEventManager"}, service_context{system, | ||
| 13 | "IPurchaseEventManager"} { | ||
| 14 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {0, D<&IPurchaseEventManager::SetDefaultDeliveryTarget>, "SetDefaultDeliveryTarget"}, | ||
| 17 | {1, D<&IPurchaseEventManager::SetDeliveryTarget>, "SetDeliveryTarget"}, | ||
| 18 | {2, D<&IPurchaseEventManager::GetPurchasedEvent>, "GetPurchasedEvent"}, | ||
| 19 | {3, D<&IPurchaseEventManager::PopPurchasedProductInfo>, "PopPurchasedProductInfo"}, | ||
| 20 | {4, D<&IPurchaseEventManager::PopPurchasedProductInfoWithUid>, "PopPurchasedProductInfoWithUid"}, | ||
| 21 | }; | ||
| 22 | // clang-format on | ||
| 23 | |||
| 24 | RegisterHandlers(functions); | ||
| 25 | |||
| 26 | purchased_event = service_context.CreateEvent("IPurchaseEventManager:PurchasedEvent"); | ||
| 27 | } | ||
| 28 | |||
| 29 | IPurchaseEventManager::~IPurchaseEventManager() { | ||
| 30 | service_context.CloseEvent(purchased_event); | ||
| 31 | } | ||
| 32 | |||
| 33 | Result IPurchaseEventManager::SetDefaultDeliveryTarget( | ||
| 34 | ClientProcessId process_id, InBuffer<BufferAttr_HipcMapAlias> in_buffer) { | ||
| 35 | LOG_WARNING(Service_AOC, "(STUBBED) called, process_id={}", process_id.pid); | ||
| 36 | |||
| 37 | R_SUCCEED(); | ||
| 38 | } | ||
| 39 | |||
| 40 | Result IPurchaseEventManager::SetDeliveryTarget(u64 unknown, | ||
| 41 | InBuffer<BufferAttr_HipcMapAlias> in_buffer) { | ||
| 42 | LOG_WARNING(Service_AOC, "(STUBBED) called, unknown={}", unknown); | ||
| 43 | |||
| 44 | R_SUCCEED(); | ||
| 45 | } | ||
| 46 | |||
| 47 | Result IPurchaseEventManager::GetPurchasedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 48 | LOG_WARNING(Service_AOC, "called"); | ||
| 49 | |||
| 50 | *out_event = &purchased_event->GetReadableEvent(); | ||
| 51 | |||
| 52 | R_SUCCEED(); | ||
| 53 | } | ||
| 54 | |||
| 55 | Result IPurchaseEventManager::PopPurchasedProductInfo() { | ||
| 56 | LOG_DEBUG(Service_AOC, "(STUBBED) called"); | ||
| 57 | |||
| 58 | R_RETURN(ResultNoPurchasedProductInfoAvailable); | ||
| 59 | } | ||
| 60 | |||
| 61 | Result IPurchaseEventManager::PopPurchasedProductInfoWithUid() { | ||
| 62 | LOG_DEBUG(Service_AOC, "(STUBBED) called"); | ||
| 63 | |||
| 64 | R_RETURN(ResultNoPurchasedProductInfoAvailable); | ||
| 65 | } | ||
| 66 | |||
| 67 | } // namespace Service::AOC | ||
diff --git a/src/core/hle/service/aoc/purchase_event_manager.h b/src/core/hle/service/aoc/purchase_event_manager.h new file mode 100644 index 000000000..ea3836bc9 --- /dev/null +++ b/src/core/hle/service/aoc/purchase_event_manager.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.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/os/event.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::AOC { | ||
| 12 | |||
| 13 | class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> { | ||
| 14 | public: | ||
| 15 | explicit IPurchaseEventManager(Core::System& system_); | ||
| 16 | ~IPurchaseEventManager() override; | ||
| 17 | |||
| 18 | Result SetDefaultDeliveryTarget(ClientProcessId process_id, | ||
| 19 | InBuffer<BufferAttr_HipcMapAlias> in_buffer); | ||
| 20 | Result SetDeliveryTarget(u64 unknown, InBuffer<BufferAttr_HipcMapAlias> in_buffer); | ||
| 21 | Result GetPurchasedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 22 | Result PopPurchasedProductInfo(); | ||
| 23 | Result PopPurchasedProductInfoWithUid(); | ||
| 24 | |||
| 25 | private: | ||
| 26 | KernelHelpers::ServiceContext service_context; | ||
| 27 | Kernel::KEvent* purchased_event; | ||
| 28 | }; | ||
| 29 | |||
| 30 | } // namespace Service::AOC | ||
diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp index c9804cf9c..7a51d1023 100644 --- a/src/core/hle/service/audio/audio_controller.cpp +++ b/src/core/hle/service/audio/audio_controller.cpp | |||
| @@ -138,7 +138,7 @@ Result IAudioController::SetOutputModeSetting(Set::AudioOutputModeTarget target, | |||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | Result IAudioController::SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode) { | 140 | Result IAudioController::SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode) { |
| 141 | LOG_WARNING(Audio, "(STUBBED) called"); | 141 | LOG_WARNING(Audio, "(STUBBED) called, output_level_mode={}", output_level_mode); |
| 142 | R_SUCCEED(); | 142 | R_SUCCEED(); |
| 143 | } | 143 | } |
| 144 | 144 | ||
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index 38cdd57ad..83618a956 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "core/core.h" | 5 | #include "core/core.h" |
| 6 | #include "core/hle/kernel/k_event.h" | 6 | #include "core/hle/kernel/k_event.h" |
| 7 | #include "core/hle/service/btdrv/btdrv.h" | 7 | #include "core/hle/service/btdrv/btdrv.h" |
| 8 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | 9 | #include "core/hle/service/ipc_helpers.h" |
| 9 | #include "core/hle/service/kernel_helpers.h" | 10 | #include "core/hle/service/kernel_helpers.h" |
| 10 | #include "core/hle/service/server_manager.h" | 11 | #include "core/hle/service/server_manager.h" |
| @@ -13,9 +14,9 @@ | |||
| 13 | 14 | ||
| 14 | namespace Service::BtDrv { | 15 | namespace Service::BtDrv { |
| 15 | 16 | ||
| 16 | class Bt final : public ServiceFramework<Bt> { | 17 | class IBluetoothUser final : public ServiceFramework<IBluetoothUser> { |
| 17 | public: | 18 | public: |
| 18 | explicit Bt(Core::System& system_) | 19 | explicit IBluetoothUser(Core::System& system_) |
| 19 | : ServiceFramework{system_, "bt"}, service_context{system_, "bt"} { | 20 | : ServiceFramework{system_, "bt"}, service_context{system_, "bt"} { |
| 20 | // clang-format off | 21 | // clang-format off |
| 21 | static const FunctionInfo functions[] = { | 22 | static const FunctionInfo functions[] = { |
| @@ -28,7 +29,7 @@ public: | |||
| 28 | {6, nullptr, "SetLeResponse"}, | 29 | {6, nullptr, "SetLeResponse"}, |
| 29 | {7, nullptr, "LeSendIndication"}, | 30 | {7, nullptr, "LeSendIndication"}, |
| 30 | {8, nullptr, "GetLeEventInfo"}, | 31 | {8, nullptr, "GetLeEventInfo"}, |
| 31 | {9, &Bt::RegisterBleEvent, "RegisterBleEvent"}, | 32 | {9, C<&IBluetoothUser::RegisterBleEvent>, "RegisterBleEvent"}, |
| 32 | }; | 33 | }; |
| 33 | // clang-format on | 34 | // clang-format on |
| 34 | RegisterHandlers(functions); | 35 | RegisterHandlers(functions); |
| @@ -36,17 +37,16 @@ public: | |||
| 36 | register_event = service_context.CreateEvent("BT:RegisterEvent"); | 37 | register_event = service_context.CreateEvent("BT:RegisterEvent"); |
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | ~Bt() override { | 40 | ~IBluetoothUser() override { |
| 40 | service_context.CloseEvent(register_event); | 41 | service_context.CloseEvent(register_event); |
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | private: | 44 | private: |
| 44 | void RegisterBleEvent(HLERequestContext& ctx) { | 45 | Result RegisterBleEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { |
| 45 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | 46 | LOG_WARNING(Service_BTM, "(STUBBED) called"); |
| 46 | 47 | ||
| 47 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 48 | *out_event = ®ister_event->GetReadableEvent(); |
| 48 | rb.Push(ResultSuccess); | 49 | R_SUCCEED(); |
| 49 | rb.PushCopyObjects(register_event->GetReadableEvent()); | ||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | KernelHelpers::ServiceContext service_context; | 52 | KernelHelpers::ServiceContext service_context; |
| @@ -54,9 +54,9 @@ private: | |||
| 54 | Kernel::KEvent* register_event; | 54 | Kernel::KEvent* register_event; |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | class BtDrv final : public ServiceFramework<BtDrv> { | 57 | class IBluetoothDriver final : public ServiceFramework<IBluetoothDriver> { |
| 58 | public: | 58 | public: |
| 59 | explicit BtDrv(Core::System& system_) : ServiceFramework{system_, "btdrv"} { | 59 | explicit IBluetoothDriver(Core::System& system_) : ServiceFramework{system_, "btdrv"} { |
| 60 | // clang-format off | 60 | // clang-format off |
| 61 | static const FunctionInfo functions[] = { | 61 | static const FunctionInfo functions[] = { |
| 62 | {0, nullptr, "InitializeBluetoothDriver"}, | 62 | {0, nullptr, "InitializeBluetoothDriver"}, |
| @@ -93,7 +93,7 @@ public: | |||
| 93 | {31, nullptr, "EnableMcMode"}, | 93 | {31, nullptr, "EnableMcMode"}, |
| 94 | {32, nullptr, "EnableLlrScan"}, | 94 | {32, nullptr, "EnableLlrScan"}, |
| 95 | {33, nullptr, "DisableLlrScan"}, | 95 | {33, nullptr, "DisableLlrScan"}, |
| 96 | {34, nullptr, "EnableRadio"}, | 96 | {34, C<&IBluetoothDriver::EnableRadio>, "EnableRadio"}, |
| 97 | {35, nullptr, "SetVisibility"}, | 97 | {35, nullptr, "SetVisibility"}, |
| 98 | {36, nullptr, "EnableTbfcScan"}, | 98 | {36, nullptr, "EnableTbfcScan"}, |
| 99 | {37, nullptr, "RegisterHidReportEvent"}, | 99 | {37, nullptr, "RegisterHidReportEvent"}, |
| @@ -195,13 +195,19 @@ public: | |||
| 195 | 195 | ||
| 196 | RegisterHandlers(functions); | 196 | RegisterHandlers(functions); |
| 197 | } | 197 | } |
| 198 | |||
| 199 | private: | ||
| 200 | Result EnableRadio() { | ||
| 201 | LOG_WARNING(Service_BTDRV, "(STUBBED) called"); | ||
| 202 | R_SUCCEED(); | ||
| 203 | } | ||
| 198 | }; | 204 | }; |
| 199 | 205 | ||
| 200 | void LoopProcess(Core::System& system) { | 206 | void LoopProcess(Core::System& system) { |
| 201 | auto server_manager = std::make_unique<ServerManager>(system); | 207 | auto server_manager = std::make_unique<ServerManager>(system); |
| 202 | 208 | ||
| 203 | server_manager->RegisterNamedService("btdrv", std::make_shared<BtDrv>(system)); | 209 | server_manager->RegisterNamedService("btdrv", std::make_shared<IBluetoothDriver>(system)); |
| 204 | server_manager->RegisterNamedService("bt", std::make_shared<Bt>(system)); | 210 | server_manager->RegisterNamedService("bt", std::make_shared<IBluetoothUser>(system)); |
| 205 | ServerManager::RunServer(std::move(server_manager)); | 211 | ServerManager::RunServer(std::move(server_manager)); |
| 206 | } | 212 | } |
| 207 | 213 | ||
diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp index 39ae3a723..6b7eab5ef 100644 --- a/src/core/hle/service/erpt/erpt.cpp +++ b/src/core/hle/service/erpt/erpt.cpp | |||
| @@ -18,7 +18,7 @@ public: | |||
| 18 | // clang-format off | 18 | // clang-format off |
| 19 | static const FunctionInfo functions[] = { | 19 | static const FunctionInfo functions[] = { |
| 20 | {0, C<&ErrorReportContext::SubmitContext>, "SubmitContext"}, | 20 | {0, C<&ErrorReportContext::SubmitContext>, "SubmitContext"}, |
| 21 | {1, nullptr, "CreateReportV0"}, | 21 | {1, C<&ErrorReportContext::CreateReportV0>, "CreateReportV0"}, |
| 22 | {2, nullptr, "SetInitialLaunchSettingsCompletionTime"}, | 22 | {2, nullptr, "SetInitialLaunchSettingsCompletionTime"}, |
| 23 | {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"}, | 23 | {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"}, |
| 24 | {4, nullptr, "UpdatePowerOnTime"}, | 24 | {4, nullptr, "UpdatePowerOnTime"}, |
| @@ -28,7 +28,8 @@ public: | |||
| 28 | {8, nullptr, "ClearApplicationLaunchTime"}, | 28 | {8, nullptr, "ClearApplicationLaunchTime"}, |
| 29 | {9, nullptr, "SubmitAttachment"}, | 29 | {9, nullptr, "SubmitAttachment"}, |
| 30 | {10, nullptr, "CreateReportWithAttachments"}, | 30 | {10, nullptr, "CreateReportWithAttachments"}, |
| 31 | {11, nullptr, "CreateReport"}, | 31 | {11, C<&ErrorReportContext::CreateReportV1>, "CreateReportV1"}, |
| 32 | {12, C<&ErrorReportContext::CreateReport>, "CreateReport"}, | ||
| 32 | {20, nullptr, "RegisterRunningApplet"}, | 33 | {20, nullptr, "RegisterRunningApplet"}, |
| 33 | {21, nullptr, "UnregisterRunningApplet"}, | 34 | {21, nullptr, "UnregisterRunningApplet"}, |
| 34 | {22, nullptr, "UpdateAppletSuspendedDuration"}, | 35 | {22, nullptr, "UpdateAppletSuspendedDuration"}, |
| @@ -40,10 +41,37 @@ public: | |||
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | private: | 43 | private: |
| 43 | Result SubmitContext(InBuffer<BufferAttr_HipcMapAlias> buffer_a, | 44 | Result SubmitContext(InBuffer<BufferAttr_HipcMapAlias> context_entry, |
| 44 | InBuffer<BufferAttr_HipcMapAlias> buffer_b) { | 45 | InBuffer<BufferAttr_HipcMapAlias> field_list) { |
| 45 | LOG_WARNING(Service_SET, "(STUBBED) called, buffer_a_size={}, buffer_b_size={}", | 46 | LOG_WARNING(Service_SET, "(STUBBED) called, context_entry_size={}, field_list_size={}", |
| 46 | buffer_a.size(), buffer_b.size()); | 47 | context_entry.size(), field_list.size()); |
| 48 | R_SUCCEED(); | ||
| 49 | } | ||
| 50 | |||
| 51 | Result CreateReportV0(u32 report_type, InBuffer<BufferAttr_HipcMapAlias> context_entry, | ||
| 52 | InBuffer<BufferAttr_HipcMapAlias> report_list, | ||
| 53 | InBuffer<BufferAttr_HipcMapAlias> report_meta_data) { | ||
| 54 | LOG_WARNING(Service_SET, "(STUBBED) called, report_type={:#x}", report_type); | ||
| 55 | R_SUCCEED(); | ||
| 56 | } | ||
| 57 | |||
| 58 | Result CreateReportV1(u32 report_type, u32 unknown, | ||
| 59 | InBuffer<BufferAttr_HipcMapAlias> context_entry, | ||
| 60 | InBuffer<BufferAttr_HipcMapAlias> report_list, | ||
| 61 | InBuffer<BufferAttr_HipcMapAlias> report_meta_data) { | ||
| 62 | LOG_WARNING(Service_SET, "(STUBBED) called, report_type={:#x}, unknown={:#x}", report_type, | ||
| 63 | unknown); | ||
| 64 | R_SUCCEED(); | ||
| 65 | } | ||
| 66 | |||
| 67 | Result CreateReport(u32 report_type, u32 unknown, u32 create_report_option_flag, | ||
| 68 | InBuffer<BufferAttr_HipcMapAlias> context_entry, | ||
| 69 | InBuffer<BufferAttr_HipcMapAlias> report_list, | ||
| 70 | InBuffer<BufferAttr_HipcMapAlias> report_meta_data) { | ||
| 71 | LOG_WARNING( | ||
| 72 | Service_SET, | ||
| 73 | "(STUBBED) called, report_type={:#x}, unknown={:#x}, create_report_option_flag={:#x}", | ||
| 74 | report_type, unknown, create_report_option_flag); | ||
| 47 | R_SUCCEED(); | 75 | R_SUCCEED(); |
| 48 | } | 76 | } |
| 49 | }; | 77 | }; |
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp index 223284255..60290f1a6 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp | |||
| @@ -71,7 +71,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) | |||
| 71 | {28, nullptr, "DeleteSaveDataFileSystemBySaveDataAttribute"}, | 71 | {28, nullptr, "DeleteSaveDataFileSystemBySaveDataAttribute"}, |
| 72 | {30, nullptr, "OpenGameCardStorage"}, | 72 | {30, nullptr, "OpenGameCardStorage"}, |
| 73 | {31, nullptr, "OpenGameCardFileSystem"}, | 73 | {31, nullptr, "OpenGameCardFileSystem"}, |
| 74 | {32, nullptr, "ExtendSaveDataFileSystem"}, | 74 | {32, D<&FSP_SRV::ExtendSaveDataFileSystem>, "ExtendSaveDataFileSystem"}, |
| 75 | {33, nullptr, "DeleteCacheStorage"}, | 75 | {33, nullptr, "DeleteCacheStorage"}, |
| 76 | {34, D<&FSP_SRV::GetCacheStorageSize>, "GetCacheStorageSize"}, | 76 | {34, D<&FSP_SRV::GetCacheStorageSize>, "GetCacheStorageSize"}, |
| 77 | {35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, | 77 | {35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, |
| @@ -79,9 +79,9 @@ FSP_SRV::FSP_SRV(Core::System& system_) | |||
| 79 | {51, D<&FSP_SRV::OpenSaveDataFileSystem>, "OpenSaveDataFileSystem"}, | 79 | {51, D<&FSP_SRV::OpenSaveDataFileSystem>, "OpenSaveDataFileSystem"}, |
| 80 | {52, D<&FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId>, "OpenSaveDataFileSystemBySystemSaveDataId"}, | 80 | {52, D<&FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId>, "OpenSaveDataFileSystemBySystemSaveDataId"}, |
| 81 | {53, D<&FSP_SRV::OpenReadOnlySaveDataFileSystem>, "OpenReadOnlySaveDataFileSystem"}, | 81 | {53, D<&FSP_SRV::OpenReadOnlySaveDataFileSystem>, "OpenReadOnlySaveDataFileSystem"}, |
| 82 | {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, | 82 | {57, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataSpaceId>, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, |
| 83 | {58, nullptr, "ReadSaveDataFileSystemExtraData"}, | 83 | {58, D<&FSP_SRV::ReadSaveDataFileSystemExtraData>, "ReadSaveDataFileSystemExtraData"}, |
| 84 | {59, nullptr, "WriteSaveDataFileSystemExtraData"}, | 84 | {59, D<&FSP_SRV::WriteSaveDataFileSystemExtraData>, "WriteSaveDataFileSystemExtraData"}, |
| 85 | {60, nullptr, "OpenSaveDataInfoReader"}, | 85 | {60, nullptr, "OpenSaveDataInfoReader"}, |
| 86 | {61, D<&FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId>, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, | 86 | {61, D<&FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId>, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, |
| 87 | {62, D<&FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage>, "OpenSaveDataInfoReaderOnlyCacheStorage"}, | 87 | {62, D<&FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage>, "OpenSaveDataInfoReaderOnlyCacheStorage"}, |
| @@ -90,8 +90,8 @@ FSP_SRV::FSP_SRV(Core::System& system_) | |||
| 90 | {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, | 90 | {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, |
| 91 | {67, D<&FSP_SRV::FindSaveDataWithFilter>, "FindSaveDataWithFilter"}, | 91 | {67, D<&FSP_SRV::FindSaveDataWithFilter>, "FindSaveDataWithFilter"}, |
| 92 | {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"}, | 92 | {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"}, |
| 93 | {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, | 93 | {69, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataAttribute>, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, |
| 94 | {70, D<&FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute>, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"}, | 94 | {70, D<&FSP_SRV::WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute>, "WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, |
| 95 | {71, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute>, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, | 95 | {71, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute>, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, |
| 96 | {80, nullptr, "OpenSaveDataMetaFile"}, | 96 | {80, nullptr, "OpenSaveDataMetaFile"}, |
| 97 | {81, nullptr, "OpenSaveDataTransferManager"}, | 97 | {81, nullptr, "OpenSaveDataTransferManager"}, |
| @@ -317,9 +317,23 @@ Result FSP_SRV::FindSaveDataWithFilter(Out<s64> out_count, | |||
| 317 | R_THROW(FileSys::ResultTargetNotFound); | 317 | R_THROW(FileSys::ResultTargetNotFound); |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | Result FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute() { | 320 | Result FSP_SRV::WriteSaveDataFileSystemExtraData(InBuffer<BufferAttr_HipcMapAlias> buffer, |
| 321 | LOG_WARNING(Service_FS, "(STUBBED) called."); | 321 | FileSys::SaveDataSpaceId space_id, |
| 322 | u64 save_data_id) { | ||
| 323 | LOG_WARNING(Service_FS, "(STUBBED) called, space_id={}, save_data_id={:016X}", space_id, | ||
| 324 | save_data_id); | ||
| 325 | R_SUCCEED(); | ||
| 326 | } | ||
| 322 | 327 | ||
| 328 | Result FSP_SRV::WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( | ||
| 329 | InBuffer<BufferAttr_HipcMapAlias> buffer, InBuffer<BufferAttr_HipcMapAlias> mask_buffer, | ||
| 330 | FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute) { | ||
| 331 | LOG_WARNING(Service_FS, | ||
| 332 | "(STUBBED) called, space_id={}, attribute.program_id={:016X}\n" | ||
| 333 | "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" | ||
| 334 | "attribute.type={}, attribute.rank={}, attribute.index={}", | ||
| 335 | space_id, attribute.program_id, attribute.user_id[1], attribute.user_id[0], | ||
| 336 | attribute.system_save_data_id, attribute.type, attribute.rank, attribute.index); | ||
| 323 | R_SUCCEED(); | 337 | R_SUCCEED(); |
| 324 | } | 338 | } |
| 325 | 339 | ||
| @@ -341,6 +355,38 @@ Result FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( | |||
| 341 | R_SUCCEED(); | 355 | R_SUCCEED(); |
| 342 | } | 356 | } |
| 343 | 357 | ||
| 358 | Result FSP_SRV::ReadSaveDataFileSystemExtraData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, | ||
| 359 | u64 save_data_id) { | ||
| 360 | // Stub, backend needs an impl to read/write the SaveDataExtraData | ||
| 361 | LOG_WARNING(Service_FS, "(STUBBED) called, save_data_id={:016X}", save_data_id); | ||
| 362 | std::memset(out_buffer.data(), 0, out_buffer.size()); | ||
| 363 | R_SUCCEED(); | ||
| 364 | } | ||
| 365 | |||
| 366 | Result FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataAttribute( | ||
| 367 | OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, | ||
| 368 | FileSys::SaveDataAttribute attribute) { | ||
| 369 | // Stub, backend needs an impl to read/write the SaveDataExtraData | ||
| 370 | LOG_WARNING(Service_FS, | ||
| 371 | "(STUBBED) called, space_id={}, attribute.program_id={:016X}\n" | ||
| 372 | "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" | ||
| 373 | "attribute.type={}, attribute.rank={}, attribute.index={}", | ||
| 374 | space_id, attribute.program_id, attribute.user_id[1], attribute.user_id[0], | ||
| 375 | attribute.system_save_data_id, attribute.type, attribute.rank, attribute.index); | ||
| 376 | std::memset(out_buffer.data(), 0, out_buffer.size()); | ||
| 377 | R_SUCCEED(); | ||
| 378 | } | ||
| 379 | |||
| 380 | Result FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataSpaceId( | ||
| 381 | OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, | ||
| 382 | u64 save_data_id) { | ||
| 383 | // Stub, backend needs an impl to read/write the SaveDataExtraData | ||
| 384 | LOG_WARNING(Service_FS, "(STUBBED) called, space_id={}, save_data_id={:016X}", space_id, | ||
| 385 | save_data_id); | ||
| 386 | std::memset(out_buffer.data(), 0, out_buffer.size()); | ||
| 387 | R_SUCCEED(); | ||
| 388 | } | ||
| 389 | |||
| 344 | Result FSP_SRV::OpenSaveDataTransferProhibiter( | 390 | Result FSP_SRV::OpenSaveDataTransferProhibiter( |
| 345 | OutInterface<ISaveDataTransferProhibiter> out_prohibiter, u64 id) { | 391 | OutInterface<ISaveDataTransferProhibiter> out_prohibiter, u64 id) { |
| 346 | LOG_WARNING(Service_FS, "(STUBBED) called, id={:016X}", id); | 392 | LOG_WARNING(Service_FS, "(STUBBED) called, id={:016X}", id); |
| @@ -476,6 +522,16 @@ Result FSP_SRV::FlushAccessLogOnSdCard() { | |||
| 476 | R_SUCCEED(); | 522 | R_SUCCEED(); |
| 477 | } | 523 | } |
| 478 | 524 | ||
| 525 | Result FSP_SRV::ExtendSaveDataFileSystem(FileSys::SaveDataSpaceId space_id, u64 save_data_id, | ||
| 526 | s64 available_size, s64 journal_size) { | ||
| 527 | // We don't have an index of save data ids, so we can't implement this. | ||
| 528 | LOG_WARNING(Service_FS, | ||
| 529 | "(STUBBED) called, space_id={}, save_data_id={:016X}, available_size={:#x}, " | ||
| 530 | "journal_size={:#x}", | ||
| 531 | space_id, save_data_id, available_size, journal_size); | ||
| 532 | R_SUCCEED(); | ||
| 533 | } | ||
| 534 | |||
| 479 | Result FSP_SRV::GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size) { | 535 | Result FSP_SRV::GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size) { |
| 480 | LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index); | 536 | LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index); |
| 481 | 537 | ||
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h index 83d9cb51c..b565cace0 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h | |||
| @@ -70,7 +70,19 @@ private: | |||
| 70 | Result FindSaveDataWithFilter(Out<s64> out_count, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, | 70 | Result FindSaveDataWithFilter(Out<s64> out_count, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, |
| 71 | FileSys::SaveDataSpaceId space_id, | 71 | FileSys::SaveDataSpaceId space_id, |
| 72 | FileSys::SaveDataFilter filter); | 72 | FileSys::SaveDataFilter filter); |
| 73 | Result WriteSaveDataFileSystemExtraDataBySaveDataAttribute(); | 73 | Result WriteSaveDataFileSystemExtraData(InBuffer<BufferAttr_HipcMapAlias> buffer, |
| 74 | FileSys::SaveDataSpaceId space_id, u64 save_data_id); | ||
| 75 | Result WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( | ||
| 76 | InBuffer<BufferAttr_HipcMapAlias> buffer, InBuffer<BufferAttr_HipcMapAlias> mask_buffer, | ||
| 77 | FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute); | ||
| 78 | Result ReadSaveDataFileSystemExtraData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, | ||
| 79 | u64 save_data_id); | ||
| 80 | Result ReadSaveDataFileSystemExtraDataBySaveDataAttribute( | ||
| 81 | OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, | ||
| 82 | FileSys::SaveDataAttribute attribute); | ||
| 83 | Result ReadSaveDataFileSystemExtraDataBySaveDataSpaceId( | ||
| 84 | OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, | ||
| 85 | u64 save_data_id); | ||
| 74 | Result ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( | 86 | Result ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( |
| 75 | FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute, | 87 | FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute, |
| 76 | InBuffer<BufferAttr_HipcMapAlias> mask_buffer, | 88 | InBuffer<BufferAttr_HipcMapAlias> mask_buffer, |
| @@ -91,6 +103,8 @@ private: | |||
| 91 | Result GetProgramIndexForAccessLog(Out<AccessLogVersion> out_access_log_version, | 103 | Result GetProgramIndexForAccessLog(Out<AccessLogVersion> out_access_log_version, |
| 92 | Out<u32> out_access_log_program_index); | 104 | Out<u32> out_access_log_program_index); |
| 93 | Result OpenMultiCommitManager(OutInterface<IMultiCommitManager> out_interface); | 105 | Result OpenMultiCommitManager(OutInterface<IMultiCommitManager> out_interface); |
| 106 | Result ExtendSaveDataFileSystem(FileSys::SaveDataSpaceId space_id, u64 save_data_id, | ||
| 107 | s64 available_size, s64 journal_size); | ||
| 94 | Result GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size); | 108 | Result GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size); |
| 95 | 109 | ||
| 96 | FileSystemController& fsc; | 110 | FileSystemController& fsc; |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index aeb849efa..38e62761b 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -42,13 +42,13 @@ public: | |||
| 42 | {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, | 42 | {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, |
| 43 | {10702, nullptr, "AddPlayHistory"}, | 43 | {10702, nullptr, "AddPlayHistory"}, |
| 44 | {11000, nullptr, "GetProfileImageUrl"}, | 44 | {11000, nullptr, "GetProfileImageUrl"}, |
| 45 | {20100, nullptr, "GetFriendCount"}, | 45 | {20100, &IFriendService::GetFriendCount, "GetFriendCount"}, |
| 46 | {20101, nullptr, "GetNewlyFriendCount"}, | 46 | {20101, &IFriendService::GetNewlyFriendCount, "GetNewlyFriendCount"}, |
| 47 | {20102, nullptr, "GetFriendDetailedInfo"}, | 47 | {20102, nullptr, "GetFriendDetailedInfo"}, |
| 48 | {20103, nullptr, "SyncFriendList"}, | 48 | {20103, nullptr, "SyncFriendList"}, |
| 49 | {20104, nullptr, "RequestSyncFriendList"}, | 49 | {20104, nullptr, "RequestSyncFriendList"}, |
| 50 | {20110, nullptr, "LoadFriendSetting"}, | 50 | {20110, nullptr, "LoadFriendSetting"}, |
| 51 | {20200, nullptr, "GetReceivedFriendRequestCount"}, | 51 | {20200, &IFriendService::GetReceivedFriendRequestCount, "GetReceivedFriendRequestCount"}, |
| 52 | {20201, nullptr, "GetFriendRequestList"}, | 52 | {20201, nullptr, "GetFriendRequestList"}, |
| 53 | {20300, nullptr, "GetFriendCandidateList"}, | 53 | {20300, nullptr, "GetFriendCandidateList"}, |
| 54 | {20301, nullptr, "GetNintendoNetworkIdInfo"}, | 54 | {20301, nullptr, "GetNintendoNetworkIdInfo"}, |
| @@ -61,14 +61,14 @@ public: | |||
| 61 | {20501, nullptr, "GetRelationship"}, | 61 | {20501, nullptr, "GetRelationship"}, |
| 62 | {20600, nullptr, "GetUserPresenceView"}, | 62 | {20600, nullptr, "GetUserPresenceView"}, |
| 63 | {20700, nullptr, "GetPlayHistoryList"}, | 63 | {20700, nullptr, "GetPlayHistoryList"}, |
| 64 | {20701, nullptr, "GetPlayHistoryStatistics"}, | 64 | {20701, &IFriendService::GetPlayHistoryStatistics, "GetPlayHistoryStatistics"}, |
| 65 | {20800, nullptr, "LoadUserSetting"}, | 65 | {20800, nullptr, "LoadUserSetting"}, |
| 66 | {20801, nullptr, "SyncUserSetting"}, | 66 | {20801, nullptr, "SyncUserSetting"}, |
| 67 | {20900, nullptr, "RequestListSummaryOverlayNotification"}, | 67 | {20900, nullptr, "RequestListSummaryOverlayNotification"}, |
| 68 | {21000, nullptr, "GetExternalApplicationCatalog"}, | 68 | {21000, nullptr, "GetExternalApplicationCatalog"}, |
| 69 | {22000, nullptr, "GetReceivedFriendInvitationList"}, | 69 | {22000, nullptr, "GetReceivedFriendInvitationList"}, |
| 70 | {22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"}, | 70 | {22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"}, |
| 71 | {22010, nullptr, "GetReceivedFriendInvitationCountCache"}, | 71 | {22010, &IFriendService::GetReceivedFriendInvitationCountCache, "GetReceivedFriendInvitationCountCache"}, |
| 72 | {30100, nullptr, "DropFriendNewlyFlags"}, | 72 | {30100, nullptr, "DropFriendNewlyFlags"}, |
| 73 | {30101, nullptr, "DeleteFriend"}, | 73 | {30101, nullptr, "DeleteFriend"}, |
| 74 | {30110, nullptr, "DropFriendNewlyFlag"}, | 74 | {30110, nullptr, "DropFriendNewlyFlag"}, |
| @@ -144,6 +144,33 @@ private: | |||
| 144 | rb.PushCopyObjects(completion_event->GetReadableEvent()); | 144 | rb.PushCopyObjects(completion_event->GetReadableEvent()); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | void GetFriendList(HLERequestContext& ctx) { | ||
| 148 | IPC::RequestParser rp{ctx}; | ||
| 149 | const auto friend_offset = rp.Pop<u32>(); | ||
| 150 | const auto uuid = rp.PopRaw<Common::UUID>(); | ||
| 151 | [[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>(); | ||
| 152 | const auto pid = rp.Pop<u64>(); | ||
| 153 | LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid=0x{}, pid={}", friend_offset, | ||
| 154 | uuid.RawString(), pid); | ||
| 155 | |||
| 156 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 157 | rb.Push(ResultSuccess); | ||
| 158 | |||
| 159 | rb.Push<u32>(0); // Friend count | ||
| 160 | // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId" | ||
| 161 | } | ||
| 162 | |||
| 163 | void CheckFriendListAvailability(HLERequestContext& ctx) { | ||
| 164 | IPC::RequestParser rp{ctx}; | ||
| 165 | const auto uuid{rp.PopRaw<Common::UUID>()}; | ||
| 166 | |||
| 167 | LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||
| 168 | |||
| 169 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 170 | rb.Push(ResultSuccess); | ||
| 171 | rb.Push(true); | ||
| 172 | } | ||
| 173 | |||
| 147 | void GetBlockedUserListIds(HLERequestContext& ctx) { | 174 | void GetBlockedUserListIds(HLERequestContext& ctx) { |
| 148 | // This is safe to stub, as there should be no adverse consequences from reporting no | 175 | // This is safe to stub, as there should be no adverse consequences from reporting no |
| 149 | // blocked users. | 176 | // blocked users. |
| @@ -153,6 +180,17 @@ private: | |||
| 153 | rb.Push<u32>(0); // Indicates there are no blocked users | 180 | rb.Push<u32>(0); // Indicates there are no blocked users |
| 154 | } | 181 | } |
| 155 | 182 | ||
| 183 | void CheckBlockedUserListAvailability(HLERequestContext& ctx) { | ||
| 184 | IPC::RequestParser rp{ctx}; | ||
| 185 | const auto uuid{rp.PopRaw<Common::UUID>()}; | ||
| 186 | |||
| 187 | LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||
| 188 | |||
| 189 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 190 | rb.Push(ResultSuccess); | ||
| 191 | rb.Push(true); | ||
| 192 | } | ||
| 193 | |||
| 156 | void DeclareCloseOnlinePlaySession(HLERequestContext& ctx) { | 194 | void DeclareCloseOnlinePlaySession(HLERequestContext& ctx) { |
| 157 | // Stub used by Splatoon 2 | 195 | // Stub used by Splatoon 2 |
| 158 | LOG_WARNING(Service_Friend, "(STUBBED) called"); | 196 | LOG_WARNING(Service_Friend, "(STUBBED) called"); |
| @@ -179,42 +217,43 @@ private: | |||
| 179 | rb.Push(ResultSuccess); | 217 | rb.Push(ResultSuccess); |
| 180 | } | 218 | } |
| 181 | 219 | ||
| 182 | void GetFriendList(HLERequestContext& ctx) { | 220 | void GetFriendCount(HLERequestContext& ctx) { |
| 183 | IPC::RequestParser rp{ctx}; | 221 | LOG_DEBUG(Service_Friend, "(STUBBED) called"); |
| 184 | const auto friend_offset = rp.Pop<u32>(); | ||
| 185 | const auto uuid = rp.PopRaw<Common::UUID>(); | ||
| 186 | [[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>(); | ||
| 187 | const auto pid = rp.Pop<u64>(); | ||
| 188 | LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid=0x{}, pid={}", friend_offset, | ||
| 189 | uuid.RawString(), pid); | ||
| 190 | 222 | ||
| 191 | IPC::ResponseBuilder rb{ctx, 3}; | 223 | IPC::ResponseBuilder rb{ctx, 3}; |
| 192 | rb.Push(ResultSuccess); | 224 | rb.Push(ResultSuccess); |
| 193 | 225 | rb.Push(0); | |
| 194 | rb.Push<u32>(0); // Friend count | ||
| 195 | // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId" | ||
| 196 | } | 226 | } |
| 197 | 227 | ||
| 198 | void CheckFriendListAvailability(HLERequestContext& ctx) { | 228 | void GetNewlyFriendCount(HLERequestContext& ctx) { |
| 199 | IPC::RequestParser rp{ctx}; | 229 | LOG_DEBUG(Service_Friend, "(STUBBED) called"); |
| 200 | const auto uuid{rp.PopRaw<Common::UUID>()}; | ||
| 201 | 230 | ||
| 202 | LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | 231 | IPC::ResponseBuilder rb{ctx, 3}; |
| 232 | rb.Push(ResultSuccess); | ||
| 233 | rb.Push(0); | ||
| 234 | } | ||
| 235 | |||
| 236 | void GetReceivedFriendRequestCount(HLERequestContext& ctx) { | ||
| 237 | LOG_DEBUG(Service_Friend, "(STUBBED) called"); | ||
| 203 | 238 | ||
| 204 | IPC::ResponseBuilder rb{ctx, 3}; | 239 | IPC::ResponseBuilder rb{ctx, 3}; |
| 205 | rb.Push(ResultSuccess); | 240 | rb.Push(ResultSuccess); |
| 206 | rb.Push(true); | 241 | rb.Push(0); |
| 207 | } | 242 | } |
| 208 | 243 | ||
| 209 | void CheckBlockedUserListAvailability(HLERequestContext& ctx) { | 244 | void GetPlayHistoryStatistics(HLERequestContext& ctx) { |
| 210 | IPC::RequestParser rp{ctx}; | 245 | LOG_ERROR(Service_Friend, "(STUBBED) called, check in out"); |
| 211 | const auto uuid{rp.PopRaw<Common::UUID>()}; | ||
| 212 | 246 | ||
| 213 | LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | 247 | IPC::ResponseBuilder rb{ctx, 2}; |
| 248 | rb.Push(ResultSuccess); | ||
| 249 | } | ||
| 250 | |||
| 251 | void GetReceivedFriendInvitationCountCache(HLERequestContext& ctx) { | ||
| 252 | LOG_DEBUG(Service_Friend, "(STUBBED) called, check in out"); | ||
| 214 | 253 | ||
| 215 | IPC::ResponseBuilder rb{ctx, 3}; | 254 | IPC::ResponseBuilder rb{ctx, 3}; |
| 216 | rb.Push(ResultSuccess); | 255 | rb.Push(ResultSuccess); |
| 217 | rb.Push(true); | 256 | rb.Push(0); |
| 218 | } | 257 | } |
| 219 | 258 | ||
| 220 | KernelHelpers::ServiceContext service_context; | 259 | KernelHelpers::ServiceContext service_context; |
diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index 059ac3fc9..cb88486dd 100644 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp | |||
| @@ -51,16 +51,17 @@ s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) { | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) { | 53 | s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) { |
| 54 | s32 year{2000}; | ||
| 55 | set_sys->GetSettingsItemValueImpl(year, "time", "standard_user_clock_initial_year"); | ||
| 56 | |||
| 54 | Service::PSC::Time::CalendarTime calendar{ | 57 | Service::PSC::Time::CalendarTime calendar{ |
| 55 | .year = 2000, | 58 | .year = static_cast<s16>(year), |
| 56 | .month = 1, | 59 | .month = 1, |
| 57 | .day = 1, | 60 | .day = 1, |
| 58 | .hour = 0, | 61 | .hour = 0, |
| 59 | .minute = 0, | 62 | .minute = 0, |
| 60 | .second = 0, | 63 | .second = 0, |
| 61 | }; | 64 | }; |
| 62 | set_sys->GetSettingsItemValueImpl<s16>(calendar.year, "time", | ||
| 63 | "standard_user_clock_initial_year"); | ||
| 64 | return CalendarTimeToEpoch(calendar); | 65 | return CalendarTimeToEpoch(calendar); |
| 65 | } | 66 | } |
| 66 | 67 | ||
diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp index b28569b68..b6bbd7965 100644 --- a/src/core/hle/service/glue/time/worker.cpp +++ b/src/core/hle/service/glue/time/worker.cpp | |||
| @@ -26,12 +26,9 @@ Service::PSC::Time::SystemClockContext g_report_ephemeral_clock_context{}; | |||
| 26 | template <typename T> | 26 | template <typename T> |
| 27 | T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys, | 27 | T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys, |
| 28 | const char* category, const char* name) { | 28 | const char* category, const char* name) { |
| 29 | std::vector<u8> interval_buf; | ||
| 30 | auto res = set_sys->GetSettingsItemValueImpl(interval_buf, category, name); | ||
| 31 | ASSERT(res == ResultSuccess); | ||
| 32 | |||
| 33 | T v{}; | 29 | T v{}; |
| 34 | std::memcpy(&v, interval_buf.data(), sizeof(T)); | 30 | auto res = set_sys->GetSettingsItemValueImpl(v, category, name); |
| 31 | ASSERT(res == ResultSuccess); | ||
| 35 | return v; | 32 | return v; |
| 36 | } | 33 | } |
| 37 | 34 | ||
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index 7126a1dcd..b0cd63d72 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp | |||
| @@ -201,7 +201,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | |||
| 201 | {1269, nullptr, "DeleteButtonConfigStorageLeft"}, | 201 | {1269, nullptr, "DeleteButtonConfigStorageLeft"}, |
| 202 | {1270, nullptr, "DeleteButtonConfigStorageRight"}, | 202 | {1270, nullptr, "DeleteButtonConfigStorageRight"}, |
| 203 | {1271, &IHidSystemServer::IsUsingCustomButtonConfig, "IsUsingCustomButtonConfig"}, | 203 | {1271, &IHidSystemServer::IsUsingCustomButtonConfig, "IsUsingCustomButtonConfig"}, |
| 204 | {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, | 204 | {1272, &IHidSystemServer::IsAnyCustomButtonConfigEnabled, "IsAnyCustomButtonConfigEnabled"}, |
| 205 | {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, | 205 | {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, |
| 206 | {1274, nullptr, "SetDefaultButtonConfig"}, | 206 | {1274, nullptr, "SetDefaultButtonConfig"}, |
| 207 | {1275, nullptr, "SetAllDefaultButtonConfig"}, | 207 | {1275, nullptr, "SetAllDefaultButtonConfig"}, |
| @@ -926,6 +926,16 @@ void IHidSystemServer::IsUsingCustomButtonConfig(HLERequestContext& ctx) { | |||
| 926 | rb.Push(is_enabled); | 926 | rb.Push(is_enabled); |
| 927 | } | 927 | } |
| 928 | 928 | ||
| 929 | void IHidSystemServer::IsAnyCustomButtonConfigEnabled(HLERequestContext& ctx) { | ||
| 930 | const bool is_enabled = false; | ||
| 931 | |||
| 932 | LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled); | ||
| 933 | |||
| 934 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 935 | rb.Push(ResultSuccess); | ||
| 936 | rb.Push(is_enabled); | ||
| 937 | } | ||
| 938 | |||
| 929 | std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() { | 939 | std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() { |
| 930 | resource_manager->Initialize(); | 940 | resource_manager->Initialize(); |
| 931 | return resource_manager; | 941 | return resource_manager; |
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h index 738313e08..1a4f244d7 100644 --- a/src/core/hle/service/hid/hid_system_server.h +++ b/src/core/hle/service/hid/hid_system_server.h | |||
| @@ -77,6 +77,7 @@ private: | |||
| 77 | void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); | 77 | void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); |
| 78 | void SetForceHandheldStyleVibration(HLERequestContext& ctx); | 78 | void SetForceHandheldStyleVibration(HLERequestContext& ctx); |
| 79 | void IsUsingCustomButtonConfig(HLERequestContext& ctx); | 79 | void IsUsingCustomButtonConfig(HLERequestContext& ctx); |
| 80 | void IsAnyCustomButtonConfigEnabled(HLERequestContext& ctx); | ||
| 80 | 81 | ||
| 81 | std::shared_ptr<ResourceManager> GetResourceManager(); | 82 | std::shared_ptr<ResourceManager> GetResourceManager(); |
| 82 | 83 | ||
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp index 98a79365d..c14b24142 100644 --- a/src/core/hle/service/lbl/lbl.cpp +++ b/src/core/hle/service/lbl/lbl.cpp | |||
| @@ -18,8 +18,8 @@ public: | |||
| 18 | explicit LBL(Core::System& system_) : ServiceFramework{system_, "lbl"} { | 18 | explicit LBL(Core::System& system_) : ServiceFramework{system_, "lbl"} { |
| 19 | // clang-format off | 19 | // clang-format off |
| 20 | static const FunctionInfo functions[] = { | 20 | static const FunctionInfo functions[] = { |
| 21 | {0, nullptr, "SaveCurrentSetting"}, | 21 | {0, &LBL::SaveCurrentSetting, "SaveCurrentSetting"}, |
| 22 | {1, nullptr, "LoadCurrentSetting"}, | 22 | {1, &LBL::LoadCurrentSetting, "LoadCurrentSetting"}, |
| 23 | {2, &LBL::SetCurrentBrightnessSetting, "SetCurrentBrightnessSetting"}, | 23 | {2, &LBL::SetCurrentBrightnessSetting, "SetCurrentBrightnessSetting"}, |
| 24 | {3, &LBL::GetCurrentBrightnessSetting, "GetCurrentBrightnessSetting"}, | 24 | {3, &LBL::GetCurrentBrightnessSetting, "GetCurrentBrightnessSetting"}, |
| 25 | {4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"}, | 25 | {4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"}, |
| @@ -47,7 +47,7 @@ public: | |||
| 47 | {26, &LBL::EnableVrMode, "EnableVrMode"}, | 47 | {26, &LBL::EnableVrMode, "EnableVrMode"}, |
| 48 | {27, &LBL::DisableVrMode, "DisableVrMode"}, | 48 | {27, &LBL::DisableVrMode, "DisableVrMode"}, |
| 49 | {28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"}, | 49 | {28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"}, |
| 50 | {29, nullptr, "IsAutoBrightnessControlSupported"}, | 50 | {29, &LBL::IsAutoBrightnessControlSupported, "IsAutoBrightnessControlSupported"}, |
| 51 | }; | 51 | }; |
| 52 | // clang-format on | 52 | // clang-format on |
| 53 | 53 | ||
| @@ -60,6 +60,20 @@ private: | |||
| 60 | On = 1, | 60 | On = 1, |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | void SaveCurrentSetting(HLERequestContext& ctx) { | ||
| 64 | LOG_WARNING(Service_LBL, "(STUBBED) called"); | ||
| 65 | |||
| 66 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 67 | rb.Push(ResultSuccess); | ||
| 68 | } | ||
| 69 | |||
| 70 | void LoadCurrentSetting(HLERequestContext& ctx) { | ||
| 71 | LOG_WARNING(Service_LBL, "(STUBBED) called"); | ||
| 72 | |||
| 73 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 74 | rb.Push(ResultSuccess); | ||
| 75 | } | ||
| 76 | |||
| 63 | void SetCurrentBrightnessSetting(HLERequestContext& ctx) { | 77 | void SetCurrentBrightnessSetting(HLERequestContext& ctx) { |
| 64 | IPC::RequestParser rp{ctx}; | 78 | IPC::RequestParser rp{ctx}; |
| 65 | auto brightness = rp.Pop<float>(); | 79 | auto brightness = rp.Pop<float>(); |
| @@ -310,6 +324,14 @@ private: | |||
| 310 | rb.Push(vr_mode_enabled); | 324 | rb.Push(vr_mode_enabled); |
| 311 | } | 325 | } |
| 312 | 326 | ||
| 327 | void IsAutoBrightnessControlSupported(HLERequestContext& ctx) { | ||
| 328 | LOG_DEBUG(Service_LBL, "called"); | ||
| 329 | |||
| 330 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 331 | rb.Push(ResultSuccess); | ||
| 332 | rb.Push<u8>(auto_brightness_supported); | ||
| 333 | } | ||
| 334 | |||
| 313 | bool vr_mode_enabled = false; | 335 | bool vr_mode_enabled = false; |
| 314 | float current_brightness = 1.0f; | 336 | float current_brightness = 1.0f; |
| 315 | float ambient_light_value = 0.0f; | 337 | float ambient_light_value = 0.0f; |
| @@ -317,7 +339,8 @@ private: | |||
| 317 | bool dimming = true; | 339 | bool dimming = true; |
| 318 | bool backlight_enabled = true; | 340 | bool backlight_enabled = true; |
| 319 | bool update_instantly = false; | 341 | bool update_instantly = false; |
| 320 | bool auto_brightness = false; // TODO(ogniK): Move to system settings | 342 | bool auto_brightness = false; |
| 343 | bool auto_brightness_supported = true; // TODO(ogniK): Move to system settings | ||
| 321 | }; | 344 | }; |
| 322 | 345 | ||
| 323 | void LoopProcess(Core::System& system) { | 346 | void LoopProcess(Core::System& system) { |
diff --git a/src/core/hle/service/ldn/monitor_service.cpp b/src/core/hle/service/ldn/monitor_service.cpp index 3471f69da..ea6ac4d5d 100644 --- a/src/core/hle/service/ldn/monitor_service.cpp +++ b/src/core/hle/service/ldn/monitor_service.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/cmif_serialization.h" | 4 | #include "core/hle/service/cmif_serialization.h" |
| 5 | #include "core/hle/service/ldn/ldn_results.h" | ||
| 5 | #include "core/hle/service/ldn/monitor_service.h" | 6 | #include "core/hle/service/ldn/monitor_service.h" |
| 6 | 7 | ||
| 7 | namespace Service::LDN { | 8 | namespace Service::LDN { |
| @@ -17,7 +18,7 @@ IMonitorService::IMonitorService(Core::System& system_) | |||
| 17 | {4, nullptr, "GetSecurityParameterForMonitor"}, | 18 | {4, nullptr, "GetSecurityParameterForMonitor"}, |
| 18 | {5, nullptr, "GetNetworkConfigForMonitor"}, | 19 | {5, nullptr, "GetNetworkConfigForMonitor"}, |
| 19 | {100, C<&IMonitorService::InitializeMonitor>, "InitializeMonitor"}, | 20 | {100, C<&IMonitorService::InitializeMonitor>, "InitializeMonitor"}, |
| 20 | {101, nullptr, "FinalizeMonitor"}, | 21 | {101, C<&IMonitorService::FinalizeMonitor>, "FinalizeMonitor"}, |
| 21 | }; | 22 | }; |
| 22 | // clang-format on | 23 | // clang-format on |
| 23 | 24 | ||
| @@ -27,16 +28,18 @@ IMonitorService::IMonitorService(Core::System& system_) | |||
| 27 | IMonitorService::~IMonitorService() = default; | 28 | IMonitorService::~IMonitorService() = default; |
| 28 | 29 | ||
| 29 | Result IMonitorService::GetStateForMonitor(Out<State> out_state) { | 30 | Result IMonitorService::GetStateForMonitor(Out<State> out_state) { |
| 30 | LOG_INFO(Service_LDN, "called"); | 31 | LOG_WARNING(Service_LDN, "(STUBBED) called"); |
| 31 | 32 | *out_state = State::None; | |
| 32 | *out_state = state; | ||
| 33 | R_SUCCEED(); | 33 | R_SUCCEED(); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | Result IMonitorService::InitializeMonitor() { | 36 | Result IMonitorService::InitializeMonitor() { |
| 37 | LOG_INFO(Service_LDN, "called"); | 37 | LOG_INFO(Service_LDN, "called"); |
| 38 | R_SUCCEED(); | ||
| 39 | } | ||
| 38 | 40 | ||
| 39 | state = State::Initialized; | 41 | Result IMonitorService::FinalizeMonitor() { |
| 42 | LOG_INFO(Service_LDN, "called"); | ||
| 40 | R_SUCCEED(); | 43 | R_SUCCEED(); |
| 41 | } | 44 | } |
| 42 | 45 | ||
diff --git a/src/core/hle/service/ldn/monitor_service.h b/src/core/hle/service/ldn/monitor_service.h index 61aacef30..e663145b4 100644 --- a/src/core/hle/service/ldn/monitor_service.h +++ b/src/core/hle/service/ldn/monitor_service.h | |||
| @@ -21,6 +21,7 @@ public: | |||
| 21 | private: | 21 | private: |
| 22 | Result GetStateForMonitor(Out<State> out_state); | 22 | Result GetStateForMonitor(Out<State> out_state); |
| 23 | Result InitializeMonitor(); | 23 | Result InitializeMonitor(); |
| 24 | Result FinalizeMonitor(); | ||
| 24 | 25 | ||
| 25 | State state{State::None}; | 26 | State state{State::None}; |
| 26 | }; | 27 | }; |
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index 94a8243b5..2dd3e9f89 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/hle/service/nfc/nfc_result.h" | 13 | #include "core/hle/service/nfc/nfc_result.h" |
| 14 | #include "core/hle/service/psc/time/steady_clock.h" | 14 | #include "core/hle/service/psc/time/steady_clock.h" |
| 15 | #include "core/hle/service/service.h" | 15 | #include "core/hle/service/service.h" |
| 16 | #include "core/hle/service/set/system_settings_server.h" | ||
| 16 | #include "core/hle/service/sm/sm.h" | 17 | #include "core/hle/service/sm/sm.h" |
| 17 | #include "hid_core/hid_types.h" | 18 | #include "hid_core/hid_types.h" |
| 18 | #include "hid_core/hid_util.h" | 19 | #include "hid_core/hid_util.h" |
| @@ -32,6 +33,9 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex | |||
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | is_initialized = false; | 35 | is_initialized = false; |
| 36 | |||
| 37 | m_set_sys = | ||
| 38 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||
| 35 | } | 39 | } |
| 36 | 40 | ||
| 37 | DeviceManager ::~DeviceManager() { | 41 | DeviceManager ::~DeviceManager() { |
| @@ -774,8 +778,8 @@ Result DeviceManager::CheckDeviceState(std::shared_ptr<NfcDevice> device) const | |||
| 774 | } | 778 | } |
| 775 | 779 | ||
| 776 | Result DeviceManager::IsNfcEnabled() const { | 780 | Result DeviceManager::IsNfcEnabled() const { |
| 777 | // TODO: This calls nn::settings::detail::GetNfcEnableFlag | 781 | bool is_enabled{}; |
| 778 | const bool is_enabled = true; | 782 | R_TRY(m_set_sys->GetNfcEnableFlag(&is_enabled)); |
| 779 | if (!is_enabled) { | 783 | if (!is_enabled) { |
| 780 | return ResultNfcDisabled; | 784 | return ResultNfcDisabled; |
| 781 | } | 785 | } |
diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h index c56a2fbda..6c0e6b255 100644 --- a/src/core/hle/service/nfc/common/device_manager.h +++ b/src/core/hle/service/nfc/common/device_manager.h | |||
| @@ -15,6 +15,10 @@ | |||
| 15 | #include "core/hle/service/service.h" | 15 | #include "core/hle/service/service.h" |
| 16 | #include "hid_core/hid_types.h" | 16 | #include "hid_core/hid_types.h" |
| 17 | 17 | ||
| 18 | namespace Service::Set { | ||
| 19 | class ISystemSettingsServer; | ||
| 20 | } | ||
| 21 | |||
| 18 | namespace Service::NFC { | 22 | namespace Service::NFC { |
| 19 | class NfcDevice; | 23 | class NfcDevice; |
| 20 | 24 | ||
| @@ -98,6 +102,7 @@ private: | |||
| 98 | Core::System& system; | 102 | Core::System& system; |
| 99 | KernelHelpers::ServiceContext service_context; | 103 | KernelHelpers::ServiceContext service_context; |
| 100 | Kernel::KEvent* availability_change_event; | 104 | Kernel::KEvent* availability_change_event; |
| 105 | std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||
| 101 | }; | 106 | }; |
| 102 | 107 | ||
| 103 | } // namespace Service::NFC | 108 | } // namespace Service::NFC |
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 30ae989b9..9d4808dbe 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp | |||
| @@ -57,7 +57,7 @@ public: | |||
| 57 | {1, &NfcInterface::Finalize, "FinalizeOld"}, | 57 | {1, &NfcInterface::Finalize, "FinalizeOld"}, |
| 58 | {2, &NfcInterface::GetState, "GetStateOld"}, | 58 | {2, &NfcInterface::GetState, "GetStateOld"}, |
| 59 | {3, &NfcInterface::IsNfcEnabled, "IsNfcEnabledOld"}, | 59 | {3, &NfcInterface::IsNfcEnabled, "IsNfcEnabledOld"}, |
| 60 | {100, nullptr, "SetNfcEnabledOld"}, | 60 | {100, &NfcInterface::SetNfcEnabled, "SetNfcEnabledOld"}, |
| 61 | {400, &NfcInterface::Initialize, "Initialize"}, | 61 | {400, &NfcInterface::Initialize, "Initialize"}, |
| 62 | {401, &NfcInterface::Finalize, "Finalize"}, | 62 | {401, &NfcInterface::Finalize, "Finalize"}, |
| 63 | {402, &NfcInterface::GetState, "GetState"}, | 63 | {402, &NfcInterface::GetState, "GetState"}, |
| @@ -71,7 +71,7 @@ public: | |||
| 71 | {410, &NfcInterface::GetTagInfo, "GetTagInfo"}, | 71 | {410, &NfcInterface::GetTagInfo, "GetTagInfo"}, |
| 72 | {411, &NfcInterface::AttachActivateEvent, "AttachActivateEvent"}, | 72 | {411, &NfcInterface::AttachActivateEvent, "AttachActivateEvent"}, |
| 73 | {412, &NfcInterface::AttachDeactivateEvent, "AttachDeactivateEvent"}, | 73 | {412, &NfcInterface::AttachDeactivateEvent, "AttachDeactivateEvent"}, |
| 74 | {500, nullptr, "SetNfcEnabled"}, | 74 | {500, &NfcInterface::SetNfcEnabled, "SetNfcEnabled"}, |
| 75 | {510, nullptr, "OutputTestWave"}, | 75 | {510, nullptr, "OutputTestWave"}, |
| 76 | {1000, &NfcInterface::ReadMifare, "ReadMifare"}, | 76 | {1000, &NfcInterface::ReadMifare, "ReadMifare"}, |
| 77 | {1001, &NfcInterface::WriteMifare, "WriteMifare"}, | 77 | {1001, &NfcInterface::WriteMifare, "WriteMifare"}, |
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp index 3e2c7deab..c28e55431 100644 --- a/src/core/hle/service/nfc/nfc_interface.cpp +++ b/src/core/hle/service/nfc/nfc_interface.cpp | |||
| @@ -13,13 +13,18 @@ | |||
| 13 | #include "core/hle/service/nfc/nfc_result.h" | 13 | #include "core/hle/service/nfc/nfc_result.h" |
| 14 | #include "core/hle/service/nfc/nfc_types.h" | 14 | #include "core/hle/service/nfc/nfc_types.h" |
| 15 | #include "core/hle/service/nfp/nfp_result.h" | 15 | #include "core/hle/service/nfp/nfp_result.h" |
| 16 | #include "core/hle/service/set/system_settings_server.h" | ||
| 17 | #include "core/hle/service/sm/sm.h" | ||
| 16 | #include "hid_core/hid_types.h" | 18 | #include "hid_core/hid_types.h" |
| 17 | 19 | ||
| 18 | namespace Service::NFC { | 20 | namespace Service::NFC { |
| 19 | 21 | ||
| 20 | NfcInterface::NfcInterface(Core::System& system_, const char* name, BackendType service_backend) | 22 | NfcInterface::NfcInterface(Core::System& system_, const char* name, BackendType service_backend) |
| 21 | : ServiceFramework{system_, name}, service_context{system_, service_name}, | 23 | : ServiceFramework{system_, name}, service_context{system_, service_name}, |
| 22 | backend_type{service_backend} {} | 24 | backend_type{service_backend} { |
| 25 | m_set_sys = | ||
| 26 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||
| 27 | } | ||
| 23 | 28 | ||
| 24 | NfcInterface ::~NfcInterface() = default; | 29 | NfcInterface ::~NfcInterface() = default; |
| 25 | 30 | ||
| @@ -65,11 +70,11 @@ void NfcInterface::GetState(HLERequestContext& ctx) { | |||
| 65 | void NfcInterface::IsNfcEnabled(HLERequestContext& ctx) { | 70 | void NfcInterface::IsNfcEnabled(HLERequestContext& ctx) { |
| 66 | LOG_DEBUG(Service_NFC, "called"); | 71 | LOG_DEBUG(Service_NFC, "called"); |
| 67 | 72 | ||
| 68 | // TODO: This calls nn::settings::detail::GetNfcEnableFlag | 73 | bool is_enabled{}; |
| 69 | const bool is_enabled = true; | 74 | const auto result = m_set_sys->GetNfcEnableFlag(&is_enabled); |
| 70 | 75 | ||
| 71 | IPC::ResponseBuilder rb{ctx, 3}; | 76 | IPC::ResponseBuilder rb{ctx, 3}; |
| 72 | rb.Push(ResultSuccess); | 77 | rb.Push(result); |
| 73 | rb.Push(is_enabled); | 78 | rb.Push(is_enabled); |
| 74 | } | 79 | } |
| 75 | 80 | ||
| @@ -212,6 +217,17 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { | |||
| 212 | rb.PushCopyObjects(out_event); | 217 | rb.PushCopyObjects(out_event); |
| 213 | } | 218 | } |
| 214 | 219 | ||
| 220 | void NfcInterface::SetNfcEnabled(HLERequestContext& ctx) { | ||
| 221 | IPC::RequestParser rp{ctx}; | ||
| 222 | const auto is_enabled{rp.Pop<bool>()}; | ||
| 223 | LOG_DEBUG(Service_NFC, "called, is_enabled={}", is_enabled); | ||
| 224 | |||
| 225 | const auto result = m_set_sys->SetNfcEnableFlag(is_enabled); | ||
| 226 | |||
| 227 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 228 | rb.Push(result); | ||
| 229 | } | ||
| 230 | |||
| 215 | void NfcInterface::ReadMifare(HLERequestContext& ctx) { | 231 | void NfcInterface::ReadMifare(HLERequestContext& ctx) { |
| 216 | IPC::RequestParser rp{ctx}; | 232 | IPC::RequestParser rp{ctx}; |
| 217 | const auto device_handle{rp.Pop<u64>()}; | 233 | const auto device_handle{rp.Pop<u64>()}; |
diff --git a/src/core/hle/service/nfc/nfc_interface.h b/src/core/hle/service/nfc/nfc_interface.h index 08be174d8..5cc0d8ec0 100644 --- a/src/core/hle/service/nfc/nfc_interface.h +++ b/src/core/hle/service/nfc/nfc_interface.h | |||
| @@ -7,6 +7,10 @@ | |||
| 7 | #include "core/hle/service/nfc/nfc_types.h" | 7 | #include "core/hle/service/nfc/nfc_types.h" |
| 8 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 9 | 9 | ||
| 10 | namespace Service::Set { | ||
| 11 | class ISystemSettingsServer; | ||
| 12 | } | ||
| 13 | |||
| 10 | namespace Service::NFC { | 14 | namespace Service::NFC { |
| 11 | class DeviceManager; | 15 | class DeviceManager; |
| 12 | 16 | ||
| @@ -29,6 +33,7 @@ public: | |||
| 29 | void AttachActivateEvent(HLERequestContext& ctx); | 33 | void AttachActivateEvent(HLERequestContext& ctx); |
| 30 | void AttachDeactivateEvent(HLERequestContext& ctx); | 34 | void AttachDeactivateEvent(HLERequestContext& ctx); |
| 31 | void ReadMifare(HLERequestContext& ctx); | 35 | void ReadMifare(HLERequestContext& ctx); |
| 36 | void SetNfcEnabled(HLERequestContext& ctx); | ||
| 32 | void WriteMifare(HLERequestContext& ctx); | 37 | void WriteMifare(HLERequestContext& ctx); |
| 33 | void SendCommandByPassThrough(HLERequestContext& ctx); | 38 | void SendCommandByPassThrough(HLERequestContext& ctx); |
| 34 | 39 | ||
| @@ -44,6 +49,7 @@ protected: | |||
| 44 | BackendType backend_type; | 49 | BackendType backend_type; |
| 45 | State state{State::NonInitialized}; | 50 | State state{State::NonInitialized}; |
| 46 | std::shared_ptr<DeviceManager> device_manager = nullptr; | 51 | std::shared_ptr<DeviceManager> device_manager = nullptr; |
| 52 | std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||
| 47 | }; | 53 | }; |
| 48 | 54 | ||
| 49 | } // namespace Service::NFC | 55 | } // namespace Service::NFC |
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp index a162e5c54..e54827efe 100644 --- a/src/core/hle/service/npns/npns.cpp +++ b/src/core/hle/service/npns/npns.cpp | |||
| @@ -3,22 +3,26 @@ | |||
| 3 | 3 | ||
| 4 | #include <memory> | 4 | #include <memory> |
| 5 | 5 | ||
| 6 | #include "core/hle/kernel/k_event.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | #include "core/hle/service/kernel_helpers.h" | ||
| 6 | #include "core/hle/service/npns/npns.h" | 9 | #include "core/hle/service/npns/npns.h" |
| 7 | #include "core/hle/service/server_manager.h" | 10 | #include "core/hle/service/server_manager.h" |
| 8 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 9 | 12 | ||
| 10 | namespace Service::NPNS { | 13 | namespace Service::NPNS { |
| 11 | 14 | ||
| 12 | class NPNS_S final : public ServiceFramework<NPNS_S> { | 15 | class INpnsSystem final : public ServiceFramework<INpnsSystem> { |
| 13 | public: | 16 | public: |
| 14 | explicit NPNS_S(Core::System& system_) : ServiceFramework{system_, "npns:s"} { | 17 | explicit INpnsSystem(Core::System& system_) |
| 18 | : ServiceFramework{system_, "npns:s"}, service_context{system, "npns:s"} { | ||
| 15 | // clang-format off | 19 | // clang-format off |
| 16 | static const FunctionInfo functions[] = { | 20 | static const FunctionInfo functions[] = { |
| 17 | {1, nullptr, "ListenAll"}, | 21 | {1, nullptr, "ListenAll"}, |
| 18 | {2, nullptr, "ListenTo"}, | 22 | {2, C<&INpnsSystem::ListenTo>, "ListenTo"}, |
| 19 | {3, nullptr, "Receive"}, | 23 | {3, nullptr, "Receive"}, |
| 20 | {4, nullptr, "ReceiveRaw"}, | 24 | {4, nullptr, "ReceiveRaw"}, |
| 21 | {5, nullptr, "GetReceiveEvent"}, | 25 | {5, C<&INpnsSystem::GetReceiveEvent>, "GetReceiveEvent"}, |
| 22 | {6, nullptr, "ListenUndelivered"}, | 26 | {6, nullptr, "ListenUndelivered"}, |
| 23 | {7, nullptr, "GetStateChangeEVent"}, | 27 | {7, nullptr, "GetStateChangeEVent"}, |
| 24 | {11, nullptr, "SubscribeTopic"}, | 28 | {11, nullptr, "SubscribeTopic"}, |
| @@ -59,12 +63,34 @@ public: | |||
| 59 | // clang-format on | 63 | // clang-format on |
| 60 | 64 | ||
| 61 | RegisterHandlers(functions); | 65 | RegisterHandlers(functions); |
| 66 | |||
| 67 | get_receive_event = service_context.CreateEvent("npns:s:GetReceiveEvent"); | ||
| 62 | } | 68 | } |
| 69 | |||
| 70 | ~INpnsSystem() override { | ||
| 71 | service_context.CloseEvent(get_receive_event); | ||
| 72 | } | ||
| 73 | |||
| 74 | private: | ||
| 75 | Result ListenTo(u32 program_id) { | ||
| 76 | LOG_WARNING(Service_AM, "(STUBBED) called, program_id={}", program_id); | ||
| 77 | R_SUCCEED(); | ||
| 78 | } | ||
| 79 | |||
| 80 | Result GetReceiveEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 81 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 82 | |||
| 83 | *out_event = &get_receive_event->GetReadableEvent(); | ||
| 84 | R_SUCCEED(); | ||
| 85 | } | ||
| 86 | |||
| 87 | KernelHelpers::ServiceContext service_context; | ||
| 88 | Kernel::KEvent* get_receive_event; | ||
| 63 | }; | 89 | }; |
| 64 | 90 | ||
| 65 | class NPNS_U final : public ServiceFramework<NPNS_U> { | 91 | class INpnsUser final : public ServiceFramework<INpnsUser> { |
| 66 | public: | 92 | public: |
| 67 | explicit NPNS_U(Core::System& system_) : ServiceFramework{system_, "npns:u"} { | 93 | explicit INpnsUser(Core::System& system_) : ServiceFramework{system_, "npns:u"} { |
| 68 | // clang-format off | 94 | // clang-format off |
| 69 | static const FunctionInfo functions[] = { | 95 | static const FunctionInfo functions[] = { |
| 70 | {1, nullptr, "ListenAll"}, | 96 | {1, nullptr, "ListenAll"}, |
| @@ -97,8 +123,8 @@ public: | |||
| 97 | void LoopProcess(Core::System& system) { | 123 | void LoopProcess(Core::System& system) { |
| 98 | auto server_manager = std::make_unique<ServerManager>(system); | 124 | auto server_manager = std::make_unique<ServerManager>(system); |
| 99 | 125 | ||
| 100 | server_manager->RegisterNamedService("npns:s", std::make_shared<NPNS_S>(system)); | 126 | server_manager->RegisterNamedService("npns:s", std::make_shared<INpnsSystem>(system)); |
| 101 | server_manager->RegisterNamedService("npns:u", std::make_shared<NPNS_U>(system)); | 127 | server_manager->RegisterNamedService("npns:u", std::make_shared<INpnsUser>(system)); |
| 102 | ServerManager::RunServer(std::move(server_manager)); | 128 | ServerManager::RunServer(std::move(server_manager)); |
| 103 | } | 129 | } |
| 104 | 130 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index bf12d69a5..efc9cca1c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/k_process.h" | ||
| 8 | #include "core/hle/service/nvdrv/core/container.h" | 9 | #include "core/hle/service/nvdrv/core/container.h" |
| 9 | #include "core/hle/service/nvdrv/core/nvmap.h" | 10 | #include "core/hle/service/nvdrv/core/nvmap.h" |
| 10 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" | 11 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" |
| @@ -75,7 +76,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 75 | case 0xd: | 76 | case 0xd: |
| 76 | return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); | 77 | return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); |
| 77 | case 0x1a: | 78 | case 0x1a: |
| 78 | return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output); | 79 | return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output, fd); |
| 79 | case 0x1b: | 80 | case 0x1b: |
| 80 | return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true); | 81 | return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true); |
| 81 | case 0x1d: | 82 | case 0x1d: |
| @@ -120,8 +121,13 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 120 | return NvResult::NotImplemented; | 121 | return NvResult::NotImplemented; |
| 121 | } | 122 | } |
| 122 | 123 | ||
| 123 | void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {} | 124 | void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) { |
| 124 | void nvhost_gpu::OnClose(DeviceFD fd) {} | 125 | sessions[fd] = session_id; |
| 126 | } | ||
| 127 | |||
| 128 | void nvhost_gpu::OnClose(DeviceFD fd) { | ||
| 129 | sessions.erase(fd); | ||
| 130 | } | ||
| 125 | 131 | ||
| 126 | NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { | 132 | NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { |
| 127 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 133 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| @@ -161,7 +167,7 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) { | |||
| 161 | return NvResult::Success; | 167 | return NvResult::Success; |
| 162 | } | 168 | } |
| 163 | 169 | ||
| 164 | NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { | 170 | NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) { |
| 165 | LOG_WARNING(Service_NVDRV, | 171 | LOG_WARNING(Service_NVDRV, |
| 166 | "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " | 172 | "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " |
| 167 | "unk1={:X}, unk2={:X}, unk3={:X}", | 173 | "unk1={:X}, unk2={:X}, unk3={:X}", |
| @@ -173,7 +179,12 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { | |||
| 173 | return NvResult::AlreadyAllocated; | 179 | return NvResult::AlreadyAllocated; |
| 174 | } | 180 | } |
| 175 | 181 | ||
| 176 | system.GPU().InitChannel(*channel_state); | 182 | u64 program_id{}; |
| 183 | if (auto* const session = core.GetSession(sessions[fd]); session != nullptr) { | ||
| 184 | program_id = session->process->GetProgramId(); | ||
| 185 | } | ||
| 186 | |||
| 187 | system.GPU().InitChannel(*channel_state, program_id); | ||
| 177 | 188 | ||
| 178 | params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); | 189 | params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); |
| 179 | 190 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index e34a978db..e0aeef953 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -192,7 +192,7 @@ private: | |||
| 192 | NvResult ZCullBind(IoctlZCullBind& params); | 192 | NvResult ZCullBind(IoctlZCullBind& params); |
| 193 | NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); | 193 | NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); |
| 194 | NvResult SetChannelPriority(IoctlChannelSetPriority& params); | 194 | NvResult SetChannelPriority(IoctlChannelSetPriority& params); |
| 195 | NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params); | 195 | NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd); |
| 196 | NvResult AllocateObjectContext(IoctlAllocObjCtx& params); | 196 | NvResult AllocateObjectContext(IoctlAllocObjCtx& params); |
| 197 | 197 | ||
| 198 | NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); | 198 | NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); |
| @@ -210,6 +210,7 @@ private: | |||
| 210 | NvCore::SyncpointManager& syncpoint_manager; | 210 | NvCore::SyncpointManager& syncpoint_manager; |
| 211 | NvCore::NvMap& nvmap; | 211 | NvCore::NvMap& nvmap; |
| 212 | std::shared_ptr<Tegra::Control::ChannelState> channel_state; | 212 | std::shared_ptr<Tegra::Control::ChannelState> channel_state; |
| 213 | std::unordered_map<DeviceFD, NvCore::SessionId> sessions; | ||
| 213 | u32 channel_syncpoint; | 214 | u32 channel_syncpoint; |
| 214 | std::mutex channel_mutex; | 215 | std::mutex channel_mutex; |
| 215 | 216 | ||
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp index 0b41bbcb9..3d898725e 100644 --- a/src/core/hle/service/server_manager.cpp +++ b/src/core/hle/service/server_manager.cpp | |||
| @@ -93,13 +93,19 @@ ServerManager::~ServerManager() { | |||
| 93 | m_threads.clear(); | 93 | m_threads.clear(); |
| 94 | 94 | ||
| 95 | // Clean up ports. | 95 | // Clean up ports. |
| 96 | for (auto it = m_servers.begin(); it != m_servers.end(); it = m_servers.erase(it)) { | 96 | auto port_it = m_servers.begin(); |
| 97 | delete std::addressof(*it); | 97 | while (port_it != m_servers.end()) { |
| 98 | auto* const port = std::addressof(*port_it); | ||
| 99 | port_it = m_servers.erase(port_it); | ||
| 100 | delete port; | ||
| 98 | } | 101 | } |
| 99 | 102 | ||
| 100 | // Clean up sessions. | 103 | // Clean up sessions. |
| 101 | for (auto it = m_sessions.begin(); it != m_sessions.end(); it = m_sessions.erase(it)) { | 104 | auto session_it = m_sessions.begin(); |
| 102 | delete std::addressof(*it); | 105 | while (session_it != m_sessions.end()) { |
| 106 | auto* const session = std::addressof(*session_it); | ||
| 107 | session_it = m_sessions.erase(session_it); | ||
| 108 | delete session; | ||
| 103 | } | 109 | } |
| 104 | 110 | ||
| 105 | // Close wakeup event. | 111 | // Close wakeup event. |
diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp index 1aa85ea54..3defa4b31 100644 --- a/src/core/hle/service/services.cpp +++ b/src/core/hle/service/services.cpp | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include "core/hle/service/acc/acc.h" | 6 | #include "core/hle/service/acc/acc.h" |
| 7 | #include "core/hle/service/am/am.h" | 7 | #include "core/hle/service/am/am.h" |
| 8 | #include "core/hle/service/aoc/aoc_u.h" | 8 | #include "core/hle/service/aoc/addon_content_manager.h" |
| 9 | #include "core/hle/service/apm/apm.h" | 9 | #include "core/hle/service/apm/apm.h" |
| 10 | #include "core/hle/service/audio/audio.h" | 10 | #include "core/hle/service/audio/audio.h" |
| 11 | #include "core/hle/service/bcat/bcat.h" | 11 | #include "core/hle/service/bcat/bcat.h" |
diff --git a/src/core/hle/service/set/setting_formats/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp index 7231ff78e..caa30c2d5 100644 --- a/src/core/hle/service/set/setting_formats/system_settings.cpp +++ b/src/core/hle/service/set/setting_formats/system_settings.cpp | |||
| @@ -52,6 +52,10 @@ SystemSettings DefaultSystemSettings() { | |||
| 52 | settings.battery_percentage_flag = true; | 52 | settings.battery_percentage_flag = true; |
| 53 | settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; | 53 | settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; |
| 54 | settings.vibration_master_volume = 1.0f; | 54 | settings.vibration_master_volume = 1.0f; |
| 55 | settings.touch_screen_mode = TouchScreenMode::Standard; | ||
| 56 | settings.nfc_enable_flag = true; | ||
| 57 | settings.bluetooth_enable_flag = true; | ||
| 58 | settings.wireless_lan_enable_flag = true; | ||
| 55 | 59 | ||
| 56 | const auto language_code = | 60 | const auto language_code = |
| 57 | available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())]; | 61 | available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())]; |
diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h index 29664e88c..92c2948b0 100644 --- a/src/core/hle/service/set/settings_types.h +++ b/src/core/hle/service/set/settings_types.h | |||
| @@ -243,6 +243,11 @@ enum class TvResolution : u32 { | |||
| 243 | Resolution480p, | 243 | Resolution480p, |
| 244 | }; | 244 | }; |
| 245 | 245 | ||
| 246 | enum class PlatformRegion : s32 { | ||
| 247 | Global = 1, | ||
| 248 | Terra = 2, | ||
| 249 | }; | ||
| 250 | |||
| 246 | constexpr std::array<LanguageCode, 18> available_language_codes = {{ | 251 | constexpr std::array<LanguageCode, 18> available_language_codes = {{ |
| 247 | LanguageCode::JA, | 252 | LanguageCode::JA, |
| 248 | LanguageCode::EN_US, | 253 | LanguageCode::EN_US, |
| @@ -405,8 +410,7 @@ struct EulaVersion { | |||
| 405 | SystemRegionCode region_code; | 410 | SystemRegionCode region_code; |
| 406 | EulaVersionClockType clock_type; | 411 | EulaVersionClockType clock_type; |
| 407 | INSERT_PADDING_BYTES(0x4); | 412 | INSERT_PADDING_BYTES(0x4); |
| 408 | s64 posix_time; | 413 | Service::PSC::Time::SystemClockContext system_clock_context; |
| 409 | Service::PSC::Time::SteadyClockTimePoint timestamp; | ||
| 410 | }; | 414 | }; |
| 411 | static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); | 415 | static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); |
| 412 | 416 | ||
diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index 93925f783..0dc8db821 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | namespace Service::Set { | 26 | namespace Service::Set { |
| 27 | 27 | ||
| 28 | namespace { | 28 | namespace { |
| 29 | constexpr u32 SETTINGS_VERSION{3u}; | 29 | constexpr u32 SETTINGS_VERSION{4u}; |
| 30 | constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't'); | 30 | constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't'); |
| 31 | struct SettingsHeader { | 31 | struct SettingsHeader { |
| 32 | u64 magic; | 32 | u64 magic; |
| @@ -272,8 +272,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 272 | {180, nullptr, "SetZoomFlag"}, | 272 | {180, nullptr, "SetZoomFlag"}, |
| 273 | {181, nullptr, "GetT"}, | 273 | {181, nullptr, "GetT"}, |
| 274 | {182, nullptr, "SetT"}, | 274 | {182, nullptr, "SetT"}, |
| 275 | {183, nullptr, "GetPlatformRegion"}, | 275 | {183, C<&ISystemSettingsServer::GetPlatformRegion>, "GetPlatformRegion"}, |
| 276 | {184, nullptr, "SetPlatformRegion"}, | 276 | {184, C<&ISystemSettingsServer::SetPlatformRegion>, "SetPlatformRegion"}, |
| 277 | {185, C<&ISystemSettingsServer::GetHomeMenuSchemeModel>, "GetHomeMenuSchemeModel"}, | 277 | {185, C<&ISystemSettingsServer::GetHomeMenuSchemeModel>, "GetHomeMenuSchemeModel"}, |
| 278 | {186, nullptr, "GetMemoryUsageRateFlag"}, | 278 | {186, nullptr, "GetMemoryUsageRateFlag"}, |
| 279 | {187, C<&ISystemSettingsServer::GetTouchScreenMode>, "GetTouchScreenMode"}, | 279 | {187, C<&ISystemSettingsServer::GetTouchScreenMode>, "GetTouchScreenMode"}, |
| @@ -306,6 +306,20 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 306 | RegisterHandlers(functions); | 306 | RegisterHandlers(functions); |
| 307 | 307 | ||
| 308 | SetupSettings(); | 308 | SetupSettings(); |
| 309 | |||
| 310 | m_system_settings.region_code = | ||
| 311 | static_cast<SystemRegionCode>(::Settings::values.region_index.GetValue()); | ||
| 312 | |||
| 313 | // TODO: Remove this when starter applet is fully functional | ||
| 314 | EulaVersion eula_version{ | ||
| 315 | .version = 0x10000, | ||
| 316 | .region_code = m_system_settings.region_code, | ||
| 317 | .clock_type = EulaVersionClockType::SteadyClock, | ||
| 318 | .system_clock_context = m_system_settings.user_system_clock_context, | ||
| 319 | }; | ||
| 320 | m_system_settings.eula_versions[0] = eula_version; | ||
| 321 | m_system_settings.eula_version_count = 1; | ||
| 322 | |||
| 309 | m_save_thread = | 323 | m_save_thread = |
| 310 | std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); | 324 | std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); |
| 311 | } | 325 | } |
| @@ -701,7 +715,7 @@ Result ISystemSettingsServer::GetSettingsItemValueSize( | |||
| 701 | } | 715 | } |
| 702 | 716 | ||
| 703 | Result ISystemSettingsServer::GetSettingsItemValue( | 717 | Result ISystemSettingsServer::GetSettingsItemValue( |
| 704 | OutBuffer<BufferAttr_HipcMapAlias> out_data, | 718 | Out<u64> out_size, OutBuffer<BufferAttr_HipcMapAlias> out_data, |
| 705 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, | 719 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, |
| 706 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buffer) { | 720 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buffer) { |
| 707 | const std::string setting_category{Common::StringFromBuffer(*setting_category_buffer)}; | 721 | const std::string setting_category{Common::StringFromBuffer(*setting_category_buffer)}; |
| @@ -709,7 +723,7 @@ Result ISystemSettingsServer::GetSettingsItemValue( | |||
| 709 | 723 | ||
| 710 | LOG_INFO(Service_SET, "called, category={}, name={}", setting_category, setting_name); | 724 | LOG_INFO(Service_SET, "called, category={}, name={}", setting_category, setting_name); |
| 711 | 725 | ||
| 712 | R_RETURN(GetSettingsItemValueImpl(out_data, setting_category, setting_name)); | 726 | R_RETURN(GetSettingsItemValueImpl(out_data, *out_size, setting_category, setting_name)); |
| 713 | } | 727 | } |
| 714 | 728 | ||
| 715 | Result ISystemSettingsServer::GetTvSettings(Out<TvSettings> out_tv_settings) { | 729 | Result ISystemSettingsServer::GetTvSettings(Out<TvSettings> out_tv_settings) { |
| @@ -1236,6 +1250,18 @@ Result ISystemSettingsServer::GetHomeMenuScheme(Out<HomeMenuScheme> out_home_men | |||
| 1236 | R_SUCCEED(); | 1250 | R_SUCCEED(); |
| 1237 | } | 1251 | } |
| 1238 | 1252 | ||
| 1253 | Result ISystemSettingsServer::GetPlatformRegion(Out<PlatformRegion> out_platform_region) { | ||
| 1254 | LOG_WARNING(Service_SET, "(STUBBED) called"); | ||
| 1255 | |||
| 1256 | *out_platform_region = PlatformRegion::Global; | ||
| 1257 | R_SUCCEED(); | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | Result ISystemSettingsServer::SetPlatformRegion(PlatformRegion platform_region) { | ||
| 1261 | LOG_WARNING(Service_SET, "(STUBBED) called"); | ||
| 1262 | R_SUCCEED(); | ||
| 1263 | } | ||
| 1264 | |||
| 1239 | Result ISystemSettingsServer::GetHomeMenuSchemeModel(Out<u32> out_home_menu_scheme_model) { | 1265 | Result ISystemSettingsServer::GetHomeMenuSchemeModel(Out<u32> out_home_menu_scheme_model) { |
| 1240 | LOG_WARNING(Service_SET, "(STUBBED) called"); | 1266 | LOG_WARNING(Service_SET, "(STUBBED) called"); |
| 1241 | 1267 | ||
| @@ -1349,13 +1375,16 @@ void ISystemSettingsServer::SetSaveNeeded() { | |||
| 1349 | m_save_needed = true; | 1375 | m_save_needed = true; |
| 1350 | } | 1376 | } |
| 1351 | 1377 | ||
| 1352 | Result ISystemSettingsServer::GetSettingsItemValueImpl(std::vector<u8>& out_value, | 1378 | Result ISystemSettingsServer::GetSettingsItemValueImpl(std::span<u8> out_value, u64& out_size, |
| 1353 | const std::string& category, | 1379 | const std::string& category, |
| 1354 | const std::string& name) { | 1380 | const std::string& name) { |
| 1355 | auto settings{GetSettings()}; | 1381 | auto settings{GetSettings()}; |
| 1356 | R_UNLESS(settings.contains(category) && settings[category].contains(name), ResultUnknown); | 1382 | R_UNLESS(settings.contains(category) && settings[category].contains(name), ResultUnknown); |
| 1357 | 1383 | ||
| 1358 | out_value = settings[category][name]; | 1384 | ASSERT_MSG(out_value.size() >= settings[category][name].size(), |
| 1385 | "Stored type is bigger than requested type"); | ||
| 1386 | out_size = std::min<u64>(settings[category][name].size(), out_value.size()); | ||
| 1387 | std::memcpy(out_value.data(), settings[category][name].data(), out_size); | ||
| 1359 | R_SUCCEED(); | 1388 | R_SUCCEED(); |
| 1360 | } | 1389 | } |
| 1361 | 1390 | ||
diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 46e06c8ea..993e5de7d 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h | |||
| @@ -34,20 +34,17 @@ public: | |||
| 34 | explicit ISystemSettingsServer(Core::System& system_); | 34 | explicit ISystemSettingsServer(Core::System& system_); |
| 35 | ~ISystemSettingsServer() override; | 35 | ~ISystemSettingsServer() override; |
| 36 | 36 | ||
| 37 | Result GetSettingsItemValueImpl(std::vector<u8>& out_value, const std::string& category, | 37 | Result GetSettingsItemValueImpl(std::span<u8> out_value, u64& out_size, |
| 38 | const std::string& name); | 38 | const std::string& category, const std::string& name); |
| 39 | 39 | ||
| 40 | template <typename T> | 40 | template <typename T> |
| 41 | Result GetSettingsItemValueImpl(T& value, const std::string& category, | 41 | Result GetSettingsItemValueImpl(T& out_value, const std::string& category, |
| 42 | const std::string& name) { | 42 | const std::string& name) { |
| 43 | std::vector<u8> data; | 43 | u64 data_size{}; |
| 44 | const auto result = GetSettingsItemValueImpl(data, category, name); | 44 | std::vector<u8> data(sizeof(T)); |
| 45 | if (result.IsError()) { | 45 | R_TRY(GetSettingsItemValueImpl(data, data_size, category, name)); |
| 46 | return result; | 46 | std::memcpy(&out_value, data.data(), data_size); |
| 47 | } | 47 | R_SUCCEED(); |
| 48 | ASSERT(data.size() >= sizeof(T)); | ||
| 49 | std::memcpy(&value, data.data(), sizeof(T)); | ||
| 50 | return result; | ||
| 51 | } | 48 | } |
| 52 | 49 | ||
| 53 | public: | 50 | public: |
| @@ -84,7 +81,7 @@ public: | |||
| 84 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, | 81 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, |
| 85 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buf); | 82 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buf); |
| 86 | Result GetSettingsItemValue( | 83 | Result GetSettingsItemValue( |
| 87 | OutBuffer<BufferAttr_HipcMapAlias> out_data, | 84 | Out<u64> out_size, OutBuffer<BufferAttr_HipcMapAlias> out_data, |
| 88 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, | 85 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, |
| 89 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buffer); | 86 | InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buffer); |
| 90 | Result GetTvSettings(Out<TvSettings> out_tv_settings); | 87 | Result GetTvSettings(Out<TvSettings> out_tv_settings); |
| @@ -152,6 +149,8 @@ public: | |||
| 152 | Result GetHomeMenuScheme(Out<HomeMenuScheme> out_home_menu_scheme); | 149 | Result GetHomeMenuScheme(Out<HomeMenuScheme> out_home_menu_scheme); |
| 153 | Result GetHomeMenuSchemeModel(Out<u32> out_home_menu_scheme_model); | 150 | Result GetHomeMenuSchemeModel(Out<u32> out_home_menu_scheme_model); |
| 154 | Result GetTouchScreenMode(Out<TouchScreenMode> out_touch_screen_mode); | 151 | Result GetTouchScreenMode(Out<TouchScreenMode> out_touch_screen_mode); |
| 152 | Result GetPlatformRegion(Out<PlatformRegion> out_platform_region); | ||
| 153 | Result SetPlatformRegion(PlatformRegion platform_region); | ||
| 155 | Result SetTouchScreenMode(TouchScreenMode touch_screen_mode); | 154 | Result SetTouchScreenMode(TouchScreenMode touch_screen_mode); |
| 156 | Result GetFieldTestingFlag(Out<bool> out_field_testing_flag); | 155 | Result GetFieldTestingFlag(Out<bool> out_field_testing_flag); |
| 157 | Result GetPanelCrcMode(Out<s32> out_panel_crc_mode); | 156 | Result GetPanelCrcMode(Out<s32> out_panel_crc_mode); |
diff --git a/src/core/hle/service/ssl/cert_store.cpp b/src/core/hle/service/ssl/cert_store.cpp new file mode 100644 index 000000000..b321e5d32 --- /dev/null +++ b/src/core/hle/service/ssl/cert_store.cpp | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/alignment.h" | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/file_sys/content_archive.h" | ||
| 7 | #include "core/file_sys/nca_metadata.h" | ||
| 8 | #include "core/file_sys/registered_cache.h" | ||
| 9 | #include "core/file_sys/romfs.h" | ||
| 10 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 11 | #include "core/hle/service/ssl/cert_store.h" | ||
| 12 | |||
| 13 | namespace Service::SSL { | ||
| 14 | |||
| 15 | // https://switchbrew.org/wiki/SSL_services#CertStore | ||
| 16 | |||
| 17 | CertStore::CertStore(Core::System& system) { | ||
| 18 | constexpr u64 CertStoreDataId = 0x0100000000000800ULL; | ||
| 19 | |||
| 20 | auto& fsc = system.GetFileSystemController(); | ||
| 21 | |||
| 22 | // Attempt to load certificate data from storage | ||
| 23 | const auto nca = | ||
| 24 | fsc.GetSystemNANDContents()->GetEntry(CertStoreDataId, FileSys::ContentRecordType::Data); | ||
| 25 | if (!nca) { | ||
| 26 | return; | ||
| 27 | } | ||
| 28 | const auto romfs = nca->GetRomFS(); | ||
| 29 | if (!romfs) { | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | const auto extracted = FileSys::ExtractRomFS(romfs); | ||
| 33 | if (!extracted) { | ||
| 34 | LOG_ERROR(Service_SSL, "CertStore could not be extracted, corrupt RomFS?"); | ||
| 35 | return; | ||
| 36 | } | ||
| 37 | const auto cert_store_file = extracted->GetFile("ssl_TrustedCerts.bdf"); | ||
| 38 | if (!cert_store_file) { | ||
| 39 | LOG_ERROR(Service_SSL, "Failed to find trusted certificates in CertStore"); | ||
| 40 | return; | ||
| 41 | } | ||
| 42 | |||
| 43 | // Read and verify the header. | ||
| 44 | CertStoreHeader header; | ||
| 45 | cert_store_file->ReadObject(std::addressof(header)); | ||
| 46 | |||
| 47 | if (header.magic != Common::MakeMagic('s', 's', 'l', 'T')) { | ||
| 48 | LOG_ERROR(Service_SSL, "Invalid certificate store magic"); | ||
| 49 | return; | ||
| 50 | } | ||
| 51 | |||
| 52 | // Ensure the file can contains the number of entries it says it does. | ||
| 53 | const u64 expected_size = sizeof(header) + sizeof(CertStoreEntry) * header.num_entries; | ||
| 54 | const u64 actual_size = cert_store_file->GetSize(); | ||
| 55 | if (actual_size < expected_size) { | ||
| 56 | LOG_ERROR(Service_SSL, "Size mismatch, expected at least {} bytes, got {}", expected_size, | ||
| 57 | actual_size); | ||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | // Read entries. | ||
| 62 | std::vector<CertStoreEntry> entries(header.num_entries); | ||
| 63 | cert_store_file->ReadArray(entries.data(), header.num_entries, sizeof(header)); | ||
| 64 | |||
| 65 | // Insert into memory store. | ||
| 66 | for (const auto& entry : entries) { | ||
| 67 | m_certs.emplace(entry.certificate_id, | ||
| 68 | Certificate{ | ||
| 69 | .status = entry.certificate_status, | ||
| 70 | .der_data = cert_store_file->ReadBytes( | ||
| 71 | entry.der_size, entry.der_offset + sizeof(header)), | ||
| 72 | }); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | CertStore::~CertStore() = default; | ||
| 77 | |||
| 78 | template <typename F> | ||
| 79 | void CertStore::ForEachCertificate(std::span<const CaCertificateId> certificate_ids, F&& f) { | ||
| 80 | if (certificate_ids.size() == 1 && certificate_ids.front() == CaCertificateId::All) { | ||
| 81 | for (const auto& entry : m_certs) { | ||
| 82 | f(entry); | ||
| 83 | } | ||
| 84 | } else { | ||
| 85 | for (const auto certificate_id : certificate_ids) { | ||
| 86 | const auto entry = m_certs.find(certificate_id); | ||
| 87 | if (entry == m_certs.end()) { | ||
| 88 | continue; | ||
| 89 | } | ||
| 90 | f(*entry); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | Result CertStore::GetCertificates(u32* out_num_entries, std::span<u8> out_data, | ||
| 96 | std::span<const CaCertificateId> certificate_ids) { | ||
| 97 | // Ensure the buffer is large enough to hold the output. | ||
| 98 | u32 required_size; | ||
| 99 | R_TRY(this->GetCertificateBufSize(std::addressof(required_size), out_num_entries, | ||
| 100 | certificate_ids)); | ||
| 101 | R_UNLESS(out_data.size_bytes() >= required_size, ResultUnknown); | ||
| 102 | |||
| 103 | // Make parallel arrays. | ||
| 104 | std::vector<BuiltInCertificateInfo> cert_infos; | ||
| 105 | std::vector<u8> der_datas; | ||
| 106 | |||
| 107 | const u32 der_data_offset = (*out_num_entries + 1) * sizeof(BuiltInCertificateInfo); | ||
| 108 | u32 cur_der_offset = der_data_offset; | ||
| 109 | |||
| 110 | // Fill output. | ||
| 111 | this->ForEachCertificate(certificate_ids, [&](auto& entry) { | ||
| 112 | const auto& [status, cur_der_data] = entry.second; | ||
| 113 | BuiltInCertificateInfo cert_info{ | ||
| 114 | .cert_id = entry.first, | ||
| 115 | .status = status, | ||
| 116 | .der_size = cur_der_data.size(), | ||
| 117 | .der_offset = cur_der_offset, | ||
| 118 | }; | ||
| 119 | |||
| 120 | cert_infos.push_back(cert_info); | ||
| 121 | der_datas.insert(der_datas.end(), cur_der_data.begin(), cur_der_data.end()); | ||
| 122 | cur_der_offset += static_cast<u32>(cur_der_data.size()); | ||
| 123 | }); | ||
| 124 | |||
| 125 | // Append terminator entry. | ||
| 126 | cert_infos.push_back(BuiltInCertificateInfo{ | ||
| 127 | .cert_id = CaCertificateId::All, | ||
| 128 | .status = TrustedCertStatus::Invalid, | ||
| 129 | .der_size = 0, | ||
| 130 | .der_offset = 0, | ||
| 131 | }); | ||
| 132 | |||
| 133 | // Write to output span. | ||
| 134 | std::memcpy(out_data.data(), cert_infos.data(), | ||
| 135 | cert_infos.size() * sizeof(BuiltInCertificateInfo)); | ||
| 136 | std::memcpy(out_data.data() + der_data_offset, der_datas.data(), der_datas.size()); | ||
| 137 | |||
| 138 | R_SUCCEED(); | ||
| 139 | } | ||
| 140 | |||
| 141 | Result CertStore::GetCertificateBufSize(u32* out_size, u32* out_num_entries, | ||
| 142 | std::span<const CaCertificateId> certificate_ids) { | ||
| 143 | // Output size is at least the size of the terminator entry. | ||
| 144 | *out_size = sizeof(BuiltInCertificateInfo); | ||
| 145 | *out_num_entries = 0; | ||
| 146 | |||
| 147 | this->ForEachCertificate(certificate_ids, [&](auto& entry) { | ||
| 148 | *out_size += sizeof(BuiltInCertificateInfo); | ||
| 149 | *out_size += Common::AlignUp(static_cast<u32>(entry.second.der_data.size()), 4); | ||
| 150 | (*out_num_entries)++; | ||
| 151 | }); | ||
| 152 | |||
| 153 | R_SUCCEED(); | ||
| 154 | } | ||
| 155 | |||
| 156 | } // namespace Service::SSL | ||
diff --git a/src/core/hle/service/ssl/cert_store.h b/src/core/hle/service/ssl/cert_store.h new file mode 100644 index 000000000..613d7b02a --- /dev/null +++ b/src/core/hle/service/ssl/cert_store.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <map> | ||
| 7 | #include <span> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "core/hle/result.h" | ||
| 11 | #include "core/hle/service/ssl/ssl_types.h" | ||
| 12 | |||
| 13 | namespace Core { | ||
| 14 | class System; | ||
| 15 | } | ||
| 16 | |||
| 17 | namespace Service::SSL { | ||
| 18 | |||
| 19 | class CertStore { | ||
| 20 | public: | ||
| 21 | explicit CertStore(Core::System& system); | ||
| 22 | ~CertStore(); | ||
| 23 | |||
| 24 | Result GetCertificates(u32* out_num_entries, std::span<u8> out_data, | ||
| 25 | std::span<const CaCertificateId> certificate_ids); | ||
| 26 | Result GetCertificateBufSize(u32* out_size, u32* out_num_entries, | ||
| 27 | std::span<const CaCertificateId> certificate_ids); | ||
| 28 | |||
| 29 | private: | ||
| 30 | template <typename F> | ||
| 31 | void ForEachCertificate(std::span<const CaCertificateId> certs, F&& f); | ||
| 32 | |||
| 33 | private: | ||
| 34 | struct Certificate { | ||
| 35 | TrustedCertStatus status; | ||
| 36 | std::vector<u8> der_data; | ||
| 37 | }; | ||
| 38 | |||
| 39 | std::map<CaCertificateId, Certificate> m_certs; | ||
| 40 | }; | ||
| 41 | |||
| 42 | } // namespace Service::SSL | ||
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 0fbb43057..008ee4492 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp | |||
| @@ -5,11 +5,13 @@ | |||
| 5 | 5 | ||
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/hle/result.h" | 7 | #include "core/hle/result.h" |
| 8 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | 9 | #include "core/hle/service/ipc_helpers.h" |
| 9 | #include "core/hle/service/server_manager.h" | 10 | #include "core/hle/service/server_manager.h" |
| 10 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 11 | #include "core/hle/service/sm/sm.h" | 12 | #include "core/hle/service/sm/sm.h" |
| 12 | #include "core/hle/service/sockets/bsd.h" | 13 | #include "core/hle/service/sockets/bsd.h" |
| 14 | #include "core/hle/service/ssl/cert_store.h" | ||
| 13 | #include "core/hle/service/ssl/ssl.h" | 15 | #include "core/hle/service/ssl/ssl.h" |
| 14 | #include "core/hle/service/ssl/ssl_backend.h" | 16 | #include "core/hle/service/ssl/ssl_backend.h" |
| 15 | #include "core/internal_network/network.h" | 17 | #include "core/internal_network/network.h" |
| @@ -492,13 +494,14 @@ private: | |||
| 492 | 494 | ||
| 493 | class ISslService final : public ServiceFramework<ISslService> { | 495 | class ISslService final : public ServiceFramework<ISslService> { |
| 494 | public: | 496 | public: |
| 495 | explicit ISslService(Core::System& system_) : ServiceFramework{system_, "ssl"} { | 497 | explicit ISslService(Core::System& system_) |
| 498 | : ServiceFramework{system_, "ssl"}, cert_store{system} { | ||
| 496 | // clang-format off | 499 | // clang-format off |
| 497 | static const FunctionInfo functions[] = { | 500 | static const FunctionInfo functions[] = { |
| 498 | {0, &ISslService::CreateContext, "CreateContext"}, | 501 | {0, &ISslService::CreateContext, "CreateContext"}, |
| 499 | {1, nullptr, "GetContextCount"}, | 502 | {1, nullptr, "GetContextCount"}, |
| 500 | {2, nullptr, "GetCertificates"}, | 503 | {2, D<&ISslService::GetCertificates>, "GetCertificates"}, |
| 501 | {3, nullptr, "GetCertificateBufSize"}, | 504 | {3, D<&ISslService::GetCertificateBufSize>, "GetCertificateBufSize"}, |
| 502 | {4, nullptr, "DebugIoctl"}, | 505 | {4, nullptr, "DebugIoctl"}, |
| 503 | {5, &ISslService::SetInterfaceVersion, "SetInterfaceVersion"}, | 506 | {5, &ISslService::SetInterfaceVersion, "SetInterfaceVersion"}, |
| 504 | {6, nullptr, "FlushSessionCache"}, | 507 | {6, nullptr, "FlushSessionCache"}, |
| @@ -540,6 +543,22 @@ private: | |||
| 540 | IPC::ResponseBuilder rb{ctx, 2}; | 543 | IPC::ResponseBuilder rb{ctx, 2}; |
| 541 | rb.Push(ResultSuccess); | 544 | rb.Push(ResultSuccess); |
| 542 | } | 545 | } |
| 546 | |||
| 547 | Result GetCertificateBufSize( | ||
| 548 | Out<u32> out_size, InArray<CaCertificateId, BufferAttr_HipcMapAlias> certificate_ids) { | ||
| 549 | LOG_INFO(Service_SSL, "called"); | ||
| 550 | u32 num_entries; | ||
| 551 | R_RETURN(cert_store.GetCertificateBufSize(out_size, &num_entries, certificate_ids)); | ||
| 552 | } | ||
| 553 | |||
| 554 | Result GetCertificates(Out<u32> out_num_entries, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, | ||
| 555 | InArray<CaCertificateId, BufferAttr_HipcMapAlias> certificate_ids) { | ||
| 556 | LOG_INFO(Service_SSL, "called"); | ||
| 557 | R_RETURN(cert_store.GetCertificates(out_num_entries, out_buffer, certificate_ids)); | ||
| 558 | } | ||
| 559 | |||
| 560 | private: | ||
| 561 | CertStore cert_store; | ||
| 543 | }; | 562 | }; |
| 544 | 563 | ||
| 545 | void LoopProcess(Core::System& system) { | 564 | void LoopProcess(Core::System& system) { |
diff --git a/src/core/hle/service/ssl/ssl_types.h b/src/core/hle/service/ssl/ssl_types.h new file mode 100644 index 000000000..dbc3dbf64 --- /dev/null +++ b/src/core/hle/service/ssl/ssl_types.h | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | |||
| 8 | namespace Service::SSL { | ||
| 9 | |||
| 10 | enum class CaCertificateId : s32 { | ||
| 11 | All = -1, | ||
| 12 | NintendoCAG3 = 1, | ||
| 13 | NintendoClass2CAG3 = 2, | ||
| 14 | NintendoRootCAG4 = 3, | ||
| 15 | AmazonRootCA1 = 1000, | ||
| 16 | StarfieldServicesRootCertificateAuthorityG2 = 1001, | ||
| 17 | AddTrustExternalCARoot = 1002, | ||
| 18 | COMODOCertificationAuthority = 1003, | ||
| 19 | UTNDATACorpSGC = 1004, | ||
| 20 | UTNUSERFirstHardware = 1005, | ||
| 21 | BaltimoreCyberTrustRoot = 1006, | ||
| 22 | CybertrustGlobalRoot = 1007, | ||
| 23 | VerizonGlobalRootCA = 1008, | ||
| 24 | DigiCertAssuredIDRootCA = 1009, | ||
| 25 | DigiCertAssuredIDRootG2 = 1010, | ||
| 26 | DigiCertGlobalRootCA = 1011, | ||
| 27 | DigiCertGlobalRootG2 = 1012, | ||
| 28 | DigiCertHighAssuranceEVRootCA = 1013, | ||
| 29 | EntrustnetCertificationAuthority2048 = 1014, | ||
| 30 | EntrustRootCertificationAuthority = 1015, | ||
| 31 | EntrustRootCertificationAuthorityG2 = 1016, | ||
| 32 | GeoTrustGlobalCA2 = 1017, | ||
| 33 | GeoTrustGlobalCA = 1018, | ||
| 34 | GeoTrustPrimaryCertificationAuthorityG3 = 1019, | ||
| 35 | GeoTrustPrimaryCertificationAuthority = 1020, | ||
| 36 | GlobalSignRootCA = 1021, | ||
| 37 | GlobalSignRootCAR2 = 1022, | ||
| 38 | GlobalSignRootCAR3 = 1023, | ||
| 39 | GoDaddyClass2CertificationAuthority = 1024, | ||
| 40 | GoDaddyRootCertificateAuthorityG2 = 1025, | ||
| 41 | StarfieldClass2CertificationAuthority = 1026, | ||
| 42 | StarfieldRootCertificateAuthorityG2 = 1027, | ||
| 43 | thawtePrimaryRootCAG3 = 1028, | ||
| 44 | thawtePrimaryRootCA = 1029, | ||
| 45 | VeriSignClass3PublicPrimaryCertificationAuthorityG3 = 1030, | ||
| 46 | VeriSignClass3PublicPrimaryCertificationAuthorityG5 = 1031, | ||
| 47 | VeriSignUniversalRootCertificationAuthority = 1032, | ||
| 48 | DSTRootCAX3 = 1033, | ||
| 49 | USERTrustRsaCertificationAuthority = 1034, | ||
| 50 | ISRGRootX10 = 1035, | ||
| 51 | USERTrustEccCertificationAuthority = 1036, | ||
| 52 | COMODORsaCertificationAuthority = 1037, | ||
| 53 | COMODOEccCertificationAuthority = 1038, | ||
| 54 | AmazonRootCA2 = 1039, | ||
| 55 | AmazonRootCA3 = 1040, | ||
| 56 | AmazonRootCA4 = 1041, | ||
| 57 | DigiCertAssuredIDRootG3 = 1042, | ||
| 58 | DigiCertGlobalRootG3 = 1043, | ||
| 59 | DigiCertTrustedRootG4 = 1044, | ||
| 60 | EntrustRootCertificationAuthorityEC1 = 1045, | ||
| 61 | EntrustRootCertificationAuthorityG4 = 1046, | ||
| 62 | GlobalSignECCRootCAR4 = 1047, | ||
| 63 | GlobalSignECCRootCAR5 = 1048, | ||
| 64 | GlobalSignECCRootCAR6 = 1049, | ||
| 65 | GTSRootR1 = 1050, | ||
| 66 | GTSRootR2 = 1051, | ||
| 67 | GTSRootR3 = 1052, | ||
| 68 | GTSRootR4 = 1053, | ||
| 69 | SecurityCommunicationRootCA = 1054, | ||
| 70 | GlobalSignRootE4 = 1055, | ||
| 71 | GlobalSignRootR4 = 1056, | ||
| 72 | TTeleSecGlobalRootClass2 = 1057, | ||
| 73 | DigiCertTLSECCP384RootG5 = 1058, | ||
| 74 | DigiCertTLSRSA4096RootG5 = 1059, | ||
| 75 | }; | ||
| 76 | |||
| 77 | enum class TrustedCertStatus : s32 { | ||
| 78 | Invalid = -1, | ||
| 79 | Removed = 0, | ||
| 80 | EnabledTrusted = 1, | ||
| 81 | EnabledNotTrusted = 2, | ||
| 82 | Revoked = 3, | ||
| 83 | }; | ||
| 84 | |||
| 85 | struct BuiltInCertificateInfo { | ||
| 86 | CaCertificateId cert_id; | ||
| 87 | TrustedCertStatus status; | ||
| 88 | u64 der_size; | ||
| 89 | u64 der_offset; | ||
| 90 | }; | ||
| 91 | static_assert(sizeof(BuiltInCertificateInfo) == 0x18, "BuiltInCertificateInfo has incorrect size."); | ||
| 92 | |||
| 93 | struct CertStoreHeader { | ||
| 94 | u32 magic; | ||
| 95 | u32 num_entries; | ||
| 96 | }; | ||
| 97 | static_assert(sizeof(CertStoreHeader) == 0x8, "CertStoreHeader has incorrect size."); | ||
| 98 | |||
| 99 | struct CertStoreEntry { | ||
| 100 | CaCertificateId certificate_id; | ||
| 101 | TrustedCertStatus certificate_status; | ||
| 102 | u32 der_size; | ||
| 103 | u32 der_offset; | ||
| 104 | }; | ||
| 105 | static_assert(sizeof(CertStoreEntry) == 0x10, "CertStoreEntry has incorrect size."); | ||
| 106 | |||
| 107 | } // namespace Service::SSL | ||