summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar liamwhite2024-02-23 11:34:29 -0500
committerGravatar GitHub2024-02-23 11:34:29 -0500
commitfa4dec9fe9ff67b0a4f73953b18f0cd7e1698bd5 (patch)
tree04d960417c9c4aef9108b8640ebf4e82fc3f28a1 /src/core/hle
parentMerge pull request #13100 from liamwhite/audio-ipc (diff)
parentpctl: rewrite IParentalControlService (diff)
downloadyuzu-fa4dec9fe9ff67b0a4f73953b18f0cd7e1698bd5.tar.gz
yuzu-fa4dec9fe9ff67b0a4f73953b18f0cd7e1698bd5.tar.xz
yuzu-fa4dec9fe9ff67b0a4f73953b18f0cd7e1698bd5.zip
Merge pull request #13115 from liamwhite/olsc-pctl
olsc, pctl: move to new ipc
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/olsc/daemon_controller.cpp40
-rw-r--r--src/core/hle/service/olsc/daemon_controller.h20
-rw-r--r--src/core/hle/service/olsc/native_handle_holder.cpp28
-rw-r--r--src/core/hle/service/olsc/native_handle_holder.h22
-rw-r--r--src/core/hle/service/olsc/olsc.cpp223
-rw-r--r--src/core/hle/service/olsc/olsc_service_for_application.cpp63
-rw-r--r--src/core/hle/service/olsc/olsc_service_for_application.h23
-rw-r--r--src/core/hle/service/olsc/olsc_service_for_system_service.cpp117
-rw-r--r--src/core/hle/service/olsc/olsc_service_for_system_service.h27
-rw-r--r--src/core/hle/service/olsc/remote_storage_controller.cpp54
-rw-r--r--src/core/hle/service/olsc/remote_storage_controller.h19
-rw-r--r--src/core/hle/service/olsc/transfer_task_list_controller.cpp55
-rw-r--r--src/core/hle/service/olsc/transfer_task_list_controller.h20
-rw-r--r--src/core/hle/service/pctl/parental_control_service.cpp434
-rw-r--r--src/core/hle/service/pctl/parental_control_service.h86
-rw-r--r--src/core/hle/service/pctl/parental_control_service_factory.cpp40
-rw-r--r--src/core/hle/service/pctl/parental_control_service_factory.h31
-rw-r--r--src/core/hle/service/pctl/pctl.cpp27
-rw-r--r--src/core/hle/service/pctl/pctl.h9
-rw-r--r--src/core/hle/service/pctl/pctl_module.cpp550
-rw-r--r--src/core/hle/service/pctl/pctl_module.h47
-rw-r--r--src/core/hle/service/pctl/pctl_results.h15
-rw-r--r--src/core/hle/service/pctl/pctl_types.h43
-rw-r--r--src/core/hle/service/services.cpp2
24 files changed, 1169 insertions, 826 deletions
diff --git a/src/core/hle/service/olsc/daemon_controller.cpp b/src/core/hle/service/olsc/daemon_controller.cpp
new file mode 100644
index 000000000..7823780a8
--- /dev/null
+++ b/src/core/hle/service/olsc/daemon_controller.cpp
@@ -0,0 +1,40 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/daemon_controller.h"
6
7namespace Service::OLSC {
8
9IDaemonController::IDaemonController(Core::System& system_)
10 : ServiceFramework{system_, "IDaemonController"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&IDaemonController::GetAutoTransferEnabledForAccountAndApplication>, "GetAutoTransferEnabledForAccountAndApplication"},
14 {1, nullptr, "SetAutoTransferEnabledForAccountAndApplication"},
15 {2, nullptr, "GetGlobalUploadEnabledForAccount"},
16 {3, nullptr, "SetGlobalUploadEnabledForAccount"},
17 {4, nullptr, "TouchAccount"},
18 {5, nullptr, "GetGlobalDownloadEnabledForAccount"},
19 {6, nullptr, "SetGlobalDownloadEnabledForAccount"},
20 {10, nullptr, "GetForbiddenSaveDataIndication"},
21 {11, nullptr, "GetStopperObject"},
22 {12, nullptr, "GetState"},
23 };
24 // clang-format on
25
26 RegisterHandlers(functions);
27}
28
29IDaemonController::~IDaemonController() = default;
30
31Result IDaemonController::GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
32 Common::UUID user_id,
33 u64 application_id) {
34 LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={} application_id={:016X}",
35 user_id.FormattedString(), application_id);
36 *out_is_enabled = false;
37 R_SUCCEED();
38}
39
40} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/daemon_controller.h b/src/core/hle/service/olsc/daemon_controller.h
new file mode 100644
index 000000000..dfad7f52a
--- /dev/null
+++ b/src/core/hle/service/olsc/daemon_controller.h
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/uuid.h"
5#include "core/hle/service/cmif_types.h"
6#include "core/hle/service/service.h"
7
8namespace Service::OLSC {
9
10class IDaemonController final : public ServiceFramework<IDaemonController> {
11public:
12 explicit IDaemonController(Core::System& system_);
13 ~IDaemonController() override;
14
15private:
16 Result GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
17 Common::UUID user_id, u64 application_id);
18};
19
20} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/native_handle_holder.cpp b/src/core/hle/service/olsc/native_handle_holder.cpp
new file mode 100644
index 000000000..3cb5d7b11
--- /dev/null
+++ b/src/core/hle/service/olsc/native_handle_holder.cpp
@@ -0,0 +1,28 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/native_handle_holder.h"
6
7namespace Service::OLSC {
8
9INativeHandleHolder::INativeHandleHolder(Core::System& system_)
10 : ServiceFramework{system_, "INativeHandleHolder"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&INativeHandleHolder::GetNativeHandle>, "GetNativeHandle"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20INativeHandleHolder::~INativeHandleHolder() = default;
21
22Result INativeHandleHolder::GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
23 LOG_WARNING(Service_OLSC, "(STUBBED) called");
24 *out_event = nullptr;
25 R_SUCCEED();
26}
27
28} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/native_handle_holder.h b/src/core/hle/service/olsc/native_handle_holder.h
new file mode 100644
index 000000000..a44754c20
--- /dev/null
+++ b/src/core/hle/service/olsc/native_handle_holder.h
@@ -0,0 +1,22 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Kernel {
8class KReadableEvent;
9}
10
11namespace Service::OLSC {
12
13class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> {
14public:
15 explicit INativeHandleHolder(Core::System& system_);
16 ~INativeHandleHolder() override;
17
18private:
19 Result GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
20};
21
22} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
index 889f27c31..18e5ad43f 100644
--- a/src/core/hle/service/olsc/olsc.cpp
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -1,226 +1,27 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/ipc_helpers.h"
5#include "core/hle/service/olsc/olsc.h" 4#include "core/hle/service/olsc/olsc.h"
5#include "core/hle/service/olsc/olsc_service_for_application.h"
6#include "core/hle/service/olsc/olsc_service_for_system_service.h"
6#include "core/hle/service/server_manager.h" 7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
9namespace Service::OLSC { 10namespace Service::OLSC {
10 11
11class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> {
12public:
13 explicit IOlscServiceForApplication(Core::System& system_)
14 : ServiceFramework{system_, "olsc:u"} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, &IOlscServiceForApplication::Initialize, "Initialize"},
18 {10, nullptr, "VerifySaveDataBackupLicenseAsync"},
19 {13, &IOlscServiceForApplication::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"},
20 {14, &IOlscServiceForApplication::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"},
21 {15, nullptr, "SetCustomData"},
22 {16, nullptr, "DeleteSaveDataBackupSetting"},
23 {18, nullptr, "GetSaveDataBackupInfoCache"},
24 {19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"},
25 {22, nullptr, "DeleteSaveDataBackupAsync"},
26 {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
27 {26, nullptr, "DownloadSaveDataBackupAsync"},
28 {27, nullptr, "UploadSaveDataBackupAsync"},
29 {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
30 {9013, nullptr, "GetSaveDataBackupSettingForDebug"},
31 {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
32 {9015, nullptr, "SetCustomDataForDebug"},
33 {9016, nullptr, "DeleteSaveDataBackupSettingForDebug"},
34 {9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"},
35 {9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"},
36 {9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"},
37 {9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"},
38 {9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"},
39 };
40 // clang-format on
41
42 RegisterHandlers(functions);
43 }
44
45private:
46 void Initialize(HLERequestContext& ctx) {
47 LOG_WARNING(Service_OLSC, "(STUBBED) called");
48
49 initialized = true;
50
51 IPC::ResponseBuilder rb{ctx, 2};
52 rb.Push(ResultSuccess);
53 }
54
55 void GetSaveDataBackupSetting(HLERequestContext& ctx) {
56 LOG_WARNING(Service_OLSC, "(STUBBED) called");
57
58 // backup_setting is set to 0 since real value is unknown
59 constexpr u64 backup_setting = 0;
60
61 IPC::ResponseBuilder rb{ctx, 4};
62 rb.Push(ResultSuccess);
63 rb.Push(backup_setting);
64 }
65
66 void SetSaveDataBackupSettingEnabled(HLERequestContext& ctx) {
67 LOG_WARNING(Service_OLSC, "(STUBBED) called");
68
69 IPC::ResponseBuilder rb{ctx, 2};
70 rb.Push(ResultSuccess);
71 }
72
73 bool initialized{};
74};
75
76class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> {
77public:
78 explicit INativeHandleHolder(Core::System& system_)
79 : ServiceFramework{system_, "INativeHandleHolder"} {
80 // clang-format off
81 static const FunctionInfo functions[] = {
82 {0, nullptr, "GetNativeHandle"},
83 };
84 // clang-format on
85
86 RegisterHandlers(functions);
87 }
88};
89
90class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
91public:
92 explicit ITransferTaskListController(Core::System& system_)
93 : ServiceFramework{system_, "ITransferTaskListController"} {
94 // clang-format off
95 static const FunctionInfo functions[] = {
96 {0, nullptr, "Unknown0"},
97 {1, nullptr, "Unknown1"},
98 {2, nullptr, "Unknown2"},
99 {3, nullptr, "Unknown3"},
100 {4, nullptr, "Unknown4"},
101 {5, &ITransferTaskListController::GetNativeHandleHolder , "GetNativeHandleHolder"},
102 {6, nullptr, "Unknown6"},
103 {7, nullptr, "Unknown7"},
104 {8, nullptr, "GetRemoteStorageController"},
105 {9, &ITransferTaskListController::GetNativeHandleHolder, "GetNativeHandleHolder2"},
106 {10, nullptr, "Unknown10"},
107 {11, nullptr, "Unknown11"},
108 {12, nullptr, "Unknown12"},
109 {13, nullptr, "Unknown13"},
110 {14, nullptr, "Unknown14"},
111 {15, nullptr, "Unknown15"},
112 {16, nullptr, "Unknown16"},
113 {17, nullptr, "Unknown17"},
114 {18, nullptr, "Unknown18"},
115 {19, nullptr, "Unknown19"},
116 {20, nullptr, "Unknown20"},
117 {21, nullptr, "Unknown21"},
118 {22, nullptr, "Unknown22"},
119 {23, nullptr, "Unknown23"},
120 {24, nullptr, "Unknown24"},
121 {25, nullptr, "Unknown25"},
122 };
123 // clang-format on
124
125 RegisterHandlers(functions);
126 }
127
128private:
129 void GetNativeHandleHolder(HLERequestContext& ctx) {
130 LOG_INFO(Service_OLSC, "called");
131
132 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
133 rb.Push(ResultSuccess);
134 rb.PushIpcInterface<INativeHandleHolder>(system);
135 }
136};
137
138class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
139public:
140 explicit IOlscServiceForSystemService(Core::System& system_)
141 : ServiceFramework{system_, "olsc:s"} {
142 // clang-format off
143 static const FunctionInfo functions[] = {
144 {0, &IOlscServiceForSystemService::OpenTransferTaskListController, "OpenTransferTaskListController"},
145 {1, nullptr, "OpenRemoteStorageController"},
146 {2, nullptr, "OpenDaemonController"},
147 {10, nullptr, "Unknown10"},
148 {11, nullptr, "Unknown11"},
149 {12, nullptr, "Unknown12"},
150 {13, nullptr, "Unknown13"},
151 {100, nullptr, "ListLastTransferTaskErrorInfo"},
152 {101, nullptr, "GetLastErrorInfoCount"},
153 {102, nullptr, "RemoveLastErrorInfoOld"},
154 {103, nullptr, "GetLastErrorInfo"},
155 {104, nullptr, "GetLastErrorEventHolder"},
156 {105, nullptr, "GetLastTransferTaskErrorInfo"},
157 {200, nullptr, "GetDataTransferPolicyInfo"},
158 {201, nullptr, "RemoveDataTransferPolicyInfo"},
159 {202, nullptr, "UpdateDataTransferPolicyOld"},
160 {203, nullptr, "UpdateDataTransferPolicy"},
161 {204, nullptr, "CleanupDataTransferPolicyInfo"},
162 {205, nullptr, "RequestDataTransferPolicy"},
163 {300, nullptr, "GetAutoTransferSeriesInfo"},
164 {301, nullptr, "UpdateAutoTransferSeriesInfo"},
165 {400, nullptr, "CleanupSaveDataArchiveInfoType1"},
166 {900, nullptr, "CleanupTransferTask"},
167 {902, nullptr, "CleanupSeriesInfoType0"},
168 {903, nullptr, "CleanupSaveDataArchiveInfoType0"},
169 {904, nullptr, "CleanupApplicationAutoTransferSetting"},
170 {905, nullptr, "CleanupErrorHistory"},
171 {906, nullptr, "SetLastError"},
172 {907, nullptr, "AddSaveDataArchiveInfoType0"},
173 {908, nullptr, "RemoveSeriesInfoType0"},
174 {909, nullptr, "GetSeriesInfoType0"},
175 {910, nullptr, "RemoveLastErrorInfo"},
176 {911, nullptr, "CleanupSeriesInfoType1"},
177 {912, nullptr, "RemoveSeriesInfoType1"},
178 {913, nullptr, "GetSeriesInfoType1"},
179 {1000, nullptr, "UpdateIssueOld"},
180 {1010, nullptr, "Unknown1010"},
181 {1011, nullptr, "ListIssueInfoOld"},
182 {1012, nullptr, "GetIssueOld"},
183 {1013, nullptr, "GetIssue2Old"},
184 {1014, nullptr, "GetIssue3Old"},
185 {1020, nullptr, "RepairIssueOld"},
186 {1021, nullptr, "RepairIssueWithUserIdOld"},
187 {1022, nullptr, "RepairIssue2Old"},
188 {1023, nullptr, "RepairIssue3Old"},
189 {1024, nullptr, "Unknown1024"},
190 {1100, nullptr, "UpdateIssue"},
191 {1110, nullptr, "Unknown1110"},
192 {1111, nullptr, "ListIssueInfo"},
193 {1112, nullptr, "GetIssue"},
194 {1113, nullptr, "GetIssue2"},
195 {1114, nullptr, "GetIssue3"},
196 {1120, nullptr, "RepairIssue"},
197 {1121, nullptr, "RepairIssueWithUserId"},
198 {1122, nullptr, "RepairIssue2"},
199 {1123, nullptr, "RepairIssue3"},
200 {1124, nullptr, "Unknown1124"},
201 };
202 // clang-format on
203
204 RegisterHandlers(functions);
205 }
206
207private:
208 void OpenTransferTaskListController(HLERequestContext& ctx) {
209 LOG_INFO(Service_OLSC, "called");
210
211 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
212 rb.Push(ResultSuccess);
213 rb.PushIpcInterface<ITransferTaskListController>(system);
214 }
215};
216
217void LoopProcess(Core::System& system) { 12void LoopProcess(Core::System& system) {
218 auto server_manager = std::make_unique<ServerManager>(system); 13 auto server_manager = std::make_unique<ServerManager>(system);
219 14
220 server_manager->RegisterNamedService("olsc:u", 15 const auto OlscFactoryForApplication = [&] {
221 std::make_shared<IOlscServiceForApplication>(system)); 16 return std::make_shared<IOlscServiceForApplication>(system);
222 server_manager->RegisterNamedService("olsc:s", 17 };
223 std::make_shared<IOlscServiceForSystemService>(system)); 18
19 const auto OlscFactoryForSystemService = [&] {
20 return std::make_shared<IOlscServiceForSystemService>(system);
21 };
22
23 server_manager->RegisterNamedService("olsc:u", OlscFactoryForApplication);
24 server_manager->RegisterNamedService("olsc:s", OlscFactoryForSystemService);
224 25
225 ServerManager::RunServer(std::move(server_manager)); 26 ServerManager::RunServer(std::move(server_manager));
226} 27}
diff --git a/src/core/hle/service/olsc/olsc_service_for_application.cpp b/src/core/hle/service/olsc/olsc_service_for_application.cpp
new file mode 100644
index 000000000..01360f5ef
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_application.cpp
@@ -0,0 +1,63 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/olsc_service_for_application.h"
6
7namespace Service::OLSC {
8
9IOlscServiceForApplication::IOlscServiceForApplication(Core::System& system_)
10 : ServiceFramework{system_, "olsc:u"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&IOlscServiceForApplication::Initialize>, "Initialize"},
14 {10, nullptr, "VerifySaveDataBackupLicenseAsync"},
15 {13, D<&IOlscServiceForApplication::GetSaveDataBackupSetting>, "GetSaveDataBackupSetting"},
16 {14, D<&IOlscServiceForApplication::SetSaveDataBackupSettingEnabled>, "SetSaveDataBackupSettingEnabled"},
17 {15, nullptr, "SetCustomData"},
18 {16, nullptr, "DeleteSaveDataBackupSetting"},
19 {18, nullptr, "GetSaveDataBackupInfoCache"},
20 {19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"},
21 {22, nullptr, "DeleteSaveDataBackupAsync"},
22 {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
23 {26, nullptr, "DownloadSaveDataBackupAsync"},
24 {27, nullptr, "UploadSaveDataBackupAsync"},
25 {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
26 {9013, nullptr, "GetSaveDataBackupSettingForDebug"},
27 {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
28 {9015, nullptr, "SetCustomDataForDebug"},
29 {9016, nullptr, "DeleteSaveDataBackupSettingForDebug"},
30 {9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"},
31 {9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"},
32 {9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"},
33 {9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"},
34 {9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"},
35 };
36 // clang-format on
37
38 RegisterHandlers(functions);
39}
40
41IOlscServiceForApplication::~IOlscServiceForApplication() = default;
42
43Result IOlscServiceForApplication::Initialize(ClientProcessId process_id) {
44 LOG_WARNING(Service_OLSC, "(STUBBED) called");
45 initialized = true;
46 R_SUCCEED();
47}
48
49Result IOlscServiceForApplication::GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting) {
50 LOG_WARNING(Service_OLSC, "(STUBBED) called");
51 // backup_setting is set to 0 since real value is unknown
52 *out_save_data_backup_setting = 0;
53 R_SUCCEED();
54}
55
56Result IOlscServiceForApplication::SetSaveDataBackupSettingEnabled(bool enabled,
57 NS::Uid account_id) {
58 LOG_WARNING(Service_OLSC, "(STUBBED) called, enabled={}, account_id={}", enabled,
59 account_id.uuid.FormattedString());
60 R_SUCCEED();
61}
62
63} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc_service_for_application.h b/src/core/hle/service/olsc/olsc_service_for_application.h
new file mode 100644
index 000000000..3f9ac7536
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_application.h
@@ -0,0 +1,23 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/ns/ns_types.h"
6#include "core/hle/service/service.h"
7
8namespace Service::OLSC {
9
10class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> {
11public:
12 explicit IOlscServiceForApplication(Core::System& system_);
13 ~IOlscServiceForApplication() override;
14
15private:
16 Result Initialize(ClientProcessId process_id);
17 Result GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting);
18 Result SetSaveDataBackupSettingEnabled(bool enabled, NS::Uid account_id);
19
20 bool initialized{};
21};
22
23} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc_service_for_system_service.cpp b/src/core/hle/service/olsc/olsc_service_for_system_service.cpp
new file mode 100644
index 000000000..f027933c9
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_system_service.cpp
@@ -0,0 +1,117 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/daemon_controller.h"
6#include "core/hle/service/olsc/olsc_service_for_system_service.h"
7#include "core/hle/service/olsc/remote_storage_controller.h"
8#include "core/hle/service/olsc/transfer_task_list_controller.h"
9
10namespace Service::OLSC {
11
12IOlscServiceForSystemService::IOlscServiceForSystemService(Core::System& system_)
13 : ServiceFramework{system_, "olsc:s"} {
14 // clang-format off
15 static const FunctionInfo functions[] = {
16 {0, D<&IOlscServiceForSystemService::OpenTransferTaskListController>, "OpenTransferTaskListController"},
17 {1, D<&IOlscServiceForSystemService::OpenRemoteStorageController>, "OpenRemoteStorageController"},
18 {2, D<&IOlscServiceForSystemService::OpenDaemonController>, "OpenDaemonController"},
19 {10, nullptr, "Unknown10"},
20 {11, nullptr, "Unknown11"},
21 {12, nullptr, "Unknown12"},
22 {13, nullptr, "Unknown13"},
23 {100, nullptr, "ListLastTransferTaskErrorInfo"},
24 {101, nullptr, "GetLastErrorInfoCount"},
25 {102, nullptr, "RemoveLastErrorInfoOld"},
26 {103, nullptr, "GetLastErrorInfo"},
27 {104, nullptr, "GetLastErrorEventHolder"},
28 {105, nullptr, "GetLastTransferTaskErrorInfo"},
29 {200, D<&IOlscServiceForSystemService::GetDataTransferPolicyInfo>, "GetDataTransferPolicyInfo"},
30 {201, nullptr, "RemoveDataTransferPolicyInfo"},
31 {202, nullptr, "UpdateDataTransferPolicyOld"},
32 {203, nullptr, "UpdateDataTransferPolicy"},
33 {204, nullptr, "CleanupDataTransferPolicyInfo"},
34 {205, nullptr, "RequestDataTransferPolicy"},
35 {300, nullptr, "GetAutoTransferSeriesInfo"},
36 {301, nullptr, "UpdateAutoTransferSeriesInfo"},
37 {400, nullptr, "CleanupSaveDataArchiveInfoType1"},
38 {900, nullptr, "CleanupTransferTask"},
39 {902, nullptr, "CleanupSeriesInfoType0"},
40 {903, nullptr, "CleanupSaveDataArchiveInfoType0"},
41 {904, nullptr, "CleanupApplicationAutoTransferSetting"},
42 {905, nullptr, "CleanupErrorHistory"},
43 {906, nullptr, "SetLastError"},
44 {907, nullptr, "AddSaveDataArchiveInfoType0"},
45 {908, nullptr, "RemoveSeriesInfoType0"},
46 {909, nullptr, "GetSeriesInfoType0"},
47 {910, nullptr, "RemoveLastErrorInfo"},
48 {911, nullptr, "CleanupSeriesInfoType1"},
49 {912, nullptr, "RemoveSeriesInfoType1"},
50 {913, nullptr, "GetSeriesInfoType1"},
51 {1000, nullptr, "UpdateIssueOld"},
52 {1010, nullptr, "Unknown1010"},
53 {1011, nullptr, "ListIssueInfoOld"},
54 {1012, nullptr, "GetIssueOld"},
55 {1013, nullptr, "GetIssue2Old"},
56 {1014, nullptr, "GetIssue3Old"},
57 {1020, nullptr, "RepairIssueOld"},
58 {1021, nullptr, "RepairIssueWithUserIdOld"},
59 {1022, nullptr, "RepairIssue2Old"},
60 {1023, nullptr, "RepairIssue3Old"},
61 {1024, nullptr, "Unknown1024"},
62 {1100, nullptr, "UpdateIssue"},
63 {1110, nullptr, "Unknown1110"},
64 {1111, nullptr, "ListIssueInfo"},
65 {1112, nullptr, "GetIssue"},
66 {1113, nullptr, "GetIssue2"},
67 {1114, nullptr, "GetIssue3"},
68 {1120, nullptr, "RepairIssue"},
69 {1121, nullptr, "RepairIssueWithUserId"},
70 {1122, nullptr, "RepairIssue2"},
71 {1123, nullptr, "RepairIssue3"},
72 {1124, nullptr, "Unknown1124"},
73 {10000, D<&IOlscServiceForSystemService::CloneService>, "CloneService"},
74 };
75 // clang-format on
76
77 RegisterHandlers(functions);
78}
79
80IOlscServiceForSystemService::~IOlscServiceForSystemService() = default;
81
82Result IOlscServiceForSystemService::OpenTransferTaskListController(
83 Out<SharedPointer<ITransferTaskListController>> out_interface) {
84 LOG_INFO(Service_OLSC, "called");
85 *out_interface = std::make_shared<ITransferTaskListController>(system);
86 R_SUCCEED();
87}
88
89Result IOlscServiceForSystemService::OpenRemoteStorageController(
90 Out<SharedPointer<IRemoteStorageController>> out_interface) {
91 LOG_INFO(Service_OLSC, "called");
92 *out_interface = std::make_shared<IRemoteStorageController>(system);
93 R_SUCCEED();
94}
95
96Result IOlscServiceForSystemService::OpenDaemonController(
97 Out<SharedPointer<IDaemonController>> out_interface) {
98 LOG_INFO(Service_OLSC, "called");
99 *out_interface = std::make_shared<IDaemonController>(system);
100 R_SUCCEED();
101}
102
103Result IOlscServiceForSystemService::GetDataTransferPolicyInfo(Out<u16> out_policy_info,
104 u64 application_id) {
105 LOG_WARNING(Service_OLSC, "(STUBBED) called");
106 *out_policy_info = 0;
107 R_SUCCEED();
108}
109
110Result IOlscServiceForSystemService::CloneService(
111 Out<SharedPointer<IOlscServiceForSystemService>> out_interface) {
112 LOG_INFO(Service_OLSC, "called");
113 *out_interface = std::static_pointer_cast<IOlscServiceForSystemService>(shared_from_this());
114 R_SUCCEED();
115}
116
117} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc_service_for_system_service.h b/src/core/hle/service/olsc/olsc_service_for_system_service.h
new file mode 100644
index 000000000..13026272a
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_system_service.h
@@ -0,0 +1,27 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Service::OLSC {
8
9class IDaemonController;
10class IRemoteStorageController;
11class ITransferTaskListController;
12
13class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
14public:
15 explicit IOlscServiceForSystemService(Core::System& system_);
16 ~IOlscServiceForSystemService() override;
17
18private:
19 Result OpenTransferTaskListController(
20 Out<SharedPointer<ITransferTaskListController>> out_interface);
21 Result OpenRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_interface);
22 Result OpenDaemonController(Out<SharedPointer<IDaemonController>> out_interface);
23 Result GetDataTransferPolicyInfo(Out<u16> out_policy_info, u64 application_id);
24 Result CloneService(Out<SharedPointer<IOlscServiceForSystemService>> out_interface);
25};
26
27} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/remote_storage_controller.cpp b/src/core/hle/service/olsc/remote_storage_controller.cpp
new file mode 100644
index 000000000..81d9c96ab
--- /dev/null
+++ b/src/core/hle/service/olsc/remote_storage_controller.cpp
@@ -0,0 +1,54 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/remote_storage_controller.h"
6
7namespace Service::OLSC {
8
9IRemoteStorageController::IRemoteStorageController(Core::System& system_)
10 : ServiceFramework{system_, "IRemoteStorageController"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, nullptr, "GetSaveDataArchiveInfoBySaveDataId"},
14 {1, nullptr, "GetSaveDataArchiveInfoByApplicationId"},
15 {3, nullptr, "GetSaveDataArchiveCount"},
16 {6, nullptr, "CleanupSaveDataArchives"},
17 {7, nullptr, "CreateSaveDataArchiveCacheUpdationTask"},
18 {8, nullptr, "CreateSaveDataArchiveCacheUpdationForSpecifiedApplicationTask"},
19 {9, nullptr, "Delete"},
20 {10, nullptr, "GetSeriesInfo"},
21 {11, nullptr, "CreateDeleteDataTask"},
22 {12, nullptr, "DeleteSeriesInfo"},
23 {13, nullptr, "CreateRegisterNotificationTokenTask"},
24 {14, nullptr, "UpdateSeriesInfo"},
25 {15, nullptr, "RegisterUploadSaveDataTransferTaskForAutonomyRegistration"},
26 {16, nullptr, "CreateCleanupToDeleteSaveDataArchiveInfoTask"},
27 {17, nullptr, "ListDataInfo"},
28 {18, nullptr, "GetDataInfo"},
29 {19, nullptr, "Unknown19"},
30 {20, nullptr, "CreateSaveDataArchiveInfoCacheForSaveDataBackupUpdationTask"},
31 {21, nullptr, "ListSecondarySaves"},
32 {22, D<&IRemoteStorageController::GetSecondarySave>, "GetSecondarySave"},
33 {23, nullptr, "TouchSecondarySave"},
34 {24, nullptr, "GetSecondarySaveDataInfo"},
35 {25, nullptr, "RegisterDownloadSaveDataTransferTaskForAutonomyRegistration"},
36 {900, nullptr, "Unknown900"},
37 };
38 // clang-format on
39
40 RegisterHandlers(functions);
41}
42
43IRemoteStorageController::~IRemoteStorageController() = default;
44
45Result IRemoteStorageController::GetSecondarySave(Out<bool> out_has_secondary_save,
46 Out<std::array<u64, 3>> out_unknown,
47 u64 application_id) {
48 LOG_ERROR(Service_OLSC, "(STUBBED) called, application_id={:016X}", application_id);
49 *out_has_secondary_save = false;
50 *out_unknown = {};
51 R_SUCCEED();
52}
53
54} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/remote_storage_controller.h b/src/core/hle/service/olsc/remote_storage_controller.h
new file mode 100644
index 000000000..e7a0b5244
--- /dev/null
+++ b/src/core/hle/service/olsc/remote_storage_controller.h
@@ -0,0 +1,19 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Service::OLSC {
8
9class IRemoteStorageController final : public ServiceFramework<IRemoteStorageController> {
10public:
11 explicit IRemoteStorageController(Core::System& system_);
12 ~IRemoteStorageController() override;
13
14private:
15 Result GetSecondarySave(Out<bool> out_has_secondary_save, Out<std::array<u64, 3>> out_unknown,
16 u64 application_id);
17};
18
19} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/transfer_task_list_controller.cpp b/src/core/hle/service/olsc/transfer_task_list_controller.cpp
new file mode 100644
index 000000000..8ea9a0f1e
--- /dev/null
+++ b/src/core/hle/service/olsc/transfer_task_list_controller.cpp
@@ -0,0 +1,55 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/native_handle_holder.h"
6#include "core/hle/service/olsc/transfer_task_list_controller.h"
7
8namespace Service::OLSC {
9
10ITransferTaskListController::ITransferTaskListController(Core::System& system_)
11 : ServiceFramework{system_, "ITransferTaskListController"} {
12 // clang-format off
13 static const FunctionInfo functions[] = {
14 {0, nullptr, "Unknown0"},
15 {1, nullptr, "Unknown1"},
16 {2, nullptr, "Unknown2"},
17 {3, nullptr, "Unknown3"},
18 {4, nullptr, "Unknown4"},
19 {5, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder"},
20 {6, nullptr, "Unknown6"},
21 {7, nullptr, "Unknown7"},
22 {8, nullptr, "GetRemoteStorageController"},
23 {9, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder2"},
24 {10, nullptr, "Unknown10"},
25 {11, nullptr, "Unknown11"},
26 {12, nullptr, "Unknown12"},
27 {13, nullptr, "Unknown13"},
28 {14, nullptr, "Unknown14"},
29 {15, nullptr, "Unknown15"},
30 {16, nullptr, "Unknown16"},
31 {17, nullptr, "Unknown17"},
32 {18, nullptr, "Unknown18"},
33 {19, nullptr, "Unknown19"},
34 {20, nullptr, "Unknown20"},
35 {21, nullptr, "Unknown21"},
36 {22, nullptr, "Unknown22"},
37 {23, nullptr, "Unknown23"},
38 {24, nullptr, "Unknown24"},
39 {25, nullptr, "Unknown25"},
40 };
41 // clang-format on
42
43 RegisterHandlers(functions);
44}
45
46ITransferTaskListController::~ITransferTaskListController() = default;
47
48Result ITransferTaskListController::GetNativeHandleHolder(
49 Out<SharedPointer<INativeHandleHolder>> out_holder) {
50 LOG_WARNING(Service_OLSC, "(STUBBED) called");
51 *out_holder = std::make_shared<INativeHandleHolder>(system);
52 R_SUCCEED();
53}
54
55} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/transfer_task_list_controller.h b/src/core/hle/service/olsc/transfer_task_list_controller.h
new file mode 100644
index 000000000..f10a71375
--- /dev/null
+++ b/src/core/hle/service/olsc/transfer_task_list_controller.h
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Service::OLSC {
8
9class INativeHandleHolder;
10
11class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
12public:
13 explicit ITransferTaskListController(Core::System& system_);
14 ~ITransferTaskListController() override;
15
16private:
17 Result GetNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder);
18};
19
20} // namespace Service::OLSC
diff --git a/src/core/hle/service/pctl/parental_control_service.cpp b/src/core/hle/service/pctl/parental_control_service.cpp
new file mode 100644
index 000000000..f57f2f157
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service.cpp
@@ -0,0 +1,434 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/core.h"
5#include "core/file_sys/control_metadata.h"
6#include "core/file_sys/patch_manager.h"
7#include "core/hle/service/cmif_serialization.h"
8#include "core/hle/service/pctl/parental_control_service.h"
9#include "core/hle/service/pctl/pctl_results.h"
10
11namespace Service::PCTL {
12
13IParentalControlService::IParentalControlService(Core::System& system_, Capability capability_)
14 : ServiceFramework{system_, "IParentalControlService"}, capability{capability_},
15 service_context{system_, "IParentalControlService"}, synchronization_event{service_context},
16 unlinked_event{service_context}, request_suspension_event{service_context} {
17 // clang-format off
18 static const FunctionInfo functions[] = {
19 {1, D<&IParentalControlService::Initialize>, "Initialize"},
20 {1001, D<&IParentalControlService::CheckFreeCommunicationPermission>, "CheckFreeCommunicationPermission"},
21 {1002, D<&IParentalControlService::ConfirmLaunchApplicationPermission>, "ConfirmLaunchApplicationPermission"},
22 {1003, D<&IParentalControlService::ConfirmResumeApplicationPermission>, "ConfirmResumeApplicationPermission"},
23 {1004, D<&IParentalControlService::ConfirmSnsPostPermission>, "ConfirmSnsPostPermission"},
24 {1005, nullptr, "ConfirmSystemSettingsPermission"},
25 {1006, D<&IParentalControlService::IsRestrictionTemporaryUnlocked>, "IsRestrictionTemporaryUnlocked"},
26 {1007, nullptr, "RevertRestrictionTemporaryUnlocked"},
27 {1008, nullptr, "EnterRestrictedSystemSettings"},
28 {1009, nullptr, "LeaveRestrictedSystemSettings"},
29 {1010, D<&IParentalControlService::IsRestrictedSystemSettingsEntered>, "IsRestrictedSystemSettingsEntered"},
30 {1011, nullptr, "RevertRestrictedSystemSettingsEntered"},
31 {1012, nullptr, "GetRestrictedFeatures"},
32 {1013, D<&IParentalControlService::ConfirmStereoVisionPermission>, "ConfirmStereoVisionPermission"},
33 {1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
34 {1015, nullptr, "ConfirmPlayableApplicationVideo"},
35 {1016, nullptr, "ConfirmShowNewsPermission"},
36 {1017, D<&IParentalControlService::EndFreeCommunication>, "EndFreeCommunication"},
37 {1018, D<&IParentalControlService::IsFreeCommunicationAvailable>, "IsFreeCommunicationAvailable"},
38 {1031, D<&IParentalControlService::IsRestrictionEnabled>, "IsRestrictionEnabled"},
39 {1032, D<&IParentalControlService::GetSafetyLevel>, "GetSafetyLevel"},
40 {1033, nullptr, "SetSafetyLevel"},
41 {1034, nullptr, "GetSafetyLevelSettings"},
42 {1035, D<&IParentalControlService::GetCurrentSettings>, "GetCurrentSettings"},
43 {1036, nullptr, "SetCustomSafetyLevelSettings"},
44 {1037, nullptr, "GetDefaultRatingOrganization"},
45 {1038, nullptr, "SetDefaultRatingOrganization"},
46 {1039, D<&IParentalControlService::GetFreeCommunicationApplicationListCount>, "GetFreeCommunicationApplicationListCount"},
47 {1042, nullptr, "AddToFreeCommunicationApplicationList"},
48 {1043, nullptr, "DeleteSettings"},
49 {1044, nullptr, "GetFreeCommunicationApplicationList"},
50 {1045, nullptr, "UpdateFreeCommunicationApplicationList"},
51 {1046, nullptr, "DisableFeaturesForReset"},
52 {1047, nullptr, "NotifyApplicationDownloadStarted"},
53 {1048, nullptr, "NotifyNetworkProfileCreated"},
54 {1049, nullptr, "ResetFreeCommunicationApplicationList"},
55 {1061, D<&IParentalControlService::ConfirmStereoVisionRestrictionConfigurable>, "ConfirmStereoVisionRestrictionConfigurable"},
56 {1062, D<&IParentalControlService::GetStereoVisionRestriction>, "GetStereoVisionRestriction"},
57 {1063, D<&IParentalControlService::SetStereoVisionRestriction>, "SetStereoVisionRestriction"},
58 {1064, D<&IParentalControlService::ResetConfirmedStereoVisionPermission>, "ResetConfirmedStereoVisionPermission"},
59 {1065, D<&IParentalControlService::IsStereoVisionPermitted>, "IsStereoVisionPermitted"},
60 {1201, nullptr, "UnlockRestrictionTemporarily"},
61 {1202, nullptr, "UnlockSystemSettingsRestriction"},
62 {1203, nullptr, "SetPinCode"},
63 {1204, nullptr, "GenerateInquiryCode"},
64 {1205, nullptr, "CheckMasterKey"},
65 {1206, D<&IParentalControlService::GetPinCodeLength>, "GetPinCodeLength"},
66 {1207, nullptr, "GetPinCodeChangedEvent"},
67 {1208, nullptr, "GetPinCode"},
68 {1403, D<&IParentalControlService::IsPairingActive>, "IsPairingActive"},
69 {1406, nullptr, "GetSettingsLastUpdated"},
70 {1411, nullptr, "GetPairingAccountInfo"},
71 {1421, nullptr, "GetAccountNickname"},
72 {1424, nullptr, "GetAccountState"},
73 {1425, nullptr, "RequestPostEvents"},
74 {1426, nullptr, "GetPostEventInterval"},
75 {1427, nullptr, "SetPostEventInterval"},
76 {1432, D<&IParentalControlService::GetSynchronizationEvent>, "GetSynchronizationEvent"},
77 {1451, D<&IParentalControlService::StartPlayTimer>, "StartPlayTimer"},
78 {1452, D<&IParentalControlService::StopPlayTimer>, "StopPlayTimer"},
79 {1453, D<&IParentalControlService::IsPlayTimerEnabled>, "IsPlayTimerEnabled"},
80 {1454, nullptr, "GetPlayTimerRemainingTime"},
81 {1455, D<&IParentalControlService::IsRestrictedByPlayTimer>, "IsRestrictedByPlayTimer"},
82 {1456, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"},
83 {1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"},
84 {1458, D<&IParentalControlService::IsPlayTimerAlarmDisabled>, "IsPlayTimerAlarmDisabled"},
85 {1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
86 {1472, nullptr, "CancelNetworkRequest"},
87 {1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"},
88 {1474, nullptr, "ClearUnlinkedEvent"},
89 {1601, nullptr, "DisableAllFeatures"},
90 {1602, nullptr, "PostEnableAllFeatures"},
91 {1603, nullptr, "IsAllFeaturesDisabled"},
92 {1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"},
93 {1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"},
94 {1903, nullptr, "GetExemptApplicationListCountForDebug"},
95 {1904, nullptr, "GetExemptApplicationListForDebug"},
96 {1905, nullptr, "UpdateExemptApplicationListForDebug"},
97 {1906, nullptr, "AddToExemptApplicationListForDebug"},
98 {1907, nullptr, "DeleteFromExemptApplicationListForDebug"},
99 {1908, nullptr, "ClearExemptApplicationListForDebug"},
100 {1941, nullptr, "DeletePairing"},
101 {1951, nullptr, "SetPlayTimerSettingsForDebug"},
102 {1952, nullptr, "GetPlayTimerSpentTimeForTest"},
103 {1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"},
104 {2001, nullptr, "RequestPairingAsync"},
105 {2002, nullptr, "FinishRequestPairing"},
106 {2003, nullptr, "AuthorizePairingAsync"},
107 {2004, nullptr, "FinishAuthorizePairing"},
108 {2005, nullptr, "RetrievePairingInfoAsync"},
109 {2006, nullptr, "FinishRetrievePairingInfo"},
110 {2007, nullptr, "UnlinkPairingAsync"},
111 {2008, nullptr, "FinishUnlinkPairing"},
112 {2009, nullptr, "GetAccountMiiImageAsync"},
113 {2010, nullptr, "FinishGetAccountMiiImage"},
114 {2011, nullptr, "GetAccountMiiImageContentTypeAsync"},
115 {2012, nullptr, "FinishGetAccountMiiImageContentType"},
116 {2013, nullptr, "SynchronizeParentalControlSettingsAsync"},
117 {2014, nullptr, "FinishSynchronizeParentalControlSettings"},
118 {2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
119 {2016, nullptr, "RequestUpdateExemptionListAsync"},
120 };
121 // clang-format on
122 RegisterHandlers(functions);
123}
124
125IParentalControlService::~IParentalControlService() = default;
126
127bool IParentalControlService::CheckFreeCommunicationPermissionImpl() const {
128 if (states.temporary_unlocked) {
129 return true;
130 }
131 if ((states.application_info.parental_control_flag & 1) == 0) {
132 return true;
133 }
134 if (pin_code[0] == '\0') {
135 return true;
136 }
137 if (!settings.is_free_communication_default_on) {
138 return true;
139 }
140 // TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here
141 // but as we don't have multiproceses support yet, we can just assume our application is
142 // valid for the time being
143 return true;
144}
145
146bool IParentalControlService::ConfirmStereoVisionPermissionImpl() const {
147 if (states.temporary_unlocked) {
148 return true;
149 }
150 if (pin_code[0] == '\0') {
151 return true;
152 }
153 if (!settings.is_stero_vision_restricted) {
154 return false;
155 }
156 return true;
157}
158
159void IParentalControlService::SetStereoVisionRestrictionImpl(bool is_restricted) {
160 if (settings.disabled) {
161 return;
162 }
163
164 if (pin_code[0] == '\0') {
165 return;
166 }
167 settings.is_stero_vision_restricted = is_restricted;
168}
169
170Result IParentalControlService::Initialize() {
171 LOG_DEBUG(Service_PCTL, "called");
172
173 if (False(capability & (Capability::Application | Capability::System))) {
174 LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability);
175 R_THROW(PCTL::ResultNoCapability);
176 }
177
178 // TODO(ogniK): Recovery flag initialization for pctl:r
179
180 const auto program_id = system.GetApplicationProcessProgramID();
181 if (program_id != 0) {
182 const FileSys::PatchManager pm{program_id, system.GetFileSystemController(),
183 system.GetContentProvider()};
184 const auto control = pm.GetControlMetadata();
185 if (control.first) {
186 states.tid_from_event = 0;
187 states.launch_time_valid = false;
188 states.is_suspended = false;
189 states.free_communication = false;
190 states.stereo_vision = false;
191 states.application_info = ApplicationInfo{
192 .application_id = program_id,
193 .age_rating = control.first->GetRatingAge(),
194 .parental_control_flag = control.first->GetParentalControlFlag(),
195 .capability = capability,
196 };
197
198 if (False(capability & (Capability::System | Capability::Recovery))) {
199 // TODO(ogniK): Signal application launch event
200 }
201 }
202 }
203
204 R_SUCCEED();
205}
206
207Result IParentalControlService::CheckFreeCommunicationPermission() {
208 LOG_DEBUG(Service_PCTL, "called");
209
210 if (!CheckFreeCommunicationPermissionImpl()) {
211 R_THROW(PCTL::ResultNoFreeCommunication);
212 } else {
213 states.free_communication = true;
214 R_SUCCEED();
215 }
216}
217
218Result IParentalControlService::ConfirmLaunchApplicationPermission(
219 InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) {
220 LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag,
221 application_id);
222 R_SUCCEED();
223}
224
225Result IParentalControlService::ConfirmResumeApplicationPermission(
226 InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) {
227 LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag,
228 application_id);
229 R_SUCCEED();
230}
231
232Result IParentalControlService::ConfirmSnsPostPermission() {
233 LOG_WARNING(Service_PCTL, "(STUBBED) called");
234 R_THROW(PCTL::ResultNoFreeCommunication);
235}
236
237Result IParentalControlService::IsRestrictionTemporaryUnlocked(
238 Out<bool> out_is_temporary_unlocked) {
239 *out_is_temporary_unlocked = false;
240 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
241 *out_is_temporary_unlocked);
242 R_SUCCEED();
243}
244
245Result IParentalControlService::IsRestrictedSystemSettingsEntered(
246 Out<bool> out_is_restricted_system_settings_entered) {
247 *out_is_restricted_system_settings_entered = false;
248 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
249 *out_is_restricted_system_settings_entered);
250 R_SUCCEED();
251}
252
253Result IParentalControlService::ConfirmStereoVisionPermission() {
254 LOG_DEBUG(Service_PCTL, "called");
255 states.stereo_vision = true;
256 R_SUCCEED();
257}
258
259Result IParentalControlService::EndFreeCommunication() {
260 LOG_WARNING(Service_PCTL, "(STUBBED) called");
261 R_SUCCEED();
262}
263
264Result IParentalControlService::IsFreeCommunicationAvailable() {
265 LOG_WARNING(Service_PCTL, "(STUBBED) called");
266
267 if (!CheckFreeCommunicationPermissionImpl()) {
268 R_THROW(PCTL::ResultNoFreeCommunication);
269 } else {
270 R_SUCCEED();
271 }
272}
273
274Result IParentalControlService::IsRestrictionEnabled(Out<bool> out_restriction_enabled) {
275 LOG_DEBUG(Service_PCTL, "called");
276
277 if (False(capability & (Capability::Status | Capability::Recovery))) {
278 LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!");
279 *out_restriction_enabled = false;
280 R_THROW(PCTL::ResultNoCapability);
281 }
282
283 *out_restriction_enabled = pin_code[0] != '\0';
284 R_SUCCEED();
285}
286
287Result IParentalControlService::GetSafetyLevel(Out<u32> out_safety_level) {
288 *out_safety_level = 0;
289 LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", *out_safety_level);
290 R_SUCCEED();
291}
292
293Result IParentalControlService::GetCurrentSettings(Out<RestrictionSettings> out_settings) {
294 LOG_INFO(Service_PCTL, "called");
295 *out_settings = restriction_settings;
296 R_SUCCEED();
297}
298
299Result IParentalControlService::GetFreeCommunicationApplicationListCount(Out<s32> out_count) {
300 *out_count = 4;
301 LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", *out_count);
302 R_SUCCEED();
303}
304
305Result IParentalControlService::ConfirmStereoVisionRestrictionConfigurable() {
306 LOG_DEBUG(Service_PCTL, "called");
307
308 if (False(capability & Capability::StereoVision)) {
309 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
310 R_THROW(PCTL::ResultNoCapability);
311 }
312
313 if (pin_code[0] == '\0') {
314 R_THROW(PCTL::ResultNoRestrictionEnabled);
315 }
316
317 R_SUCCEED();
318}
319
320Result IParentalControlService::IsStereoVisionPermitted(Out<bool> out_is_permitted) {
321 LOG_DEBUG(Service_PCTL, "called");
322
323 if (!ConfirmStereoVisionPermissionImpl()) {
324 *out_is_permitted = false;
325 R_THROW(PCTL::ResultStereoVisionRestricted);
326 } else {
327 *out_is_permitted = true;
328 R_SUCCEED();
329 }
330}
331
332Result IParentalControlService::GetPinCodeLength(Out<s32> out_length) {
333 *out_length = 0;
334 LOG_WARNING(Service_PCTL, "(STUBBED) called, length={}", *out_length);
335 R_SUCCEED();
336}
337
338Result IParentalControlService::IsPairingActive(Out<bool> out_is_pairing_active) {
339 *out_is_pairing_active = false;
340 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", *out_is_pairing_active);
341 R_SUCCEED();
342}
343
344Result IParentalControlService::GetSynchronizationEvent(
345 OutCopyHandle<Kernel::KReadableEvent> out_event) {
346 LOG_INFO(Service_PCTL, "called");
347 *out_event = synchronization_event.GetHandle();
348 R_SUCCEED();
349}
350
351Result IParentalControlService::StartPlayTimer() {
352 LOG_WARNING(Service_PCTL, "(STUBBED) called");
353 R_SUCCEED();
354}
355
356Result IParentalControlService::StopPlayTimer() {
357 LOG_WARNING(Service_PCTL, "(STUBBED) called");
358 R_SUCCEED();
359}
360
361Result IParentalControlService::IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled) {
362 *out_is_play_timer_enabled = false;
363 LOG_WARNING(Service_PCTL, "(STUBBED) called, enabled={}", *out_is_play_timer_enabled);
364 R_SUCCEED();
365}
366
367Result IParentalControlService::IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer) {
368 *out_is_restricted_by_play_timer = false;
369 LOG_WARNING(Service_PCTL, "(STUBBED) called, restricted={}", *out_is_restricted_by_play_timer);
370 R_SUCCEED();
371}
372
373Result IParentalControlService::GetPlayTimerSettings(
374 Out<PlayTimerSettings> out_play_timer_settings) {
375 LOG_WARNING(Service_PCTL, "(STUBBED) called");
376 *out_play_timer_settings = {};
377 R_SUCCEED();
378}
379
380Result IParentalControlService::GetPlayTimerEventToRequestSuspension(
381 OutCopyHandle<Kernel::KReadableEvent> out_event) {
382 LOG_INFO(Service_PCTL, "called");
383 *out_event = request_suspension_event.GetHandle();
384 R_SUCCEED();
385}
386
387Result IParentalControlService::IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled) {
388 *out_play_timer_alarm_disabled = false;
389 LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}",
390 *out_play_timer_alarm_disabled);
391 R_SUCCEED();
392}
393
394Result IParentalControlService::GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
395 LOG_INFO(Service_PCTL, "called");
396 *out_event = unlinked_event.GetHandle();
397 R_SUCCEED();
398}
399
400Result IParentalControlService::GetStereoVisionRestriction(
401 Out<bool> out_stereo_vision_restriction) {
402 LOG_DEBUG(Service_PCTL, "called");
403
404 if (False(capability & Capability::StereoVision)) {
405 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
406 *out_stereo_vision_restriction = false;
407 R_THROW(PCTL::ResultNoCapability);
408 }
409
410 *out_stereo_vision_restriction = settings.is_stero_vision_restricted;
411 R_SUCCEED();
412}
413
414Result IParentalControlService::SetStereoVisionRestriction(bool stereo_vision_restriction) {
415 LOG_DEBUG(Service_PCTL, "called, can_use={}", stereo_vision_restriction);
416
417 if (False(capability & Capability::StereoVision)) {
418 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
419 R_THROW(PCTL::ResultNoCapability);
420 }
421
422 SetStereoVisionRestrictionImpl(stereo_vision_restriction);
423 R_SUCCEED();
424}
425
426Result IParentalControlService::ResetConfirmedStereoVisionPermission() {
427 LOG_DEBUG(Service_PCTL, "called");
428
429 states.stereo_vision = false;
430
431 R_SUCCEED();
432}
433
434} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/parental_control_service.h b/src/core/hle/service/pctl/parental_control_service.h
new file mode 100644
index 000000000..03dbaa2e5
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service.h
@@ -0,0 +1,86 @@
1// SPDX-FileCopyrightText: Copyright 2024 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/pctl/pctl_types.h"
10#include "core/hle/service/service.h"
11
12namespace Service::PCTL {
13
14class IParentalControlService final : public ServiceFramework<IParentalControlService> {
15public:
16 explicit IParentalControlService(Core::System& system_, Capability capability_);
17 ~IParentalControlService() override;
18
19private:
20 bool CheckFreeCommunicationPermissionImpl() const;
21 bool ConfirmStereoVisionPermissionImpl() const;
22 void SetStereoVisionRestrictionImpl(bool is_restricted);
23
24 Result Initialize();
25 Result CheckFreeCommunicationPermission();
26 Result ConfirmLaunchApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset,
27 u64 nacp_flag, u64 application_id);
28 Result ConfirmResumeApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset,
29 u64 nacp_flag, u64 application_id);
30 Result ConfirmSnsPostPermission();
31 Result IsRestrictionTemporaryUnlocked(Out<bool> out_is_temporary_unlocked);
32 Result IsRestrictedSystemSettingsEntered(Out<bool> out_is_restricted_system_settings_entered);
33 Result ConfirmStereoVisionPermission();
34 Result EndFreeCommunication();
35 Result IsFreeCommunicationAvailable();
36 Result IsRestrictionEnabled(Out<bool> out_restriction_enabled);
37 Result GetSafetyLevel(Out<u32> out_safety_level);
38 Result GetCurrentSettings(Out<RestrictionSettings> out_settings);
39 Result GetFreeCommunicationApplicationListCount(Out<s32> out_count);
40 Result ConfirmStereoVisionRestrictionConfigurable();
41 Result IsStereoVisionPermitted(Out<bool> out_is_permitted);
42 Result GetPinCodeLength(Out<s32> out_length);
43 Result IsPairingActive(Out<bool> out_is_pairing_active);
44 Result GetSynchronizationEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
45 Result StartPlayTimer();
46 Result StopPlayTimer();
47 Result IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled);
48 Result IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer);
49 Result GetPlayTimerSettings(Out<PlayTimerSettings> out_play_timer_settings);
50 Result GetPlayTimerEventToRequestSuspension(OutCopyHandle<Kernel::KReadableEvent> out_event);
51 Result IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled);
52 Result GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
53 Result GetStereoVisionRestriction(Out<bool> out_stereo_vision_restriction);
54 Result SetStereoVisionRestriction(bool stereo_vision_restriction);
55 Result ResetConfirmedStereoVisionPermission();
56
57 struct States {
58 u64 current_tid{};
59 ApplicationInfo application_info{};
60 u64 tid_from_event{};
61 bool launch_time_valid{};
62 bool is_suspended{};
63 bool temporary_unlocked{};
64 bool free_communication{};
65 bool stereo_vision{};
66 };
67
68 struct ParentalControlSettings {
69 bool is_stero_vision_restricted{};
70 bool is_free_communication_default_on{};
71 bool disabled{};
72 };
73
74 States states{};
75 ParentalControlSettings settings{};
76 RestrictionSettings restriction_settings{};
77 std::array<char, 8> pin_code{};
78 Capability capability{};
79
80 KernelHelpers::ServiceContext service_context;
81 Event synchronization_event;
82 Event unlinked_event;
83 Event request_suspension_event;
84};
85
86} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/parental_control_service_factory.cpp b/src/core/hle/service/pctl/parental_control_service_factory.cpp
new file mode 100644
index 000000000..7d8f361e9
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service_factory.cpp
@@ -0,0 +1,40 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/pctl/parental_control_service.h"
6#include "core/hle/service/pctl/parental_control_service_factory.h"
7
8namespace Service::PCTL {
9
10IParentalControlServiceFactory::IParentalControlServiceFactory(Core::System& system_,
11 const char* name_,
12 Capability capability_)
13 : ServiceFramework{system_, name_}, capability{capability_} {
14 static const FunctionInfo functions[] = {
15 {0, D<&IParentalControlServiceFactory::CreateService>, "CreateService"},
16 {1, D<&IParentalControlServiceFactory::CreateServiceWithoutInitialize>,
17 "CreateServiceWithoutInitialize"},
18 };
19 RegisterHandlers(functions);
20}
21
22IParentalControlServiceFactory::~IParentalControlServiceFactory() = default;
23
24Result IParentalControlServiceFactory::CreateService(
25 Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) {
26 LOG_DEBUG(Service_PCTL, "called");
27 // TODO(ogniK): Get application id from process
28 *out_service = std::make_shared<IParentalControlService>(system, capability);
29 R_SUCCEED();
30}
31
32Result IParentalControlServiceFactory::CreateServiceWithoutInitialize(
33 Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) {
34 LOG_DEBUG(Service_PCTL, "called");
35 // TODO(ogniK): Get application id from process
36 *out_service = std::make_shared<IParentalControlService>(system, capability);
37 R_SUCCEED();
38}
39
40} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/parental_control_service_factory.h b/src/core/hle/service/pctl/parental_control_service_factory.h
new file mode 100644
index 000000000..362988add
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service_factory.h
@@ -0,0 +1,31 @@
1// SPDX-FileCopyrightText: Copyright 2024 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/pctl/pctl_types.h"
8#include "core/hle/service/service.h"
9
10namespace Service::PCTL {
11
12class IParentalControlService;
13
14class IParentalControlServiceFactory : public ServiceFramework<IParentalControlServiceFactory> {
15public:
16 explicit IParentalControlServiceFactory(Core::System& system_, const char* name_,
17 Capability capability_);
18 ~IParentalControlServiceFactory() override;
19
20 Result CreateService(Out<SharedPointer<IParentalControlService>> out_service,
21 ClientProcessId process_id);
22 Result CreateServiceWithoutInitialize(Out<SharedPointer<IParentalControlService>> out_service,
23 ClientProcessId process_id);
24
25private:
26 Capability capability{};
27};
28
29void LoopProcess(Core::System& system);
30
31} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp
index 3f47bf094..d92dbe216 100644
--- a/src/core/hle/service/pctl/pctl.cpp
+++ b/src/core/hle/service/pctl/pctl.cpp
@@ -1,19 +1,28 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/pctl/parental_control_service_factory.h"
4#include "core/hle/service/pctl/pctl.h" 5#include "core/hle/service/pctl/pctl.h"
6#include "core/hle/service/server_manager.h"
5 7
6namespace Service::PCTL { 8namespace Service::PCTL {
7 9
8PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name, 10void LoopProcess(Core::System& system) {
9 Capability capability_) 11 auto server_manager = std::make_unique<ServerManager>(system);
10 : Interface{system_, std::move(module_), name, capability_} { 12
11 static const FunctionInfo functions[] = { 13 server_manager->RegisterNamedService("pctl",
12 {0, &PCTL::CreateService, "CreateService"}, 14 std::make_shared<IParentalControlServiceFactory>(
13 {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, 15 system, "pctl",
14 }; 16 Capability::Application | Capability::SnsPost |
15 RegisterHandlers(functions); 17 Capability::Status | Capability::StereoVision));
18 // TODO(ogniK): Implement remaining capabilities
19 server_manager->RegisterNamedService("pctl:a", std::make_shared<IParentalControlServiceFactory>(
20 system, "pctl:a", Capability::None));
21 server_manager->RegisterNamedService("pctl:r", std::make_shared<IParentalControlServiceFactory>(
22 system, "pctl:r", Capability::None));
23 server_manager->RegisterNamedService("pctl:s", std::make_shared<IParentalControlServiceFactory>(
24 system, "pctl:s", Capability::None));
25 ServerManager::RunServer(std::move(server_manager));
16} 26}
17 27
18PCTL::~PCTL() = default;
19} // namespace Service::PCTL 28} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h
index 87f93161e..5f9d03d4d 100644
--- a/src/core/hle/service/pctl/pctl.h
+++ b/src/core/hle/service/pctl/pctl.h
@@ -3,19 +3,12 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/pctl/pctl_module.h"
7
8namespace Core { 6namespace Core {
9class System; 7class System;
10} 8}
11 9
12namespace Service::PCTL { 10namespace Service::PCTL {
13 11
14class PCTL final : public Module::Interface { 12void LoopProcess(Core::System& system);
15public:
16 explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
17 Capability capability_);
18 ~PCTL() override;
19};
20 13
21} // namespace Service::PCTL 14} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl_module.cpp b/src/core/hle/service/pctl/pctl_module.cpp
deleted file mode 100644
index 6a7fd72bc..000000000
--- a/src/core/hle/service/pctl/pctl_module.cpp
+++ /dev/null
@@ -1,550 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/logging/log.h"
5#include "core/core.h"
6#include "core/file_sys/control_metadata.h"
7#include "core/file_sys/patch_manager.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/pctl/pctl.h"
11#include "core/hle/service/pctl/pctl_module.h"
12#include "core/hle/service/server_manager.h"
13
14namespace Service::PCTL {
15
16namespace Error {
17
18constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101};
19constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104};
20constexpr Result ResultNoCapability{ErrorModule::PCTL, 131};
21constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181};
22
23} // namespace Error
24
25class IParentalControlService final : public ServiceFramework<IParentalControlService> {
26public:
27 explicit IParentalControlService(Core::System& system_, Capability capability_)
28 : ServiceFramework{system_, "IParentalControlService"}, capability{capability_},
29 service_context{system_, "IParentalControlService"} {
30 // clang-format off
31 static const FunctionInfo functions[] = {
32 {1, &IParentalControlService::Initialize, "Initialize"},
33 {1001, &IParentalControlService::CheckFreeCommunicationPermission, "CheckFreeCommunicationPermission"},
34 {1002, nullptr, "ConfirmLaunchApplicationPermission"},
35 {1003, nullptr, "ConfirmResumeApplicationPermission"},
36 {1004, &IParentalControlService::ConfirmSnsPostPermission, "ConfirmSnsPostPermission"},
37 {1005, nullptr, "ConfirmSystemSettingsPermission"},
38 {1006, &IParentalControlService::IsRestrictionTemporaryUnlocked, "IsRestrictionTemporaryUnlocked"},
39 {1007, nullptr, "RevertRestrictionTemporaryUnlocked"},
40 {1008, nullptr, "EnterRestrictedSystemSettings"},
41 {1009, nullptr, "LeaveRestrictedSystemSettings"},
42 {1010, nullptr, "IsRestrictedSystemSettingsEntered"},
43 {1011, nullptr, "RevertRestrictedSystemSettingsEntered"},
44 {1012, nullptr, "GetRestrictedFeatures"},
45 {1013, &IParentalControlService::ConfirmStereoVisionPermission, "ConfirmStereoVisionPermission"},
46 {1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
47 {1015, nullptr, "ConfirmPlayableApplicationVideo"},
48 {1016, nullptr, "ConfirmShowNewsPermission"},
49 {1017, &IParentalControlService::EndFreeCommunication, "EndFreeCommunication"},
50 {1018, &IParentalControlService::IsFreeCommunicationAvailable, "IsFreeCommunicationAvailable"},
51 {1031, &IParentalControlService::IsRestrictionEnabled, "IsRestrictionEnabled"},
52 {1032, &IParentalControlService::GetSafetyLevel, "GetSafetyLevel"},
53 {1033, nullptr, "SetSafetyLevel"},
54 {1034, nullptr, "GetSafetyLevelSettings"},
55 {1035, &IParentalControlService::GetCurrentSettings, "GetCurrentSettings"},
56 {1036, nullptr, "SetCustomSafetyLevelSettings"},
57 {1037, nullptr, "GetDefaultRatingOrganization"},
58 {1038, nullptr, "SetDefaultRatingOrganization"},
59 {1039, &IParentalControlService::GetFreeCommunicationApplicationListCount, "GetFreeCommunicationApplicationListCount"},
60 {1042, nullptr, "AddToFreeCommunicationApplicationList"},
61 {1043, nullptr, "DeleteSettings"},
62 {1044, nullptr, "GetFreeCommunicationApplicationList"},
63 {1045, nullptr, "UpdateFreeCommunicationApplicationList"},
64 {1046, nullptr, "DisableFeaturesForReset"},
65 {1047, nullptr, "NotifyApplicationDownloadStarted"},
66 {1048, nullptr, "NotifyNetworkProfileCreated"},
67 {1049, nullptr, "ResetFreeCommunicationApplicationList"},
68 {1061, &IParentalControlService::ConfirmStereoVisionRestrictionConfigurable, "ConfirmStereoVisionRestrictionConfigurable"},
69 {1062, &IParentalControlService::GetStereoVisionRestriction, "GetStereoVisionRestriction"},
70 {1063, &IParentalControlService::SetStereoVisionRestriction, "SetStereoVisionRestriction"},
71 {1064, &IParentalControlService::ResetConfirmedStereoVisionPermission, "ResetConfirmedStereoVisionPermission"},
72 {1065, &IParentalControlService::IsStereoVisionPermitted, "IsStereoVisionPermitted"},
73 {1201, nullptr, "UnlockRestrictionTemporarily"},
74 {1202, nullptr, "UnlockSystemSettingsRestriction"},
75 {1203, nullptr, "SetPinCode"},
76 {1204, nullptr, "GenerateInquiryCode"},
77 {1205, nullptr, "CheckMasterKey"},
78 {1206, nullptr, "GetPinCodeLength"},
79 {1207, nullptr, "GetPinCodeChangedEvent"},
80 {1208, nullptr, "GetPinCode"},
81 {1403, &IParentalControlService::IsPairingActive, "IsPairingActive"},
82 {1406, nullptr, "GetSettingsLastUpdated"},
83 {1411, nullptr, "GetPairingAccountInfo"},
84 {1421, nullptr, "GetAccountNickname"},
85 {1424, nullptr, "GetAccountState"},
86 {1425, nullptr, "RequestPostEvents"},
87 {1426, nullptr, "GetPostEventInterval"},
88 {1427, nullptr, "SetPostEventInterval"},
89 {1432, &IParentalControlService::GetSynchronizationEvent, "GetSynchronizationEvent"},
90 {1451, nullptr, "StartPlayTimer"},
91 {1452, nullptr, "StopPlayTimer"},
92 {1453, nullptr, "IsPlayTimerEnabled"},
93 {1454, nullptr, "GetPlayTimerRemainingTime"},
94 {1455, nullptr, "IsRestrictedByPlayTimer"},
95 {1456, &IParentalControlService::GetPlayTimerSettings, "GetPlayTimerSettings"},
96 {1457, &IParentalControlService::GetPlayTimerEventToRequestSuspension, "GetPlayTimerEventToRequestSuspension"},
97 {1458, &IParentalControlService::IsPlayTimerAlarmDisabled, "IsPlayTimerAlarmDisabled"},
98 {1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
99 {1472, nullptr, "CancelNetworkRequest"},
100 {1473, &IParentalControlService::GetUnlinkedEvent, "GetUnlinkedEvent"},
101 {1474, nullptr, "ClearUnlinkedEvent"},
102 {1601, nullptr, "DisableAllFeatures"},
103 {1602, nullptr, "PostEnableAllFeatures"},
104 {1603, nullptr, "IsAllFeaturesDisabled"},
105 {1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"},
106 {1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"},
107 {1903, nullptr, "GetExemptApplicationListCountForDebug"},
108 {1904, nullptr, "GetExemptApplicationListForDebug"},
109 {1905, nullptr, "UpdateExemptApplicationListForDebug"},
110 {1906, nullptr, "AddToExemptApplicationListForDebug"},
111 {1907, nullptr, "DeleteFromExemptApplicationListForDebug"},
112 {1908, nullptr, "ClearExemptApplicationListForDebug"},
113 {1941, nullptr, "DeletePairing"},
114 {1951, nullptr, "SetPlayTimerSettingsForDebug"},
115 {1952, nullptr, "GetPlayTimerSpentTimeForTest"},
116 {1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"},
117 {2001, nullptr, "RequestPairingAsync"},
118 {2002, nullptr, "FinishRequestPairing"},
119 {2003, nullptr, "AuthorizePairingAsync"},
120 {2004, nullptr, "FinishAuthorizePairing"},
121 {2005, nullptr, "RetrievePairingInfoAsync"},
122 {2006, nullptr, "FinishRetrievePairingInfo"},
123 {2007, nullptr, "UnlinkPairingAsync"},
124 {2008, nullptr, "FinishUnlinkPairing"},
125 {2009, nullptr, "GetAccountMiiImageAsync"},
126 {2010, nullptr, "FinishGetAccountMiiImage"},
127 {2011, nullptr, "GetAccountMiiImageContentTypeAsync"},
128 {2012, nullptr, "FinishGetAccountMiiImageContentType"},
129 {2013, nullptr, "SynchronizeParentalControlSettingsAsync"},
130 {2014, nullptr, "FinishSynchronizeParentalControlSettings"},
131 {2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
132 {2016, nullptr, "RequestUpdateExemptionListAsync"},
133 };
134 // clang-format on
135 RegisterHandlers(functions);
136
137 synchronization_event =
138 service_context.CreateEvent("IParentalControlService::SynchronizationEvent");
139 unlinked_event = service_context.CreateEvent("IParentalControlService::UnlinkedEvent");
140 request_suspension_event =
141 service_context.CreateEvent("IParentalControlService::RequestSuspensionEvent");
142 }
143
144 ~IParentalControlService() {
145 service_context.CloseEvent(synchronization_event);
146 service_context.CloseEvent(unlinked_event);
147 service_context.CloseEvent(request_suspension_event);
148 };
149
150private:
151 bool CheckFreeCommunicationPermissionImpl() const {
152 if (states.temporary_unlocked) {
153 return true;
154 }
155 if ((states.application_info.parental_control_flag & 1) == 0) {
156 return true;
157 }
158 if (pin_code[0] == '\0') {
159 return true;
160 }
161 if (!settings.is_free_communication_default_on) {
162 return true;
163 }
164 // TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here
165 // but as we don't have multiproceses support yet, we can just assume our application is
166 // valid for the time being
167 return true;
168 }
169
170 bool ConfirmStereoVisionPermissionImpl() const {
171 if (states.temporary_unlocked) {
172 return true;
173 }
174 if (pin_code[0] == '\0') {
175 return true;
176 }
177 if (!settings.is_stero_vision_restricted) {
178 return false;
179 }
180 return true;
181 }
182
183 void SetStereoVisionRestrictionImpl(bool is_restricted) {
184 if (settings.disabled) {
185 return;
186 }
187
188 if (pin_code[0] == '\0') {
189 return;
190 }
191 settings.is_stero_vision_restricted = is_restricted;
192 }
193
194 void Initialize(HLERequestContext& ctx) {
195 LOG_DEBUG(Service_PCTL, "called");
196 IPC::ResponseBuilder rb{ctx, 2};
197
198 if (False(capability & (Capability::Application | Capability::System))) {
199 LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability);
200 return;
201 }
202
203 // TODO(ogniK): Recovery flag initialization for pctl:r
204
205 const auto tid = system.GetApplicationProcessProgramID();
206 if (tid != 0) {
207 const FileSys::PatchManager pm{tid, system.GetFileSystemController(),
208 system.GetContentProvider()};
209 const auto control = pm.GetControlMetadata();
210 if (control.first) {
211 states.tid_from_event = 0;
212 states.launch_time_valid = false;
213 states.is_suspended = false;
214 states.free_communication = false;
215 states.stereo_vision = false;
216 states.application_info = ApplicationInfo{
217 .tid = tid,
218 .age_rating = control.first->GetRatingAge(),
219 .parental_control_flag = control.first->GetParentalControlFlag(),
220 .capability = capability,
221 };
222
223 if (False(capability & (Capability::System | Capability::Recovery))) {
224 // TODO(ogniK): Signal application launch event
225 }
226 }
227 }
228
229 rb.Push(ResultSuccess);
230 }
231
232 void CheckFreeCommunicationPermission(HLERequestContext& ctx) {
233 LOG_DEBUG(Service_PCTL, "called");
234
235 IPC::ResponseBuilder rb{ctx, 2};
236 if (!CheckFreeCommunicationPermissionImpl()) {
237 rb.Push(Error::ResultNoFreeCommunication);
238 } else {
239 rb.Push(ResultSuccess);
240 }
241
242 states.free_communication = true;
243 }
244
245 void ConfirmSnsPostPermission(HLERequestContext& ctx) {
246 LOG_WARNING(Service_PCTL, "(STUBBED) called");
247
248 IPC::ResponseBuilder rb{ctx, 2};
249 rb.Push(Error::ResultNoFreeCommunication);
250 }
251
252 void IsRestrictionTemporaryUnlocked(HLERequestContext& ctx) {
253 const bool is_temporary_unlocked = false;
254
255 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
256 is_temporary_unlocked);
257
258 IPC::ResponseBuilder rb{ctx, 3};
259 rb.Push(ResultSuccess);
260 rb.Push<u8>(is_temporary_unlocked);
261 }
262
263 void ConfirmStereoVisionPermission(HLERequestContext& ctx) {
264 LOG_DEBUG(Service_PCTL, "called");
265 states.stereo_vision = true;
266
267 IPC::ResponseBuilder rb{ctx, 2};
268 rb.Push(ResultSuccess);
269 }
270
271 void EndFreeCommunication(HLERequestContext& ctx) {
272 LOG_WARNING(Service_PCTL, "(STUBBED) called");
273
274 IPC::ResponseBuilder rb{ctx, 2};
275 rb.Push(ResultSuccess);
276 }
277
278 void IsFreeCommunicationAvailable(HLERequestContext& ctx) {
279 LOG_WARNING(Service_PCTL, "(STUBBED) called");
280
281 IPC::ResponseBuilder rb{ctx, 2};
282 if (!CheckFreeCommunicationPermissionImpl()) {
283 rb.Push(Error::ResultNoFreeCommunication);
284 } else {
285 rb.Push(ResultSuccess);
286 }
287 }
288
289 void IsRestrictionEnabled(HLERequestContext& ctx) {
290 LOG_DEBUG(Service_PCTL, "called");
291
292 IPC::ResponseBuilder rb{ctx, 3};
293 if (False(capability & (Capability::Status | Capability::Recovery))) {
294 LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!");
295 rb.Push(Error::ResultNoCapability);
296 rb.Push(false);
297 return;
298 }
299
300 rb.Push(pin_code[0] != '\0');
301 }
302
303 void GetSafetyLevel(HLERequestContext& ctx) {
304 const u32 safety_level = 0;
305
306 LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", safety_level);
307
308 IPC::ResponseBuilder rb{ctx, 3};
309 rb.Push(ResultSuccess);
310 rb.Push(safety_level);
311 }
312
313 void GetCurrentSettings(HLERequestContext& ctx) {
314 LOG_INFO(Service_PCTL, "called");
315
316 IPC::ResponseBuilder rb{ctx, 3};
317 rb.Push(ResultSuccess);
318 rb.PushRaw(restriction_settings);
319 }
320
321 void GetFreeCommunicationApplicationListCount(HLERequestContext& ctx) {
322 const u32 count = 4;
323
324 LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", count);
325
326 IPC::ResponseBuilder rb{ctx, 3};
327 rb.Push(ResultSuccess);
328 rb.Push(count);
329 }
330
331 void ConfirmStereoVisionRestrictionConfigurable(HLERequestContext& ctx) {
332 LOG_DEBUG(Service_PCTL, "called");
333
334 IPC::ResponseBuilder rb{ctx, 2};
335
336 if (False(capability & Capability::StereoVision)) {
337 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
338 rb.Push(Error::ResultNoCapability);
339 return;
340 }
341
342 if (pin_code[0] == '\0') {
343 rb.Push(Error::ResultNoRestrictionEnabled);
344 return;
345 }
346
347 rb.Push(ResultSuccess);
348 }
349
350 void IsStereoVisionPermitted(HLERequestContext& ctx) {
351 LOG_DEBUG(Service_PCTL, "called");
352
353 IPC::ResponseBuilder rb{ctx, 3};
354 if (!ConfirmStereoVisionPermissionImpl()) {
355 rb.Push(Error::ResultStereoVisionRestricted);
356 rb.Push(false);
357 } else {
358 rb.Push(ResultSuccess);
359 rb.Push(true);
360 }
361 }
362
363 void IsPairingActive(HLERequestContext& ctx) {
364 const bool is_pairing_active = false;
365
366 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", is_pairing_active);
367
368 IPC::ResponseBuilder rb{ctx, 3};
369 rb.Push(ResultSuccess);
370 rb.Push<u8>(is_pairing_active);
371 }
372
373 void GetSynchronizationEvent(HLERequestContext& ctx) {
374 LOG_INFO(Service_PCTL, "called");
375
376 IPC::ResponseBuilder rb{ctx, 2, 1};
377 rb.Push(ResultSuccess);
378 rb.PushCopyObjects(synchronization_event->GetReadableEvent());
379 }
380
381 void GetPlayTimerSettings(HLERequestContext& ctx) {
382 LOG_WARNING(Service_PCTL, "(STUBBED) called");
383
384 const PlayTimerSettings timer_settings{};
385
386 IPC::ResponseBuilder rb{ctx, 15};
387 rb.Push(ResultSuccess);
388 rb.PushRaw(timer_settings);
389 }
390
391 void GetPlayTimerEventToRequestSuspension(HLERequestContext& ctx) {
392 LOG_INFO(Service_PCTL, "called");
393
394 IPC::ResponseBuilder rb{ctx, 2, 1};
395 rb.Push(ResultSuccess);
396 rb.PushCopyObjects(request_suspension_event->GetReadableEvent());
397 }
398
399 void IsPlayTimerAlarmDisabled(HLERequestContext& ctx) {
400 const bool is_play_timer_alarm_disabled = false;
401
402 LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}",
403 is_play_timer_alarm_disabled);
404
405 IPC::ResponseBuilder rb{ctx, 3};
406 rb.Push(ResultSuccess);
407 rb.Push<u8>(is_play_timer_alarm_disabled);
408 }
409
410 void GetUnlinkedEvent(HLERequestContext& ctx) {
411 LOG_INFO(Service_PCTL, "called");
412
413 IPC::ResponseBuilder rb{ctx, 2, 1};
414 rb.Push(ResultSuccess);
415 rb.PushCopyObjects(unlinked_event->GetReadableEvent());
416 }
417
418 void SetStereoVisionRestriction(HLERequestContext& ctx) {
419 IPC::RequestParser rp{ctx};
420 const auto can_use = rp.Pop<bool>();
421 LOG_DEBUG(Service_PCTL, "called, can_use={}", can_use);
422
423 IPC::ResponseBuilder rb{ctx, 2};
424 if (False(capability & Capability::StereoVision)) {
425 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
426 rb.Push(Error::ResultNoCapability);
427 return;
428 }
429
430 SetStereoVisionRestrictionImpl(can_use);
431 rb.Push(ResultSuccess);
432 }
433
434 void GetStereoVisionRestriction(HLERequestContext& ctx) {
435 LOG_DEBUG(Service_PCTL, "called");
436
437 IPC::ResponseBuilder rb{ctx, 3};
438 if (False(capability & Capability::StereoVision)) {
439 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
440 rb.Push(Error::ResultNoCapability);
441 rb.Push(false);
442 return;
443 }
444
445 rb.Push(ResultSuccess);
446 rb.Push(settings.is_stero_vision_restricted);
447 }
448
449 void ResetConfirmedStereoVisionPermission(HLERequestContext& ctx) {
450 LOG_DEBUG(Service_PCTL, "called");
451
452 states.stereo_vision = false;
453
454 IPC::ResponseBuilder rb{ctx, 2};
455 rb.Push(ResultSuccess);
456 }
457
458 struct ApplicationInfo {
459 u64 tid{};
460 std::array<u8, 32> age_rating{};
461 u32 parental_control_flag{};
462 Capability capability{};
463 };
464
465 struct States {
466 u64 current_tid{};
467 ApplicationInfo application_info{};
468 u64 tid_from_event{};
469 bool launch_time_valid{};
470 bool is_suspended{};
471 bool temporary_unlocked{};
472 bool free_communication{};
473 bool stereo_vision{};
474 };
475
476 struct ParentalControlSettings {
477 bool is_stero_vision_restricted{};
478 bool is_free_communication_default_on{};
479 bool disabled{};
480 };
481
482 // This is nn::pctl::RestrictionSettings
483 struct RestrictionSettings {
484 u8 rating_age;
485 bool sns_post_restriction;
486 bool free_communication_restriction;
487 };
488 static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size.");
489
490 // This is nn::pctl::PlayTimerSettings
491 struct PlayTimerSettings {
492 std::array<u32, 13> settings;
493 };
494 static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size.");
495
496 States states{};
497 ParentalControlSettings settings{};
498 RestrictionSettings restriction_settings{};
499 std::array<char, 8> pin_code{};
500 Capability capability{};
501
502 Kernel::KEvent* synchronization_event;
503 Kernel::KEvent* unlinked_event;
504 Kernel::KEvent* request_suspension_event;
505 KernelHelpers::ServiceContext service_context;
506};
507
508void Module::Interface::CreateService(HLERequestContext& ctx) {
509 LOG_DEBUG(Service_PCTL, "called");
510
511 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
512 rb.Push(ResultSuccess);
513 // TODO(ogniK): Get TID from process
514
515 rb.PushIpcInterface<IParentalControlService>(system, capability);
516}
517
518void Module::Interface::CreateServiceWithoutInitialize(HLERequestContext& ctx) {
519 LOG_DEBUG(Service_PCTL, "called");
520
521 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
522 rb.Push(ResultSuccess);
523 rb.PushIpcInterface<IParentalControlService>(system, capability);
524}
525
526Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
527 const char* name_, Capability capability_)
528 : ServiceFramework{system_, name_}, module{std::move(module_)}, capability{capability_} {}
529
530Module::Interface::~Interface() = default;
531
532void LoopProcess(Core::System& system) {
533 auto server_manager = std::make_unique<ServerManager>(system);
534
535 auto module = std::make_shared<Module>();
536 server_manager->RegisterNamedService(
537 "pctl", std::make_shared<PCTL>(system, module, "pctl",
538 Capability::Application | Capability::SnsPost |
539 Capability::Status | Capability::StereoVision));
540 // TODO(ogniK): Implement remaining capabilities
541 server_manager->RegisterNamedService(
542 "pctl:a", std::make_shared<PCTL>(system, module, "pctl:a", Capability::None));
543 server_manager->RegisterNamedService(
544 "pctl:r", std::make_shared<PCTL>(system, module, "pctl:r", Capability::None));
545 server_manager->RegisterNamedService(
546 "pctl:s", std::make_shared<PCTL>(system, module, "pctl:s", Capability::None));
547 ServerManager::RunServer(std::move(server_manager));
548}
549
550} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl_module.h b/src/core/hle/service/pctl/pctl_module.h
deleted file mode 100644
index dff0d3f08..000000000
--- a/src/core/hle/service/pctl/pctl_module.h
+++ /dev/null
@@ -1,47 +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 "common/common_funcs.h"
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Service::PCTL {
14
15enum class Capability : u32 {
16 None = 0,
17 Application = 1 << 0,
18 SnsPost = 1 << 1,
19 Recovery = 1 << 6,
20 Status = 1 << 8,
21 StereoVision = 1 << 9,
22 System = 1 << 15,
23};
24DECLARE_ENUM_FLAG_OPERATORS(Capability);
25
26class Module final {
27public:
28 class Interface : public ServiceFramework<Interface> {
29 public:
30 explicit Interface(Core::System& system_, std::shared_ptr<Module> module_,
31 const char* name_, Capability capability_);
32 ~Interface() override;
33
34 void CreateService(HLERequestContext& ctx);
35 void CreateServiceWithoutInitialize(HLERequestContext& ctx);
36
37 protected:
38 std::shared_ptr<Module> module;
39
40 private:
41 Capability capability{};
42 };
43};
44
45void LoopProcess(Core::System& system);
46
47} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl_results.h b/src/core/hle/service/pctl/pctl_results.h
new file mode 100644
index 000000000..1fc54727b
--- /dev/null
+++ b/src/core/hle/service/pctl/pctl_results.h
@@ -0,0 +1,15 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/result.h"
7
8namespace Service::PCTL {
9
10constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101};
11constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104};
12constexpr Result ResultNoCapability{ErrorModule::PCTL, 131};
13constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181};
14
15} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl_types.h b/src/core/hle/service/pctl/pctl_types.h
new file mode 100644
index 000000000..daaecdf48
--- /dev/null
+++ b/src/core/hle/service/pctl/pctl_types.h
@@ -0,0 +1,43 @@
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_funcs.h"
7
8namespace Service::PCTL {
9
10enum class Capability : u32 {
11 None = 0,
12 Application = 1 << 0,
13 SnsPost = 1 << 1,
14 Recovery = 1 << 6,
15 Status = 1 << 8,
16 StereoVision = 1 << 9,
17 System = 1 << 15,
18};
19DECLARE_ENUM_FLAG_OPERATORS(Capability);
20
21struct ApplicationInfo {
22 u64 application_id{};
23 std::array<u8, 32> age_rating{};
24 u32 parental_control_flag{};
25 Capability capability{};
26};
27static_assert(sizeof(ApplicationInfo) == 0x30, "ApplicationInfo has incorrect size.");
28
29// This is nn::pctl::RestrictionSettings
30struct RestrictionSettings {
31 u8 rating_age;
32 bool sns_post_restriction;
33 bool free_communication_restriction;
34};
35static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size.");
36
37// This is nn::pctl::PlayTimerSettings
38struct PlayTimerSettings {
39 std::array<u32, 13> settings;
40};
41static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size.");
42
43} // namespace Service::PCTL
diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp
index d6c6eff50..1aa85ea54 100644
--- a/src/core/hle/service/services.cpp
+++ b/src/core/hle/service/services.cpp
@@ -46,7 +46,7 @@
46#include "core/hle/service/olsc/olsc.h" 46#include "core/hle/service/olsc/olsc.h"
47#include "core/hle/service/omm/omm.h" 47#include "core/hle/service/omm/omm.h"
48#include "core/hle/service/pcie/pcie.h" 48#include "core/hle/service/pcie/pcie.h"
49#include "core/hle/service/pctl/pctl_module.h" 49#include "core/hle/service/pctl/pctl.h"
50#include "core/hle/service/pcv/pcv.h" 50#include "core/hle/service/pcv/pcv.h"
51#include "core/hle/service/pm/pm.h" 51#include "core/hle/service/pm/pm.h"
52#include "core/hle/service/prepo/prepo.h" 52#include "core/hle/service/prepo/prepo.h"