summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/apt/apt.cpp132
-rw-r--r--src/core/hle/service/apt/apt.h6
2 files changed, 105 insertions, 33 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 5c44b43bb..4e6b7b6f5 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <boost/optional.hpp>
5#include "common/common_paths.h" 6#include "common/common_paths.h"
6#include "common/file_util.h" 7#include "common/file_util.h"
7#include "common/logging/log.h" 8#include "common/logging/log.h"
@@ -44,7 +45,7 @@ static u8 unknown_ns_state_field;
44static ScreencapPostPermission screen_capture_post_permission; 45static ScreencapPostPermission screen_capture_post_permission;
45 46
46/// Parameter data to be returned in the next call to Glance/ReceiveParameter 47/// Parameter data to be returned in the next call to Glance/ReceiveParameter
47static MessageParameter next_parameter; 48static boost::optional<MessageParameter> next_parameter;
48 49
49void SendParameter(const MessageParameter& parameter) { 50void SendParameter(const MessageParameter& parameter) {
50 next_parameter = parameter; 51 next_parameter = parameter;
@@ -189,8 +190,20 @@ void SendParameter(Service::Interface* self) {
189 std::shared_ptr<HLE::Applets::Applet> dest_applet = 190 std::shared_ptr<HLE::Applets::Applet> dest_applet =
190 HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id)); 191 HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
191 192
193 LOG_DEBUG(Service_APT,
194 "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
195 "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
196 src_app_id, dst_app_id, signal_type, buffer_size, handle, size, buffer);
197
192 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); 198 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
193 199
200 // A new parameter can not be sent if the previous one hasn't been consumed yet
201 if (next_parameter) {
202 rb.Push(ResultCode(ErrCodes::ParameterPresent, ErrorModule::Applet,
203 ErrorSummary::InvalidState, ErrorLevel::Status));
204 return;
205 }
206
194 if (dest_applet == nullptr) { 207 if (dest_applet == nullptr) {
195 LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id); 208 LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
196 rb.Push<u32>(-1); // TODO(Subv): Find the right error code 209 rb.Push<u32>(-1); // TODO(Subv): Find the right error code
@@ -206,11 +219,6 @@ void SendParameter(Service::Interface* self) {
206 Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); 219 Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
207 220
208 rb.Push(dest_applet->ReceiveParameter(param)); 221 rb.Push(dest_applet->ReceiveParameter(param));
209
210 LOG_WARNING(Service_APT,
211 "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
212 "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
213 src_app_id, dst_app_id, signal_type, buffer_size, handle, size, buffer);
214} 222}
215 223
216void ReceiveParameter(Service::Interface* self) { 224void ReceiveParameter(Service::Interface* self) {
@@ -226,21 +234,40 @@ void ReceiveParameter(Service::Interface* self) {
226 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", 234 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)",
227 buffer_size, static_buff_size); 235 buffer_size, static_buff_size);
228 236
237 LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size);
238
239 if (!next_parameter) {
240 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
241 rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::Applet,
242 ErrorSummary::InvalidState, ErrorLevel::Status));
243 return;
244 }
245
246 if (next_parameter->destination_id != app_id) {
247 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
248 rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotFound,
249 ErrorLevel::Status));
250 return;
251 }
252
229 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4); 253 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4);
254
230 rb.Push(RESULT_SUCCESS); // No error 255 rb.Push(RESULT_SUCCESS); // No error
231 rb.Push(next_parameter.sender_id); 256 rb.Push(next_parameter->sender_id);
232 rb.Push(next_parameter.signal); // Signal type 257 rb.Push(next_parameter->signal); // Signal type
233 ASSERT_MSG(next_parameter.buffer.size() <= buffer_size, "Input static buffer is too small !"); 258 ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !");
234 rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size 259 rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size
235 260
236 rb.PushMoveHandles((next_parameter.object != nullptr) 261 rb.PushMoveHandles((next_parameter->object != nullptr)
237 ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() 262 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap()
238 : 0); 263 : 0);
239 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0);
240 264
241 Memory::WriteBlock(buffer, next_parameter.buffer.data(), next_parameter.buffer.size()); 265 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0);
242 266
243 LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); 267 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size());
268
269 // Clear the parameter
270 next_parameter = boost::none;
244} 271}
245 272
246void GlanceParameter(Service::Interface* self) { 273void GlanceParameter(Service::Interface* self) {
@@ -256,37 +283,74 @@ void GlanceParameter(Service::Interface* self) {
256 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", 283 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)",
257 buffer_size, static_buff_size); 284 buffer_size, static_buff_size);
258 285
286 LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size);
287
288 if (!next_parameter) {
289 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
290 rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::Applet,
291 ErrorSummary::InvalidState, ErrorLevel::Status));
292 return;
293 }
294
295 if (next_parameter->destination_id != app_id) {
296 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
297 rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotFound,
298 ErrorLevel::Status));
299 return;
300 }
301
259 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4); 302 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4);
260 rb.Push(RESULT_SUCCESS); // No error 303 rb.Push(RESULT_SUCCESS); // No error
261 rb.Push(next_parameter.sender_id); 304 rb.Push(next_parameter->sender_id);
262 rb.Push(next_parameter.signal); // Signal type 305 rb.Push(next_parameter->signal); // Signal type
263 ASSERT_MSG(next_parameter.buffer.size() <= buffer_size, "Input static buffer is too small !"); 306 ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !");
264 rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size 307 rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size
265 308
266 rb.PushCopyHandles((next_parameter.object != nullptr) 309 rb.PushMoveHandles((next_parameter->object != nullptr)
267 ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() 310 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap()
268 : 0); 311 : 0);
269 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0);
270 312
271 Memory::WriteBlock(buffer, next_parameter.buffer.data(), next_parameter.buffer.size()); 313 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0);
272 314
273 LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); 315 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size());
316
317 // Note: The NS module always clears the DSPSleep and DSPWakeup signals even in GlanceParameter.
318 if (next_parameter->signal == static_cast<u32>(SignalType::DspSleep) ||
319 next_parameter->signal == static_cast<u32>(SignalType::DspWakeup))
320 next_parameter = boost::none;
274} 321}
275 322
276void CancelParameter(Service::Interface* self) { 323void CancelParameter(Service::Interface* self) {
277 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xF, 4, 0); // 0xF0100 324 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xF, 4, 0); // 0xF0100
278 325
279 u32 check_sender = rp.Pop<u32>(); 326 bool check_sender = rp.Pop<bool>();
280 u32 sender_appid = rp.Pop<u32>(); 327 u32 sender_appid = rp.Pop<u32>();
281 u32 check_receiver = rp.Pop<u32>(); 328 bool check_receiver = rp.Pop<bool>();
282 u32 receiver_appid = rp.Pop<u32>(); 329 u32 receiver_appid = rp.Pop<u32>();
330
331 bool cancellation_success = true;
332
333 if (!next_parameter) {
334 cancellation_success = false;
335 } else {
336 if (check_sender && next_parameter->sender_id != sender_appid)
337 cancellation_success = false;
338
339 if (check_receiver && next_parameter->destination_id != receiver_appid)
340 cancellation_success = false;
341 }
342
343 if (cancellation_success)
344 next_parameter = boost::none;
345
283 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); 346 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
347
284 rb.Push(RESULT_SUCCESS); // No error 348 rb.Push(RESULT_SUCCESS); // No error
285 rb.Push(true); // Set to Success 349 rb.Push(cancellation_success);
286 350
287 LOG_WARNING(Service_APT, "(STUBBED) called check_sender=0x%08X, sender_appid=0x%08X, " 351 LOG_DEBUG(Service_APT, "called check_sender=%u, sender_appid=0x%08X, "
288 "check_receiver=0x%08X, receiver_appid=0x%08X", 352 "check_receiver=%u, receiver_appid=0x%08X",
289 check_sender, sender_appid, check_receiver, receiver_appid); 353 check_sender, sender_appid, check_receiver, receiver_appid);
290} 354}
291 355
292void PrepareToStartApplication(Service::Interface* self) { 356void PrepareToStartApplication(Service::Interface* self) {
@@ -800,8 +864,10 @@ void Init() {
800 notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification"); 864 notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification");
801 parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Start"); 865 parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Start");
802 866
803 next_parameter.signal = static_cast<u32>(SignalType::Wakeup); 867 // Initialize the parameter to wake up the application.
804 next_parameter.destination_id = 0x300; 868 next_parameter.emplace();
869 next_parameter->signal = static_cast<u32>(SignalType::Wakeup);
870 next_parameter->destination_id = static_cast<u32>(AppletId::Application);
805} 871}
806 872
807void Shutdown() { 873void Shutdown() {
@@ -812,7 +878,7 @@ void Shutdown() {
812 notification_event = nullptr; 878 notification_event = nullptr;
813 parameter_event = nullptr; 879 parameter_event = nullptr;
814 880
815 next_parameter.object = nullptr; 881 next_parameter = boost::none;
816 882
817 HLE::Applets::Shutdown(); 883 HLE::Applets::Shutdown();
818} 884}
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index ee80926d2..106754853 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -116,6 +116,12 @@ enum class ScreencapPostPermission : u32 {
116 DisableScreenshotPostingToMiiverse = 3 116 DisableScreenshotPostingToMiiverse = 3
117}; 117};
118 118
119namespace ErrCodes {
120enum {
121 ParameterPresent = 2,
122};
123}
124
119/// Send a parameter to the currently-running application, which will read it via ReceiveParameter 125/// Send a parameter to the currently-running application, which will read it via ReceiveParameter
120void SendParameter(const MessageParameter& parameter); 126void SendParameter(const MessageParameter& parameter);
121 127