diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 2f7362748..59ea9823d 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -171,7 +171,11 @@ void SendParameter(const MessageParameter& parameter) { next_parameter = parameter; // Signal the event to let the receiver know that a new parameter is ready to be read auto* const slot_data = GetAppletSlotData(static_cast(parameter.destination_id)); - ASSERT(slot_data); + if (slot_data == nullptr) { + LOG_DEBUG(Service_APT, "No applet was registered with the id %03X", + parameter.destination_id); + return; + } slot_data->parameter_event->Signal(); } @@ -505,9 +509,6 @@ void SendParameter(Service::Interface* self) { size_t size; VAddr buffer = rp.PopStaticBuffer(&size); - std::shared_ptr dest_applet = - HLE::Applets::Applet::Get(static_cast(dst_app_id)); - LOG_DEBUG(Service_APT, "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X", @@ -522,12 +523,6 @@ void SendParameter(Service::Interface* self) { return; } - if (dest_applet == nullptr) { - LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id); - rb.Push(-1); // TODO(Subv): Find the right error code - return; - } - MessageParameter param; param.destination_id = dst_app_id; param.sender_id = src_app_id; @@ -536,7 +531,14 @@ void SendParameter(Service::Interface* self) { param.buffer.resize(buffer_size); Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); - rb.Push(dest_applet->ReceiveParameter(param)); + SendParameter(param); + + // If the applet is running in HLE mode, use the HLE interface to communicate with it. + if (auto dest_applet = HLE::Applets::Applet::Get(static_cast(dst_app_id))) { + rb.Push(dest_applet->ReceiveParameter(param)); + } else { + rb.Push(RESULT_SUCCESS); + } } void ReceiveParameter(Service::Interface* self) { @@ -765,7 +767,12 @@ void PrepareToStartLibraryApplet(Service::Interface* self) { IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040 AppletId applet_id = static_cast(rp.Pop()); + LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + + // TODO(Subv): Launch the requested applet application. + auto applet = HLE::Applets::Applet::Get(applet_id); if (applet) { LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); @@ -773,7 +780,6 @@ void PrepareToStartLibraryApplet(Service::Interface* self) { } else { rb.Push(HLE::Applets::Applet::Create(applet_id)); } - LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); } void PrepareToStartNewestHomeMenu(Service::Interface* self) { @@ -794,7 +800,12 @@ void PreloadLibraryApplet(Service::Interface* self) { IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040 AppletId applet_id = static_cast(rp.Pop()); + LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + + // TODO(Subv): Launch the requested applet application. + auto applet = HLE::Applets::Applet::Get(applet_id); if (applet) { LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); @@ -802,34 +813,40 @@ void PreloadLibraryApplet(Service::Interface* self) { } else { rb.Push(HLE::Applets::Applet::Create(applet_id)); } - LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); } void StartLibraryApplet(Service::Interface* self) { IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084 AppletId applet_id = static_cast(rp.Pop()); - std::shared_ptr applet = HLE::Applets::Applet::Get(applet_id); - - LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); - - if (applet == nullptr) { - LOG_ERROR(Service_APT, "unknown applet id=%08X", applet_id); - IPC::RequestBuilder rb = rp.MakeBuilder(1, 0, false); - rb.Push(-1); // TODO(Subv): Find the right error code - return; - } size_t buffer_size = rp.Pop(); Kernel::Handle handle = rp.PopHandle(); VAddr buffer_addr = rp.PopStaticBuffer(); - AppletStartupParameter parameter; - parameter.object = Kernel::g_handle_table.GetGeneric(handle); - parameter.buffer.resize(buffer_size); - Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size()); + LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(applet->Start(parameter)); + + // Send the Wakeup signal to the applet + MessageParameter param; + param.destination_id = static_cast(applet_id); + param.sender_id = static_cast(AppletId::Application); + param.object = Kernel::g_handle_table.GetGeneric(handle); + param.signal = static_cast(SignalType::Wakeup); + param.buffer.resize(buffer_size); + Memory::ReadBlock(buffer_addr, param.buffer.data(), param.buffer.size()); + SendParameter(param); + + // In case the applet is being HLEd, attempt to communicate with it. + if (auto applet = HLE::Applets::Applet::Get(applet_id)) { + AppletStartupParameter parameter; + parameter.object = Kernel::g_handle_table.GetGeneric(handle); + parameter.buffer.resize(buffer_size); + Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size()); + rb.Push(applet->Start(parameter)); + } else { + rb.Push(RESULT_SUCCESS); + } } void CancelLibraryApplet(Service::Interface* self) { diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index fe1d21fff..bb78ee7d7 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -20,7 +20,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00090040, IsRegistered, "IsRegistered"}, {0x000A0040, nullptr, "GetAttribute"}, {0x000B0040, InquireNotification, "InquireNotification"}, - {0x000C0104, nullptr, "SendParameter"}, + {0x000C0104, SendParameter, "SendParameter"}, {0x000D0080, ReceiveParameter, "ReceiveParameter"}, {0x000E0080, GlanceParameter, "GlanceParameter"}, {0x000F0100, nullptr, "CancelParameter"}, @@ -38,7 +38,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x001B00C4, nullptr, "StartApplication"}, {0x001C0000, nullptr, "WakeupApplication"}, {0x001D0000, nullptr, "CancelApplication"}, - {0x001E0084, nullptr, "StartLibraryApplet"}, + {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, {0x001F0084, nullptr, "StartSystemApplet"}, {0x00200044, nullptr, "StartNewestHomeMenu"}, {0x00210000, nullptr, "OrderToCloseApplication"},