diff options
Diffstat (limited to 'src/core/hle/service')
49 files changed, 1172 insertions, 797 deletions
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 2dc23e674..d120dade8 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp @@ -3,141 +3,18 @@ #include <memory> -#include "common/logging/log.h" -#include "core/core.h" -#include "core/hle/kernel/k_event.h" #include "core/hle/service/btm/btm.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/btm/btm_debug.h" +#include "core/hle/service/btm/btm_system.h" +#include "core/hle/service/btm/btm_user.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" namespace Service::BTM { -class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { +class IBtm final : public ServiceFramework<IBtm> { public: - explicit IBtmUserCore(Core::System& system_) - : ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"}, - {1, nullptr, "GetBleScanFilterParameter"}, - {2, nullptr, "GetBleScanFilterParameter2"}, - {3, nullptr, "StartBleScanForGeneral"}, - {4, nullptr, "StopBleScanForGeneral"}, - {5, nullptr, "GetBleScanResultsForGeneral"}, - {6, nullptr, "StartBleScanForPaired"}, - {7, nullptr, "StopBleScanForPaired"}, - {8, nullptr, "StartBleScanForSmartDevice"}, - {9, nullptr, "StopBleScanForSmartDevice"}, - {10, nullptr, "GetBleScanResultsForSmartDevice"}, - {17, &IBtmUserCore::AcquireBleConnectionEvent, "AcquireBleConnectionEvent"}, - {18, nullptr, "BleConnect"}, - {19, nullptr, "BleDisconnect"}, - {20, nullptr, "BleGetConnectionState"}, - {21, nullptr, "AcquireBlePairingEvent"}, - {22, nullptr, "BlePairDevice"}, - {23, nullptr, "BleUnPairDevice"}, - {24, nullptr, "BleUnPairDevice2"}, - {25, nullptr, "BleGetPairedDevices"}, - {26, &IBtmUserCore::AcquireBleServiceDiscoveryEvent, "AcquireBleServiceDiscoveryEvent"}, - {27, nullptr, "GetGattServices"}, - {28, nullptr, "GetGattService"}, - {29, nullptr, "GetGattIncludedServices"}, - {30, nullptr, "GetBelongingGattService"}, - {31, nullptr, "GetGattCharacteristics"}, - {32, nullptr, "GetGattDescriptors"}, - {33, &IBtmUserCore::AcquireBleMtuConfigEvent, "AcquireBleMtuConfigEvent"}, - {34, nullptr, "ConfigureBleMtu"}, - {35, nullptr, "GetBleMtu"}, - {36, nullptr, "RegisterBleGattDataPath"}, - {37, nullptr, "UnregisterBleGattDataPath"}, - }; - // clang-format on - RegisterHandlers(functions); - - scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent"); - connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent"); - service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent"); - config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent"); - } - - ~IBtmUserCore() override { - service_context.CloseEvent(scan_event); - service_context.CloseEvent(connection_event); - service_context.CloseEvent(service_discovery_event); - service_context.CloseEvent(config_event); - } - -private: - void AcquireBleScanEvent(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3, 1}; - rb.Push(ResultSuccess); - rb.Push(true); - rb.PushCopyObjects(scan_event->GetReadableEvent()); - } - - void AcquireBleConnectionEvent(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3, 1}; - rb.Push(ResultSuccess); - rb.Push(true); - rb.PushCopyObjects(connection_event->GetReadableEvent()); - } - - void AcquireBleServiceDiscoveryEvent(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3, 1}; - rb.Push(ResultSuccess); - rb.Push(true); - rb.PushCopyObjects(service_discovery_event->GetReadableEvent()); - } - - void AcquireBleMtuConfigEvent(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3, 1}; - rb.Push(ResultSuccess); - rb.Push(true); - rb.PushCopyObjects(config_event->GetReadableEvent()); - } - - KernelHelpers::ServiceContext service_context; - - Kernel::KEvent* scan_event; - Kernel::KEvent* connection_event; - Kernel::KEvent* service_discovery_event; - Kernel::KEvent* config_event; -}; - -class BTM_USR final : public ServiceFramework<BTM_USR> { -public: - explicit BTM_USR(Core::System& system_) : ServiceFramework{system_, "btm:u"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &BTM_USR::GetCore, "GetCore"}, - }; - // clang-format on - RegisterHandlers(functions); - } - -private: - void GetCore(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IBtmUserCore>(system); - } -}; - -class BTM final : public ServiceFramework<BTM> { -public: - explicit BTM(Core::System& system_) : ServiceFramework{system_, "btm"} { + explicit IBtm(Core::System& system_) : ServiceFramework{system_, "btm"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "GetState"}, @@ -232,144 +109,13 @@ public: } }; -class BTM_DBG final : public ServiceFramework<BTM_DBG> { -public: - explicit BTM_DBG(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "AcquireDiscoveryEvent"}, - {1, nullptr, "StartDiscovery"}, - {2, nullptr, "CancelDiscovery"}, - {3, nullptr, "GetDeviceProperty"}, - {4, nullptr, "CreateBond"}, - {5, nullptr, "CancelBond"}, - {6, nullptr, "SetTsiMode"}, - {7, nullptr, "GeneralTest"}, - {8, nullptr, "HidConnect"}, - {9, nullptr, "GeneralGet"}, - {10, nullptr, "GetGattClientDisconnectionReason"}, - {11, nullptr, "GetBleConnectionParameter"}, - {12, nullptr, "GetBleConnectionParameterRequest"}, - {13, nullptr, "Unknown13"}, - }; - // clang-format on - - RegisterHandlers(functions); - } -}; - -class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> { -public: - explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"}, - {1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"}, - {2, nullptr, "ClearGamepadPairingDatabase"}, - {3, nullptr, "GetPairedGamepadCount"}, - {4, nullptr, "EnableRadio"}, - {5, nullptr, "DisableRadio"}, - {6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"}, - {7, nullptr, "AcquireRadioEvent"}, - {8, nullptr, "AcquireGamepadPairingEvent"}, - {9, nullptr, "IsGamepadPairingStarted"}, - {10, nullptr, "StartAudioDeviceDiscovery"}, - {11, nullptr, "StopAudioDeviceDiscovery"}, - {12, nullptr, "IsDiscoveryingAudioDevice"}, - {13, nullptr, "GetDiscoveredAudioDevice"}, - {14, nullptr, "AcquireAudioDeviceConnectionEvent"}, - {15, nullptr, "ConnectAudioDevice"}, - {16, nullptr, "IsConnectingAudioDevice"}, - {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"}, - {18, nullptr, "DisconnectAudioDevice"}, - {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"}, - {20, &IBtmSystemCore::GetPairedAudioDevices, "GetPairedAudioDevices"}, - {21, nullptr, "RemoveAudioDevicePairing"}, - {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"}, - {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"} - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void IsRadioEnabled(HLERequestContext& ctx) { - LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(true); - } - - void StartGamepadPairing(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void CancelGamepadPairing(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetConnectedAudioDevices(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push<u32>(0); - } - - void GetPairedAudioDevices(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push<u32>(0); - } - - void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } -}; - -class BTM_SYS final : public ServiceFramework<BTM_SYS> { -public: - explicit BTM_SYS(Core::System& system_) : ServiceFramework{system_, "btm:sys"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &BTM_SYS::GetCore, "GetCore"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void GetCore(HLERequestContext& ctx) { - LOG_WARNING(Service_BTM, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IBtmSystemCore>(system); - } -}; - void LoopProcess(Core::System& system) { auto server_manager = std::make_unique<ServerManager>(system); - server_manager->RegisterNamedService("btm", std::make_shared<BTM>(system)); - server_manager->RegisterNamedService("btm:dbg", std::make_shared<BTM_DBG>(system)); - server_manager->RegisterNamedService("btm:sys", std::make_shared<BTM_SYS>(system)); - server_manager->RegisterNamedService("btm:u", std::make_shared<BTM_USR>(system)); + server_manager->RegisterNamedService("btm", std::make_shared<IBtm>(system)); + server_manager->RegisterNamedService("btm:dbg", std::make_shared<IBtmDebug>(system)); + server_manager->RegisterNamedService("btm:sys", std::make_shared<IBtmSystem>(system)); + server_manager->RegisterNamedService("btm:u", std::make_shared<IBtmUser>(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h index a99b34364..0bf77d053 100644 --- a/src/core/hle/service/btm/btm.h +++ b/src/core/hle/service/btm/btm.h @@ -3,10 +3,6 @@ #pragma once -namespace Service::SM { -class ServiceManager; -} - namespace Core { class System; }; diff --git a/src/core/hle/service/btm/btm_debug.cpp b/src/core/hle/service/btm/btm_debug.cpp new file mode 100644 index 000000000..4d61d2641 --- /dev/null +++ b/src/core/hle/service/btm/btm_debug.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/btm/btm_debug.h" + +namespace Service::BTM { + +IBtmDebug::IBtmDebug(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "AcquireDiscoveryEvent"}, + {1, nullptr, "StartDiscovery"}, + {2, nullptr, "CancelDiscovery"}, + {3, nullptr, "GetDeviceProperty"}, + {4, nullptr, "CreateBond"}, + {5, nullptr, "CancelBond"}, + {6, nullptr, "SetTsiMode"}, + {7, nullptr, "GeneralTest"}, + {8, nullptr, "HidConnect"}, + {9, nullptr, "GeneralGet"}, + {10, nullptr, "GetGattClientDisconnectionReason"}, + {11, nullptr, "GetBleConnectionParameter"}, + {12, nullptr, "GetBleConnectionParameterRequest"}, + {13, nullptr, "Unknown13"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IBtmDebug::~IBtmDebug() = default; + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_debug.h b/src/core/hle/service/btm/btm_debug.h new file mode 100644 index 000000000..bf4f7e14f --- /dev/null +++ b/src/core/hle/service/btm/btm_debug.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BTM { + +class IBtmDebug final : public ServiceFramework<IBtmDebug> { +public: + explicit IBtmDebug(Core::System& system_); + ~IBtmDebug() override; +}; + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_system.cpp b/src/core/hle/service/btm/btm_system.cpp new file mode 100644 index 000000000..99718a7b0 --- /dev/null +++ b/src/core/hle/service/btm/btm_system.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "common/logging/log.h" +#include "core/hle/service/btm/btm_system.h" +#include "core/hle/service/btm/btm_system_core.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/service.h" + +namespace Service::BTM { + +IBtmSystem::IBtmSystem(Core::System& system_) : ServiceFramework{system_, "btm:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IBtmSystem::GetCore>, "GetCore"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IBtmSystem::~IBtmSystem() = default; + +Result IBtmSystem::GetCore(OutInterface<IBtmSystemCore> out_interface) { + LOG_WARNING(Service_BTM, "called"); + + *out_interface = std::make_shared<IBtmSystemCore>(system); + R_SUCCEED(); +} + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_system.h b/src/core/hle/service/btm/btm_system.h new file mode 100644 index 000000000..fe1c6dbd7 --- /dev/null +++ b/src/core/hle/service/btm/btm_system.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BTM { +class IBtmSystemCore; + +class IBtmSystem final : public ServiceFramework<IBtmSystem> { +public: + explicit IBtmSystem(Core::System& system_); + ~IBtmSystem() override; + +private: + Result GetCore(OutInterface<IBtmSystemCore> out_interface); +}; + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_system_core.cpp b/src/core/hle/service/btm/btm_system_core.cpp new file mode 100644 index 000000000..4bc8a9e8b --- /dev/null +++ b/src/core/hle/service/btm/btm_system_core.cpp @@ -0,0 +1,127 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "common/logging/log.h" +#include "core/hle/service/btm/btm_system_core.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/set/system_settings_server.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::BTM { + +IBtmSystemCore::IBtmSystemCore(Core::System& system_) + : ServiceFramework{system_, "IBtmSystemCore"}, service_context{system_, "IBtmSystemCore"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IBtmSystemCore::StartGamepadPairing>, "StartGamepadPairing"}, + {1, C<&IBtmSystemCore::CancelGamepadPairing>, "CancelGamepadPairing"}, + {2, nullptr, "ClearGamepadPairingDatabase"}, + {3, nullptr, "GetPairedGamepadCount"}, + {4, C<&IBtmSystemCore::EnableRadio>, "EnableRadio"}, + {5, C<&IBtmSystemCore::DisableRadio>, "DisableRadio"}, + {6, C<&IBtmSystemCore::IsRadioEnabled>, "IsRadioEnabled"}, + {7, C<&IBtmSystemCore::AcquireRadioEvent>, "AcquireRadioEvent"}, + {8, nullptr, "AcquireGamepadPairingEvent"}, + {9, nullptr, "IsGamepadPairingStarted"}, + {10, nullptr, "StartAudioDeviceDiscovery"}, + {11, nullptr, "StopAudioDeviceDiscovery"}, + {12, nullptr, "IsDiscoveryingAudioDevice"}, + {13, nullptr, "GetDiscoveredAudioDevice"}, + {14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"}, + {15, nullptr, "ConnectAudioDevice"}, + {16, nullptr, "IsConnectingAudioDevice"}, + {17, C<&IBtmSystemCore::GetConnectedAudioDevices>, "GetConnectedAudioDevices"}, + {18, nullptr, "DisconnectAudioDevice"}, + {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"}, + {20, C<&IBtmSystemCore::GetPairedAudioDevices>, "GetPairedAudioDevices"}, + {21, nullptr, "RemoveAudioDevicePairing"}, + {22, C<&IBtmSystemCore::RequestAudioDeviceConnectionRejection>, "RequestAudioDeviceConnectionRejection"}, + {23, C<&IBtmSystemCore::CancelAudioDeviceConnectionRejection>, "CancelAudioDeviceConnectionRejection"} + }; + // clang-format on + + RegisterHandlers(functions); + radio_event = service_context.CreateEvent("IBtmSystemCore::RadioEvent"); + audio_device_connection_event = + service_context.CreateEvent("IBtmSystemCore::AudioDeviceConnectionEvent"); + + m_set_sys = + system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); +} + +IBtmSystemCore::~IBtmSystemCore() { + service_context.CloseEvent(radio_event); + service_context.CloseEvent(audio_device_connection_event); +} + +Result IBtmSystemCore::StartGamepadPairing() { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IBtmSystemCore::CancelGamepadPairing() { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IBtmSystemCore::EnableRadio() { + LOG_DEBUG(Service_BTM, "called"); + + R_RETURN(m_set_sys->SetBluetoothEnableFlag(true)); +} +Result IBtmSystemCore::DisableRadio() { + LOG_DEBUG(Service_BTM, "called"); + + R_RETURN(m_set_sys->SetBluetoothEnableFlag(false)); +} + +Result IBtmSystemCore::IsRadioEnabled(Out<bool> out_is_enabled) { + LOG_DEBUG(Service_BTM, "called"); + + R_RETURN(m_set_sys->GetBluetoothEnableFlag(out_is_enabled)); +} + +Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_is_valid = true; + *out_event = &radio_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent( + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_event = &audio_device_connection_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IBtmSystemCore::GetConnectedAudioDevices( + Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_count = 0; + R_SUCCEED(); +} + +Result IBtmSystemCore::GetPairedAudioDevices( + Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_count = 0; + R_SUCCEED(); +} + +Result IBtmSystemCore::RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) { + LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid); + R_SUCCEED(); +} + +Result IBtmSystemCore::CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) { + LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid); + R_SUCCEED(); +} + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_system_core.h b/src/core/hle/service/btm/btm_system_core.h new file mode 100644 index 000000000..06498b21e --- /dev/null +++ b/src/core/hle/service/btm/btm_system_core.h @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Core { +class System; +} + +namespace Service::Set { +class ISystemSettingsServer; +} + +namespace Service::BTM { + +class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> { +public: + explicit IBtmSystemCore(Core::System& system_); + ~IBtmSystemCore() override; + +private: + Result StartGamepadPairing(); + Result CancelGamepadPairing(); + Result EnableRadio(); + Result DisableRadio(); + Result IsRadioEnabled(Out<bool> out_is_enabled); + + Result AcquireRadioEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event); + + Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); + + Result GetConnectedAudioDevices( + Out<s32> out_count, + OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices); + + Result GetPairedAudioDevices( + Out<s32> out_count, + OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices); + + Result RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid); + Result CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid); + + KernelHelpers::ServiceContext service_context; + + Kernel::KEvent* radio_event; + Kernel::KEvent* audio_device_connection_event; + std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; +}; + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_user.cpp b/src/core/hle/service/btm/btm_user.cpp new file mode 100644 index 000000000..d2e228f8d --- /dev/null +++ b/src/core/hle/service/btm/btm_user.cpp @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "common/logging/log.h" +#include "core/hle/service/btm/btm_user.h" +#include "core/hle/service/btm/btm_user_core.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BTM { + +IBtmUser::IBtmUser(Core::System& system_) : ServiceFramework{system_, "btm:u"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IBtmUser::GetCore>, "GetCore"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IBtmUser::~IBtmUser() = default; + +Result IBtmUser::GetCore(OutInterface<IBtmUserCore> out_interface) { + LOG_WARNING(Service_BTM, "called"); + + *out_interface = std::make_shared<IBtmUserCore>(system); + R_SUCCEED(); +} + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_user.h b/src/core/hle/service/btm/btm_user.h new file mode 100644 index 000000000..d9ee5db45 --- /dev/null +++ b/src/core/hle/service/btm/btm_user.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BTM { +class IBtmUserCore; + +class IBtmUser final : public ServiceFramework<IBtmUser> { +public: + explicit IBtmUser(Core::System& system_); + ~IBtmUser() override; + +private: + Result GetCore(OutInterface<IBtmUserCore> out_interface); +}; + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_user_core.cpp b/src/core/hle/service/btm/btm_user_core.cpp new file mode 100644 index 000000000..6f9fa589b --- /dev/null +++ b/src/core/hle/service/btm/btm_user_core.cpp @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include <memory> + +#include "common/logging/log.h" +#include "core/core.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/service/btm/btm_user_core.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BTM { + +IBtmUserCore::IBtmUserCore(Core::System& system_) + : ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IBtmUserCore::AcquireBleScanEvent>, "AcquireBleScanEvent"}, + {1, nullptr, "GetBleScanFilterParameter"}, + {2, nullptr, "GetBleScanFilterParameter2"}, + {3, nullptr, "StartBleScanForGeneral"}, + {4, nullptr, "StopBleScanForGeneral"}, + {5, nullptr, "GetBleScanResultsForGeneral"}, + {6, nullptr, "StartBleScanForPaired"}, + {7, nullptr, "StopBleScanForPaired"}, + {8, nullptr, "StartBleScanForSmartDevice"}, + {9, nullptr, "StopBleScanForSmartDevice"}, + {10, nullptr, "GetBleScanResultsForSmartDevice"}, + {17, C<&IBtmUserCore::AcquireBleConnectionEvent>, "AcquireBleConnectionEvent"}, + {18, nullptr, "BleConnect"}, + {19, nullptr, "BleDisconnect"}, + {20, nullptr, "BleGetConnectionState"}, + {21, nullptr, "AcquireBlePairingEvent"}, + {22, nullptr, "BlePairDevice"}, + {23, nullptr, "BleUnPairDevice"}, + {24, nullptr, "BleUnPairDevice2"}, + {25, nullptr, "BleGetPairedDevices"}, + {26, C<&IBtmUserCore::AcquireBleServiceDiscoveryEvent>, "AcquireBleServiceDiscoveryEvent"}, + {27, nullptr, "GetGattServices"}, + {28, nullptr, "GetGattService"}, + {29, nullptr, "GetGattIncludedServices"}, + {30, nullptr, "GetBelongingGattService"}, + {31, nullptr, "GetGattCharacteristics"}, + {32, nullptr, "GetGattDescriptors"}, + {33, C<&IBtmUserCore::AcquireBleMtuConfigEvent>, "AcquireBleMtuConfigEvent"}, + {34, nullptr, "ConfigureBleMtu"}, + {35, nullptr, "GetBleMtu"}, + {36, nullptr, "RegisterBleGattDataPath"}, + {37, nullptr, "UnregisterBleGattDataPath"}, + }; + // clang-format on + RegisterHandlers(functions); + + scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent"); + connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent"); + service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent"); + config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent"); +} + +IBtmUserCore::~IBtmUserCore() { + service_context.CloseEvent(scan_event); + service_context.CloseEvent(connection_event); + service_context.CloseEvent(service_discovery_event); + service_context.CloseEvent(config_event); +} + +Result IBtmUserCore::AcquireBleScanEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_is_valid = true; + *out_event = &scan_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IBtmUserCore::AcquireBleConnectionEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_is_valid = true; + *out_event = &connection_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IBtmUserCore::AcquireBleServiceDiscoveryEvent( + Out<bool> out_is_valid, OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_is_valid = true; + *out_event = &service_discovery_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IBtmUserCore::AcquireBleMtuConfigEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + + *out_is_valid = true; + *out_event = &config_event->GetReadableEvent(); + R_SUCCEED(); +} + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm_user_core.h b/src/core/hle/service/btm/btm_user_core.h new file mode 100644 index 000000000..dc0a22e81 --- /dev/null +++ b/src/core/hle/service/btm/btm_user_core.h @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Core { +class System; +} + +namespace Service::BTM { + +class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { +public: + explicit IBtmUserCore(Core::System& system_); + ~IBtmUserCore() override; + +private: + Result AcquireBleScanEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event); + + Result AcquireBleConnectionEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event); + + Result AcquireBleServiceDiscoveryEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event); + + Result AcquireBleMtuConfigEvent(Out<bool> out_is_valid, + OutCopyHandle<Kernel::KReadableEvent> out_event); + + KernelHelpers::ServiceContext service_context; + + Kernel::KEvent* scan_event; + Kernel::KEvent* connection_event; + Kernel::KEvent* service_discovery_event; + Kernel::KEvent* config_event; +}; + +} // namespace Service::BTM diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp index 39690018b..8483394d0 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp @@ -3,82 +3,34 @@ #include "core/file_sys/fs_filesystem.h" #include "core/file_sys/savedata_factory.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/filesystem/fsp/fs_i_directory.h" -#include "core/hle/service/ipc_helpers.h" namespace Service::FileSystem { -template <typename T> -static void BuildEntryIndex(std::vector<FileSys::DirectoryEntry>& entries, - const std::vector<T>& new_data, FileSys::DirectoryEntryType type) { - entries.reserve(entries.size() + new_data.size()); - - for (const auto& new_entry : new_data) { - auto name = new_entry->GetName(); - - if (type == FileSys::DirectoryEntryType::File && - name == FileSys::GetSaveDataSizeFileName()) { - continue; - } - - entries.emplace_back(name, static_cast<s8>(type), - type == FileSys::DirectoryEntryType::Directory ? 0 - : new_entry->GetSize()); - } -} - -IDirectory::IDirectory(Core::System& system_, FileSys::VirtualDir backend_, +IDirectory::IDirectory(Core::System& system_, FileSys::VirtualDir directory_, FileSys::OpenDirectoryMode mode) - : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) { + : ServiceFramework{system_, "IDirectory"}, + backend(std::make_unique<FileSys::Fsa::IDirectory>(directory_, mode)) { static const FunctionInfo functions[] = { - {0, &IDirectory::Read, "Read"}, - {1, &IDirectory::GetEntryCount, "GetEntryCount"}, + {0, D<&IDirectory::Read>, "Read"}, + {1, D<&IDirectory::GetEntryCount>, "GetEntryCount"}, }; RegisterHandlers(functions); - - // TODO(DarkLordZach): Verify that this is the correct behavior. - // Build entry index now to save time later. - if (True(mode & FileSys::OpenDirectoryMode::Directory)) { - BuildEntryIndex(entries, backend->GetSubdirectories(), - FileSys::DirectoryEntryType::Directory); - } - if (True(mode & FileSys::OpenDirectoryMode::File)) { - BuildEntryIndex(entries, backend->GetFiles(), FileSys::DirectoryEntryType::File); - } } -void IDirectory::Read(HLERequestContext& ctx) { +Result IDirectory::Read( + Out<s64> out_count, + const OutArray<FileSys::DirectoryEntry, BufferAttr_HipcMapAlias> out_entries) { LOG_DEBUG(Service_FS, "called."); - // Calculate how many entries we can fit in the output buffer - const u64 count_entries = ctx.GetWriteBufferNumElements<FileSys::DirectoryEntry>(); - - // Cap at total number of entries. - const u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); - - // Determine data start and end - const auto* begin = reinterpret_cast<u8*>(entries.data() + next_entry_index); - const auto* end = reinterpret_cast<u8*>(entries.data() + next_entry_index + actual_entries); - const auto range_size = static_cast<std::size_t>(std::distance(begin, end)); - - next_entry_index += actual_entries; - - // Write the data to memory - ctx.WriteBuffer(begin, range_size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(actual_entries); + R_RETURN(backend->Read(out_count, out_entries.data(), out_entries.size())); } -void IDirectory::GetEntryCount(HLERequestContext& ctx) { +Result IDirectory::GetEntryCount(Out<s64> out_count) { LOG_DEBUG(Service_FS, "called"); - u64 count = entries.size() - next_entry_index; - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(count); + R_RETURN(backend->GetEntryCount(out_count)); } } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.h b/src/core/hle/service/filesystem/fsp/fs_i_directory.h index 793ecfcd7..b6251f7fd 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_directory.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.h @@ -3,7 +3,9 @@ #pragma once +#include "core/file_sys/fsa/fs_i_directory.h" #include "core/file_sys/vfs/vfs.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/service.h" @@ -15,16 +17,15 @@ namespace Service::FileSystem { class IDirectory final : public ServiceFramework<IDirectory> { public: - explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_, + explicit IDirectory(Core::System& system_, FileSys::VirtualDir directory_, FileSys::OpenDirectoryMode mode); private: - FileSys::VirtualDir backend; - std::vector<FileSys::DirectoryEntry> entries; - u64 next_entry_index = 0; + std::unique_ptr<FileSys::Fsa::IDirectory> backend; - void Read(HLERequestContext& ctx); - void GetEntryCount(HLERequestContext& ctx); + Result Read(Out<s64> out_count, + const OutArray<FileSys::DirectoryEntry, BufferAttr_HipcMapAlias> out_entries); + Result GetEntryCount(Out<s64> out_count); }; } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_file.cpp b/src/core/hle/service/filesystem/fsp/fs_i_file.cpp index 9a18f6ec5..a355d46ae 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_file.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.cpp @@ -2,126 +2,64 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/file_sys/errors.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/filesystem/fsp/fs_i_file.h" -#include "core/hle/service/ipc_helpers.h" namespace Service::FileSystem { -IFile::IFile(Core::System& system_, FileSys::VirtualFile backend_) - : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) { +IFile::IFile(Core::System& system_, FileSys::VirtualFile file_) + : ServiceFramework{system_, "IFile"}, backend{std::make_unique<FileSys::Fsa::IFile>(file_)} { + // clang-format off static const FunctionInfo functions[] = { - {0, &IFile::Read, "Read"}, - {1, &IFile::Write, "Write"}, - {2, &IFile::Flush, "Flush"}, - {3, &IFile::SetSize, "SetSize"}, - {4, &IFile::GetSize, "GetSize"}, + {0, D<&IFile::Read>, "Read"}, + {1, D<&IFile::Write>, "Write"}, + {2, D<&IFile::Flush>, "Flush"}, + {3, D<&IFile::SetSize>, "SetSize"}, + {4, D<&IFile::GetSize>, "GetSize"}, {5, nullptr, "OperateRange"}, {6, nullptr, "OperateRangeWithBuffer"}, }; + // clang-format on RegisterHandlers(functions); } -void IFile::Read(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const u64 option = rp.Pop<u64>(); - const s64 offset = rp.Pop<s64>(); - const s64 length = rp.Pop<s64>(); - - LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, length); - - // Error checking - if (length < 0) { - LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ResultInvalidSize); - return; - } - if (offset < 0) { - LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ResultInvalidOffset); - return; - } +Result IFile::Read( + FileSys::ReadOption option, Out<s64> out_size, s64 offset, + const OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer, + s64 size) { + LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option.value, offset, + size); // Read the data from the Storage backend - std::vector<u8> output = backend->ReadBytes(length, offset); - - // Write the data to memory - ctx.WriteBuffer(output); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(static_cast<u64>(output.size())); + R_RETURN( + backend->Read(reinterpret_cast<size_t*>(out_size.Get()), offset, out_buffer.data(), size)); } -void IFile::Write(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const u64 option = rp.Pop<u64>(); - const s64 offset = rp.Pop<s64>(); - const s64 length = rp.Pop<s64>(); - - LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, length); - - // Error checking - if (length < 0) { - LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ResultInvalidSize); - return; - } - if (offset < 0) { - LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ResultInvalidOffset); - return; - } - - const auto data = ctx.ReadBuffer(); +Result IFile::Write( + const InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> buffer, + FileSys::WriteOption option, s64 offset, s64 size) { + LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option.value, offset, + size); - ASSERT_MSG(static_cast<s64>(data.size()) <= length, - "Attempting to write more data than requested (requested={:016X}, actual={:016X}).", - length, data.size()); - - // Write the data to the Storage backend - const auto write_size = - static_cast<std::size_t>(std::distance(data.begin(), data.begin() + length)); - const std::size_t written = backend->Write(data.data(), write_size, offset); - - ASSERT_MSG(static_cast<s64>(written) == length, - "Could not write all bytes to file (requested={:016X}, actual={:016X}).", length, - written); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_RETURN(backend->Write(offset, buffer.data(), size, option)); } -void IFile::Flush(HLERequestContext& ctx) { +Result IFile::Flush() { LOG_DEBUG(Service_FS, "called"); - // Exists for SDK compatibiltity -- No need to flush file. - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_RETURN(backend->Flush()); } -void IFile::SetSize(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const u64 size = rp.Pop<u64>(); +Result IFile::SetSize(s64 size) { LOG_DEBUG(Service_FS, "called, size={}", size); - backend->Resize(size); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_RETURN(backend->SetSize(size)); } -void IFile::GetSize(HLERequestContext& ctx) { - const u64 size = backend->GetSize(); - LOG_DEBUG(Service_FS, "called, size={}", size); +Result IFile::GetSize(Out<s64> out_size) { + LOG_DEBUG(Service_FS, "called"); - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push<u64>(size); + R_RETURN(backend->GetSize(out_size)); } } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_file.h b/src/core/hle/service/filesystem/fsp/fs_i_file.h index 5e5430c67..e8599ee2f 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_file.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.h @@ -3,6 +3,8 @@ #pragma once +#include "core/file_sys/fsa/fs_i_file.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/service.h" @@ -10,16 +12,21 @@ namespace Service::FileSystem { class IFile final : public ServiceFramework<IFile> { public: - explicit IFile(Core::System& system_, FileSys::VirtualFile backend_); + explicit IFile(Core::System& system_, FileSys::VirtualFile file_); private: - FileSys::VirtualFile backend; + std::unique_ptr<FileSys::Fsa::IFile> backend; - void Read(HLERequestContext& ctx); - void Write(HLERequestContext& ctx); - void Flush(HLERequestContext& ctx); - void SetSize(HLERequestContext& ctx); - void GetSize(HLERequestContext& ctx); + Result Read(FileSys::ReadOption option, Out<s64> out_size, s64 offset, + const OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> + out_buffer, + s64 size); + Result Write( + const InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> buffer, + FileSys::WriteOption option, s64 offset, s64 size); + Result Flush(); + Result SetSize(s64 size); + Result GetSize(Out<s64> out_size); }; } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp index efa394dd1..d881e144d 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp @@ -2,261 +2,172 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/string_util.h" +#include "core/file_sys/fssrv/fssrv_sf_path.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/filesystem/fsp/fs_i_directory.h" #include "core/hle/service/filesystem/fsp/fs_i_file.h" #include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" -#include "core/hle/service/ipc_helpers.h" namespace Service::FileSystem { -IFileSystem::IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) - : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, size{std::move( - size_)} { +IFileSystem::IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_getter_) + : ServiceFramework{system_, "IFileSystem"}, backend{std::make_unique<FileSys::Fsa::IFileSystem>( + dir_)}, + size_getter{std::move(size_getter_)} { static const FunctionInfo functions[] = { - {0, &IFileSystem::CreateFile, "CreateFile"}, - {1, &IFileSystem::DeleteFile, "DeleteFile"}, - {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, - {3, &IFileSystem::DeleteDirectory, "DeleteDirectory"}, - {4, &IFileSystem::DeleteDirectoryRecursively, "DeleteDirectoryRecursively"}, - {5, &IFileSystem::RenameFile, "RenameFile"}, + {0, D<&IFileSystem::CreateFile>, "CreateFile"}, + {1, D<&IFileSystem::DeleteFile>, "DeleteFile"}, + {2, D<&IFileSystem::CreateDirectory>, "CreateDirectory"}, + {3, D<&IFileSystem::DeleteDirectory>, "DeleteDirectory"}, + {4, D<&IFileSystem::DeleteDirectoryRecursively>, "DeleteDirectoryRecursively"}, + {5, D<&IFileSystem::RenameFile>, "RenameFile"}, {6, nullptr, "RenameDirectory"}, - {7, &IFileSystem::GetEntryType, "GetEntryType"}, - {8, &IFileSystem::OpenFile, "OpenFile"}, - {9, &IFileSystem::OpenDirectory, "OpenDirectory"}, - {10, &IFileSystem::Commit, "Commit"}, - {11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"}, - {12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"}, - {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, - {14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"}, + {7, D<&IFileSystem::GetEntryType>, "GetEntryType"}, + {8, D<&IFileSystem::OpenFile>, "OpenFile"}, + {9, D<&IFileSystem::OpenDirectory>, "OpenDirectory"}, + {10, D<&IFileSystem::Commit>, "Commit"}, + {11, D<&IFileSystem::GetFreeSpaceSize>, "GetFreeSpaceSize"}, + {12, D<&IFileSystem::GetTotalSpaceSize>, "GetTotalSpaceSize"}, + {13, D<&IFileSystem::CleanDirectoryRecursively>, "CleanDirectoryRecursively"}, + {14, D<&IFileSystem::GetFileTimeStampRaw>, "GetFileTimeStampRaw"}, {15, nullptr, "QueryEntry"}, - {16, &IFileSystem::GetFileSystemAttribute, "GetFileSystemAttribute"}, + {16, D<&IFileSystem::GetFileSystemAttribute>, "GetFileSystemAttribute"}, }; RegisterHandlers(functions); } -void IFileSystem::CreateFile(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; +Result IFileSystem::CreateFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, + s32 option, s64 size) { + LOG_DEBUG(Service_FS, "called. file={}, option=0x{:X}, size=0x{:08X}", path->str, option, size); - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - const u64 file_mode = rp.Pop<u64>(); - const u32 file_size = rp.Pop<u32>(); - - LOG_DEBUG(Service_FS, "called. file={}, mode=0x{:X}, size=0x{:08X}", name, file_mode, - file_size); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CreateFile(name, file_size)); + R_RETURN(backend->CreateFile(FileSys::Path(path->str), size)); } -void IFileSystem::DeleteFile(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); +Result IFileSystem::DeleteFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { + LOG_DEBUG(Service_FS, "called. file={}", path->str); - LOG_DEBUG(Service_FS, "called. file={}", name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.DeleteFile(name)); + R_RETURN(backend->DeleteFile(FileSys::Path(path->str))); } -void IFileSystem::CreateDirectory(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. directory={}", name); +Result IFileSystem::CreateDirectory( + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { + LOG_DEBUG(Service_FS, "called. directory={}", path->str); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CreateDirectory(name)); + R_RETURN(backend->CreateDirectory(FileSys::Path(path->str))); } -void IFileSystem::DeleteDirectory(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. directory={}", name); +Result IFileSystem::DeleteDirectory( + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { + LOG_DEBUG(Service_FS, "called. directory={}", path->str); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.DeleteDirectory(name)); + R_RETURN(backend->DeleteDirectory(FileSys::Path(path->str))); } -void IFileSystem::DeleteDirectoryRecursively(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); +Result IFileSystem::DeleteDirectoryRecursively( + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { + LOG_DEBUG(Service_FS, "called. directory={}", path->str); - LOG_DEBUG(Service_FS, "called. directory={}", name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.DeleteDirectoryRecursively(name)); + R_RETURN(backend->DeleteDirectoryRecursively(FileSys::Path(path->str))); } -void IFileSystem::CleanDirectoryRecursively(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. Directory: {}", name); +Result IFileSystem::CleanDirectoryRecursively( + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { + LOG_DEBUG(Service_FS, "called. Directory: {}", path->str); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CleanDirectoryRecursively(name)); + R_RETURN(backend->CleanDirectoryRecursively(FileSys::Path(path->str))); } -void IFileSystem::RenameFile(HLERequestContext& ctx) { - const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0)); - const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1)); - - LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name); +Result IFileSystem::RenameFile( + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> old_path, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> new_path) { + LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", old_path->str, new_path->str); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.RenameFile(src_name, dst_name)); + R_RETURN(backend->RenameFile(FileSys::Path(old_path->str), FileSys::Path(new_path->str))); } -void IFileSystem::OpenFile(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - const auto mode = static_cast<FileSys::OpenMode>(rp.Pop<u32>()); - - LOG_DEBUG(Service_FS, "called. file={}, mode={}", name, mode); +Result IFileSystem::OpenFile(OutInterface<IFile> out_interface, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, + u32 mode) { + LOG_DEBUG(Service_FS, "called. file={}, mode={}", path->str, mode); FileSys::VirtualFile vfs_file{}; - auto result = backend.OpenFile(&vfs_file, name, mode); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - auto file = std::make_shared<IFile>(system, vfs_file); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IFile>(std::move(file)); -} - -void IFileSystem::OpenDirectory(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; + R_TRY(backend->OpenFile(&vfs_file, FileSys::Path(path->str), + static_cast<FileSys::OpenMode>(mode))); - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - const auto mode = rp.PopRaw<FileSys::OpenDirectoryMode>(); + *out_interface = std::make_shared<IFile>(system, vfs_file); + R_SUCCEED(); +} - LOG_DEBUG(Service_FS, "called. directory={}, mode={}", name, mode); +Result IFileSystem::OpenDirectory(OutInterface<IDirectory> out_interface, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, + u32 mode) { + LOG_DEBUG(Service_FS, "called. directory={}, mode={}", path->str, mode); FileSys::VirtualDir vfs_dir{}; - auto result = backend.OpenDirectory(&vfs_dir, name); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - auto directory = std::make_shared<IDirectory>(system, vfs_dir, mode); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IDirectory>(std::move(directory)); -} + R_TRY(backend->OpenDirectory(&vfs_dir, FileSys::Path(path->str), + static_cast<FileSys::OpenDirectoryMode>(mode))); -void IFileSystem::GetEntryType(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); + *out_interface = std::make_shared<IDirectory>(system, vfs_dir, + static_cast<FileSys::OpenDirectoryMode>(mode)); + R_SUCCEED(); +} - LOG_DEBUG(Service_FS, "called. file={}", name); +Result IFileSystem::GetEntryType( + Out<u32> out_type, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { + LOG_DEBUG(Service_FS, "called. file={}", path->str); FileSys::DirectoryEntryType vfs_entry_type{}; - auto result = backend.GetEntryType(&vfs_entry_type, name); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push<u32>(static_cast<u32>(vfs_entry_type)); + R_TRY(backend->GetEntryType(&vfs_entry_type, FileSys::Path(path->str))); + + *out_type = static_cast<u32>(vfs_entry_type); + R_SUCCEED(); } -void IFileSystem::Commit(HLERequestContext& ctx) { +Result IFileSystem::Commit() { LOG_WARNING(Service_FS, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_SUCCEED(); } -void IFileSystem::GetFreeSpaceSize(HLERequestContext& ctx) { +Result IFileSystem::GetFreeSpaceSize( + Out<s64> out_size, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { LOG_DEBUG(Service_FS, "called"); - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(size.get_free_size()); + *out_size = size_getter.get_free_size(); + R_SUCCEED(); } -void IFileSystem::GetTotalSpaceSize(HLERequestContext& ctx) { +Result IFileSystem::GetTotalSpaceSize( + Out<s64> out_size, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { LOG_DEBUG(Service_FS, "called"); - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(size.get_total_size()); + *out_size = size_getter.get_total_size(); + R_SUCCEED(); } -void IFileSystem::GetFileTimeStampRaw(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", name); +Result IFileSystem::GetFileTimeStampRaw( + Out<FileSys::FileTimeStampRaw> out_timestamp, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { + LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", path->str); FileSys::FileTimeStampRaw vfs_timestamp{}; - auto result = backend.GetFileTimeStampRaw(&vfs_timestamp, name); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - IPC::ResponseBuilder rb{ctx, 10}; - rb.Push(ResultSuccess); - rb.PushRaw(vfs_timestamp); + R_TRY(backend->GetFileTimeStampRaw(&vfs_timestamp, FileSys::Path(path->str))); + + *out_timestamp = vfs_timestamp; + R_SUCCEED(); } -void IFileSystem::GetFileSystemAttribute(HLERequestContext& ctx) { +Result IFileSystem::GetFileSystemAttribute(Out<FileSys::FileSystemAttribute> out_attribute) { LOG_WARNING(Service_FS, "(STUBBED) called"); - struct FileSystemAttribute { - u8 dir_entry_name_length_max_defined; - u8 file_entry_name_length_max_defined; - u8 dir_path_name_length_max_defined; - u8 file_path_name_length_max_defined; - INSERT_PADDING_BYTES_NOINIT(0x5); - u8 utf16_dir_entry_name_length_max_defined; - u8 utf16_file_entry_name_length_max_defined; - u8 utf16_dir_path_name_length_max_defined; - u8 utf16_file_path_name_length_max_defined; - INSERT_PADDING_BYTES_NOINIT(0x18); - s32 dir_entry_name_length_max; - s32 file_entry_name_length_max; - s32 dir_path_name_length_max; - s32 file_path_name_length_max; - INSERT_PADDING_WORDS_NOINIT(0x5); - s32 utf16_dir_entry_name_length_max; - s32 utf16_file_entry_name_length_max; - s32 utf16_dir_path_name_length_max; - s32 utf16_file_path_name_length_max; - INSERT_PADDING_WORDS_NOINIT(0x18); - INSERT_PADDING_WORDS_NOINIT(0x1); - }; - static_assert(sizeof(FileSystemAttribute) == 0xc0, "FileSystemAttribute has incorrect size"); - - FileSystemAttribute savedata_attribute{}; + FileSys::FileSystemAttribute savedata_attribute{}; savedata_attribute.dir_entry_name_length_max_defined = true; savedata_attribute.file_entry_name_length_max_defined = true; savedata_attribute.dir_entry_name_length_max = 0x40; savedata_attribute.file_entry_name_length_max = 0x40; - IPC::ResponseBuilder rb{ctx, 50}; - rb.Push(ResultSuccess); - rb.PushRaw(savedata_attribute); + *out_attribute = savedata_attribute; + R_SUCCEED(); } } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h index b1f3ab5dd..dd069f36f 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h @@ -3,36 +3,58 @@ #pragma once +#include "common/common_funcs.h" +#include "core/file_sys/fs_filesystem.h" +#include "core/file_sys/fsa/fs_i_filesystem.h" #include "core/file_sys/vfs/vfs.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/fsp/fsp_types.h" #include "core/hle/service/service.h" +namespace FileSys::Sf { +struct Path; +} + namespace Service::FileSystem { +class IFile; +class IDirectory; + class IFileSystem final : public ServiceFramework<IFileSystem> { public: - explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_); - - void CreateFile(HLERequestContext& ctx); - void DeleteFile(HLERequestContext& ctx); - void CreateDirectory(HLERequestContext& ctx); - void DeleteDirectory(HLERequestContext& ctx); - void DeleteDirectoryRecursively(HLERequestContext& ctx); - void CleanDirectoryRecursively(HLERequestContext& ctx); - void RenameFile(HLERequestContext& ctx); - void OpenFile(HLERequestContext& ctx); - void OpenDirectory(HLERequestContext& ctx); - void GetEntryType(HLERequestContext& ctx); - void Commit(HLERequestContext& ctx); - void GetFreeSpaceSize(HLERequestContext& ctx); - void GetTotalSpaceSize(HLERequestContext& ctx); - void GetFileTimeStampRaw(HLERequestContext& ctx); - void GetFileSystemAttribute(HLERequestContext& ctx); + explicit IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_getter_); + + Result CreateFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, s32 option, + s64 size); + Result DeleteFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result CreateDirectory(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result DeleteDirectory(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result DeleteDirectoryRecursively( + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result CleanDirectoryRecursively( + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result RenameFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> old_path, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> new_path); + Result OpenFile(OutInterface<IFile> out_interface, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, u32 mode); + Result OpenDirectory(OutInterface<IDirectory> out_interface, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, + u32 mode); + Result GetEntryType(Out<u32> out_type, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result Commit(); + Result GetFreeSpaceSize(Out<s64> out_size, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result GetTotalSpaceSize(Out<s64> out_size, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result GetFileTimeStampRaw(Out<FileSys::FileTimeStampRaw> out_timestamp, + const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); + Result GetFileSystemAttribute(Out<FileSys::FileSystemAttribute> out_attribute); private: - VfsDirectoryServiceWrapper backend; - SizeGetter size; + std::unique_ptr<FileSys::Fsa::IFileSystem> backend; + SizeGetter size_getter; }; } // namespace Service::FileSystem diff --git a/src/core/hle/service/ns/application_manager_interface.cpp b/src/core/hle/service/ns/application_manager_interface.cpp index 2e3a44c0d..7a91727f9 100644 --- a/src/core/hle/service/ns/application_manager_interface.cpp +++ b/src/core/hle/service/ns/application_manager_interface.cpp @@ -436,14 +436,14 @@ Result IApplicationManagerInterface::GetApplicationViewWithPromotionInfo( Result IApplicationManagerInterface::GetApplicationRightsOnClient( OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count, - Common::UUID account_id, u32 flags, u64 application_id) { + u32 flags, u64 application_id, Uid account_id) { LOG_WARNING(Service_NS, "(STUBBED) called, flags={}, application_id={:016X}, account_id={}", - flags, application_id, account_id.FormattedString()); + flags, application_id, account_id.uuid.FormattedString()); if (!out_rights.empty()) { ApplicationRightsOnClient rights{}; rights.application_id = application_id; - rights.uid = account_id; + rights.uid = account_id.uuid; rights.flags = 0; rights.flags2 = 0; diff --git a/src/core/hle/service/ns/application_manager_interface.h b/src/core/hle/service/ns/application_manager_interface.h index 350ec37ce..f33d269b3 100644 --- a/src/core/hle/service/ns/application_manager_interface.h +++ b/src/core/hle/service/ns/application_manager_interface.h @@ -37,7 +37,7 @@ public: InArray<u64, BufferAttr_HipcMapAlias> application_ids); Result GetApplicationRightsOnClient( OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count, - Common::UUID account_id, u32 flags, u64 application_id); + u32 flags, u64 application_id, Uid account_id); Result CheckSdCardMountStatus(); Result GetSdCardMountStatusChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); Result GetFreeSpaceSize(Out<s64> out_free_space_size, FileSys::StorageId storage_id); diff --git a/src/core/hle/service/ns/ns_types.h b/src/core/hle/service/ns/ns_types.h index 38421b0f4..2dd664c4e 100644 --- a/src/core/hle/service/ns/ns_types.h +++ b/src/core/hle/service/ns/ns_types.h @@ -108,4 +108,9 @@ struct ContentPath { }; static_assert(sizeof(ContentPath) == 0x10, "ContentPath has incorrect size."); +struct Uid { + alignas(8) Common::UUID uuid; +}; +static_assert(sizeof(Uid) == 0x10, "Uid has incorrect size."); + } // namespace Service::NS diff --git a/src/core/hle/service/ns/query_service.cpp b/src/core/hle/service/ns/query_service.cpp index 946b7fa23..138400541 100644 --- a/src/core/hle/service/ns/query_service.cpp +++ b/src/core/hle/service/ns/query_service.cpp @@ -41,8 +41,7 @@ IQueryService::IQueryService(Core::System& system_) : ServiceFramework{system_, IQueryService::~IQueryService() = default; Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId( - Out<PlayStatistics> out_play_statistics, bool unknown, Common::UUID account_id, - u64 application_id) { + Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id) { // TODO(German77): Read statistics of the game *out_play_statistics = { .application_id = application_id, @@ -50,7 +49,7 @@ Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId( }; LOG_WARNING(Service_NS, "(STUBBED) called. unknown={}. application_id={:016X}, account_id={}", - unknown, application_id, account_id.FormattedString()); + unknown, application_id, account_id.uuid.FormattedString()); R_SUCCEED(); } diff --git a/src/core/hle/service/ns/query_service.h b/src/core/hle/service/ns/query_service.h index 6cdbfa277..c4c82b752 100644 --- a/src/core/hle/service/ns/query_service.h +++ b/src/core/hle/service/ns/query_service.h @@ -5,6 +5,7 @@ #include "common/uuid.h" #include "core/hle/service/cmif_types.h" +#include "core/hle/service/ns/ns_types.h" #include "core/hle/service/service.h" namespace Service::NS { @@ -29,8 +30,7 @@ public: private: Result QueryPlayStatisticsByApplicationIdAndUserAccountId( - Out<PlayStatistics> out_play_statistics, bool unknown, Common::UUID account_id, - u64 application_id); + Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id); }; } // namespace Service::NS diff --git a/src/core/hle/service/nvnflinger/display.h b/src/core/hle/service/nvnflinger/display.h index f27cbf144..40aa59787 100644 --- a/src/core/hle/service/nvnflinger/display.h +++ b/src/core/hle/service/nvnflinger/display.h @@ -3,8 +3,6 @@ #pragma once -#include <list> - #include "core/hle/service/nvnflinger/buffer_item_consumer.h" #include "core/hle/service/nvnflinger/hwc_layer.h" @@ -26,18 +24,12 @@ struct Layer { }; struct LayerStack { - std::list<Layer> layers; -}; - -struct Display { - explicit Display(u64 id_) { - id = id_; - } + std::vector<std::shared_ptr<Layer>> layers; - Layer* FindLayer(s32 consumer_id) { - for (auto& layer : stack.layers) { - if (layer.consumer_id == consumer_id) { - return &layer; + std::shared_ptr<Layer> FindLayer(s32 consumer_id) { + for (auto& layer : layers) { + if (layer->consumer_id == consumer_id) { + return layer; } } @@ -45,7 +37,13 @@ struct Display { } bool HasLayers() { - return !stack.layers.empty(); + return !layers.empty(); + } +}; + +struct Display { + explicit Display(u64 id_) { + id = id_; } u64 id; diff --git a/src/core/hle/service/nvnflinger/hardware_composer.cpp b/src/core/hle/service/nvnflinger/hardware_composer.cpp index 02215a786..f2dfe85a9 100644 --- a/src/core/hle/service/nvnflinger/hardware_composer.cpp +++ b/src/core/hle/service/nvnflinger/hardware_composer.cpp @@ -55,10 +55,10 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, // Acquire all necessary framebuffers. for (auto& layer : display.stack.layers) { - auto consumer_id = layer.consumer_id; + auto consumer_id = layer->consumer_id; // Try to fetch the framebuffer (either new or stale). - const auto result = this->CacheFramebufferLocked(layer, consumer_id); + const auto result = this->CacheFramebufferLocked(*layer, consumer_id); // If we failed, skip this layer. if (result == CacheStatus::NoBufferAvailable) { @@ -75,7 +75,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, const auto& igbp_buffer = *item.graphic_buffer; // TODO: get proper Z-index from layer - if (layer.visible) { + if (layer->visible) { composition_stack.emplace_back(HwcLayer{ .buffer_handle = igbp_buffer.BufferId(), .offset = igbp_buffer.Offset(), @@ -84,7 +84,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, .height = igbp_buffer.Height(), .stride = igbp_buffer.Stride(), .z_index = 0, - .blending = layer.blending, + .blending = layer->blending, .transform = static_cast<android::BufferTransformFlags>(item.transform), .crop_rect = item.crop, .acquire_fence = item.fence, @@ -134,7 +134,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, continue; } - if (auto* layer = display.FindLayer(layer_id); layer != nullptr) { + if (const auto layer = display.stack.FindLayer(layer_id); layer != nullptr) { // TODO: support release fence // This is needed to prevent screen tearing layer->buffer_item_consumer->ReleaseBuffer(framebuffer.item, android::Fence::NoFence()); @@ -153,7 +153,7 @@ void HardwareComposer::RemoveLayerLocked(Display& display, ConsumerId consumer_i } // Try to release the buffer item. - auto* const layer = display.FindLayer(consumer_id); + const auto layer = display.stack.FindLayer(consumer_id); if (layer && it->second.is_acquired) { layer->buffer_item_consumer->ReleaseBuffer(it->second.item, android::Fence::NoFence()); } diff --git a/src/core/hle/service/nvnflinger/surface_flinger.cpp b/src/core/hle/service/nvnflinger/surface_flinger.cpp index 41a705717..8362b65e5 100644 --- a/src/core/hle/service/nvnflinger/surface_flinger.cpp +++ b/src/core/hle/service/nvnflinger/surface_flinger.cpp @@ -36,7 +36,7 @@ void SurfaceFlinger::RemoveDisplay(u64 display_id) { bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id) { auto* const display = this->FindDisplay(display_id); - if (!display || !display->HasLayers()) { + if (!display || !display->stack.HasLayers()) { return false; } @@ -46,19 +46,34 @@ bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_spe return true; } -void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) { - auto* const display = this->FindDisplay(display_id); +void SurfaceFlinger::CreateLayer(s32 consumer_binder_id) { auto binder = std::static_pointer_cast<android::BufferQueueConsumer>( m_server.TryGetBinder(consumer_binder_id)); - - if (!display || !binder) { + if (!binder) { return; } auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(binder)); buffer_item_consumer->Connect(false); - display->stack.layers.emplace_back(std::move(buffer_item_consumer), consumer_binder_id); + m_layers.layers.emplace_back( + std::make_shared<Layer>(std::move(buffer_item_consumer), consumer_binder_id)); +} + +void SurfaceFlinger::DestroyLayer(s32 consumer_binder_id) { + std::erase_if(m_layers.layers, + [&](auto& layer) { return layer->consumer_id == consumer_binder_id; }); +} + +void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) { + auto* const display = this->FindDisplay(display_id); + auto layer = this->FindLayer(consumer_binder_id); + + if (!display || !layer) { + return; + } + + display->stack.layers.emplace_back(std::move(layer)); } void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id) { @@ -69,18 +84,18 @@ void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_bi m_composer.RemoveLayerLocked(*display, consumer_binder_id); std::erase_if(display->stack.layers, - [&](auto& layer) { return layer.consumer_id == consumer_binder_id; }); + [&](auto& layer) { return layer->consumer_id == consumer_binder_id; }); } void SurfaceFlinger::SetLayerVisibility(s32 consumer_binder_id, bool visible) { - if (auto* layer = this->FindLayer(consumer_binder_id); layer != nullptr) { + if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) { layer->visible = visible; return; } } void SurfaceFlinger::SetLayerBlending(s32 consumer_binder_id, LayerBlending blending) { - if (auto* layer = this->FindLayer(consumer_binder_id); layer != nullptr) { + if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) { layer->blending = blending; return; } @@ -96,9 +111,9 @@ Display* SurfaceFlinger::FindDisplay(u64 display_id) { return nullptr; } -Layer* SurfaceFlinger::FindLayer(s32 consumer_binder_id) { - for (auto& display : m_displays) { - if (auto* layer = display.FindLayer(consumer_binder_id); layer != nullptr) { +std::shared_ptr<Layer> SurfaceFlinger::FindLayer(s32 consumer_binder_id) { + for (auto& layer : m_layers.layers) { + if (layer->consumer_id == consumer_binder_id) { return layer; } } diff --git a/src/core/hle/service/nvnflinger/surface_flinger.h b/src/core/hle/service/nvnflinger/surface_flinger.h index d8c53fbda..406281c83 100644 --- a/src/core/hle/service/nvnflinger/surface_flinger.h +++ b/src/core/hle/service/nvnflinger/surface_flinger.h @@ -36,6 +36,9 @@ public: void RemoveDisplay(u64 display_id); bool ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id); + void CreateLayer(s32 consumer_binder_id); + void DestroyLayer(s32 consumer_binder_id); + void AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id); void RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id); @@ -44,7 +47,7 @@ public: private: Display* FindDisplay(u64 display_id); - Layer* FindLayer(s32 consumer_binder_id); + std::shared_ptr<Layer> FindLayer(s32 consumer_binder_id); public: // TODO: these don't belong here @@ -57,6 +60,7 @@ private: KernelHelpers::ServiceContext m_context; std::vector<Display> m_displays; + LayerStack m_layers; std::shared_ptr<Nvidia::Module> nvdrv; s32 disp_fd; HardwareComposer m_composer; diff --git a/src/core/hle/service/psc/ovln/ovln_types.h b/src/core/hle/service/psc/ovln/ovln_types.h new file mode 100644 index 000000000..343b05dcc --- /dev/null +++ b/src/core/hle/service/psc/ovln/ovln_types.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/bit_field.h" +#include "common/common_types.h" + +namespace Service::PSC { + +using OverlayNotification = std::array<u64, 0x10>; +static_assert(sizeof(OverlayNotification) == 0x80, "OverlayNotification has incorrect size"); + +union MessageFlags { + u64 raw; + BitField<0, 8, u64> message_type; + BitField<8, 8, u64> queue_type; +}; +static_assert(sizeof(MessageFlags) == 0x8, "MessageFlags has incorrect size"); + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/receiver.cpp b/src/core/hle/service/psc/ovln/receiver.cpp new file mode 100644 index 000000000..85f62816d --- /dev/null +++ b/src/core/hle/service/psc/ovln/receiver.cpp @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/psc/ovln/receiver.h" + +namespace Service::PSC { + +IReceiver::IReceiver(Core::System& system_) : ServiceFramework{system_, "IReceiver"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "AddSource"}, + {1, nullptr, "RemoveSource"}, + {2, nullptr, "GetReceiveEventHandle"}, + {3, nullptr, "Receive"}, + {4, nullptr, "ReceiveWithTick"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IReceiver::~IReceiver() = default; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/receiver.h b/src/core/hle/service/psc/ovln/receiver.h new file mode 100644 index 000000000..c47a4ff7e --- /dev/null +++ b/src/core/hle/service/psc/ovln/receiver.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::PSC { + +class IReceiver final : public ServiceFramework<IReceiver> { +public: + explicit IReceiver(Core::System& system_); + ~IReceiver() override; +}; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/receiver_service.cpp b/src/core/hle/service/psc/ovln/receiver_service.cpp new file mode 100644 index 000000000..bb988e905 --- /dev/null +++ b/src/core/hle/service/psc/ovln/receiver_service.cpp @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/psc/ovln/receiver.h" +#include "core/hle/service/psc/ovln/receiver_service.h" + +namespace Service::PSC { + +IReceiverService::IReceiverService(Core::System& system_) : ServiceFramework{system_, "ovln:rcv"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&IReceiverService::OpenReceiver>, "OpenReceiver"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IReceiverService::~IReceiverService() = default; + +Result IReceiverService::OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver) { + LOG_DEBUG(Service_PSC, "called"); + *out_receiver = std::make_shared<IReceiver>(system); + R_SUCCEED(); +} + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/receiver_service.h b/src/core/hle/service/psc/ovln/receiver_service.h new file mode 100644 index 000000000..b3b31ba4a --- /dev/null +++ b/src/core/hle/service/psc/ovln/receiver_service.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Service::PSC { + +class IReceiver; + +class IReceiverService final : public ServiceFramework<IReceiverService> { +public: + explicit IReceiverService(Core::System& system_); + ~IReceiverService() override; + +private: + Result OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver); +}; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/sender.cpp b/src/core/hle/service/psc/ovln/sender.cpp new file mode 100644 index 000000000..3227a56f2 --- /dev/null +++ b/src/core/hle/service/psc/ovln/sender.cpp @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/psc/ovln/sender.h" + +namespace Service::PSC { + +ISender::ISender(Core::System& system_) : ServiceFramework{system_, "ISender"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&ISender::Send>, "Send"}, + {1, nullptr, "GetUnreceivedMessageCount"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISender::~ISender() = default; + +Result ISender::Send(const OverlayNotification& notification, MessageFlags flags) { + std::string data; + for (const auto m : notification) { + data += fmt::format("{:016X} ", m); + } + + LOG_WARNING(Service_PSC, "(STUBBED) called, flags={} notification={}", flags.raw, data); + R_SUCCEED(); +} + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/sender.h b/src/core/hle/service/psc/ovln/sender.h new file mode 100644 index 000000000..c1575428e --- /dev/null +++ b/src/core/hle/service/psc/ovln/sender.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/psc/ovln/ovln_types.h" +#include "core/hle/service/service.h" + +namespace Service::PSC { + +class ISender final : public ServiceFramework<ISender> { +public: + explicit ISender(Core::System& system_); + ~ISender() override; + +private: + Result Send(const OverlayNotification& notification, MessageFlags flags); +}; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/sender_service.cpp b/src/core/hle/service/psc/ovln/sender_service.cpp new file mode 100644 index 000000000..18d2c83a3 --- /dev/null +++ b/src/core/hle/service/psc/ovln/sender_service.cpp @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/psc/ovln/sender.h" +#include "core/hle/service/psc/ovln/sender_service.h" + +namespace Service::PSC { + +ISenderService::ISenderService(Core::System& system_) : ServiceFramework{system_, "ovln:snd"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&ISenderService::OpenSender>, "OpenSender"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISenderService::~ISenderService() = default; + +Result ISenderService::OpenSender(Out<SharedPointer<ISender>> out_sender, u32 sender_id, + std::array<u64, 2> data) { + LOG_WARNING(Service_PSC, "(STUBBED) called, sender_id={}, data={:016X} {:016X}", sender_id, + data[0], data[1]); + *out_sender = std::make_shared<ISender>(system); + R_SUCCEED(); +} + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/ovln/sender_service.h b/src/core/hle/service/psc/ovln/sender_service.h new file mode 100644 index 000000000..10027701f --- /dev/null +++ b/src/core/hle/service/psc/ovln/sender_service.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Service::PSC { + +class ISender; + +class ISenderService final : public ServiceFramework<ISenderService> { +public: + explicit ISenderService(Core::System& system_); + ~ISenderService() override; + +private: + Result OpenSender(Out<SharedPointer<ISender>> out_sender, u32 sender_id, + std::array<u64, 2> data); +}; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/pm_control.cpp b/src/core/hle/service/psc/pm_control.cpp new file mode 100644 index 000000000..7dedb7662 --- /dev/null +++ b/src/core/hle/service/psc/pm_control.cpp @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/psc/pm_control.h" + +namespace Service::PSC { + +IPmControl::IPmControl(Core::System& system_) : ServiceFramework{system_, "psc:c"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "DispatchRequest"}, + {2, nullptr, "GetResult"}, + {3, nullptr, "GetState"}, + {4, nullptr, "Cancel"}, + {5, nullptr, "PrintModuleInformation"}, + {6, nullptr, "GetModuleInformation"}, + {10, nullptr, "AcquireStateLock"}, + {11, nullptr, "HasStateLock"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IPmControl::~IPmControl() = default; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/pm_control.h b/src/core/hle/service/psc/pm_control.h new file mode 100644 index 000000000..e0ae2f39c --- /dev/null +++ b/src/core/hle/service/psc/pm_control.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::PSC { + +class IPmControl final : public ServiceFramework<IPmControl> { +public: + explicit IPmControl(Core::System& system_); + ~IPmControl() override; +}; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/pm_module.cpp b/src/core/hle/service/psc/pm_module.cpp new file mode 100644 index 000000000..74dc7ed4e --- /dev/null +++ b/src/core/hle/service/psc/pm_module.cpp @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/psc/pm_module.h" + +namespace Service::PSC { + +IPmModule::IPmModule(Core::System& system_) : ServiceFramework{system_, "IPmModule"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "GetRequest"}, + {2, nullptr, "Acknowledge"}, + {3, nullptr, "Finalize"}, + {4, nullptr, "AcknowledgeEx"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IPmModule::~IPmModule() = default; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/pm_module.h b/src/core/hle/service/psc/pm_module.h new file mode 100644 index 000000000..b3a2d2584 --- /dev/null +++ b/src/core/hle/service/psc/pm_module.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::PSC { + +class IPmModule final : public ServiceFramework<IPmModule> { +public: + explicit IPmModule(Core::System& system_); + ~IPmModule() override; +}; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/pm_service.cpp b/src/core/hle/service/psc/pm_service.cpp new file mode 100644 index 000000000..c4e0ad228 --- /dev/null +++ b/src/core/hle/service/psc/pm_service.cpp @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/psc/pm_module.h" +#include "core/hle/service/psc/pm_service.h" + +namespace Service::PSC { + +IPmService::IPmService(Core::System& system_) : ServiceFramework{system_, "psc:m"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&IPmService::GetPmModule>, "GetPmModule"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IPmService::~IPmService() = default; + +Result IPmService::GetPmModule(Out<SharedPointer<IPmModule>> out_module) { + LOG_DEBUG(Service_PSC, "called"); + *out_module = std::make_shared<IPmModule>(system); + R_SUCCEED(); +} + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/pm_service.h b/src/core/hle/service/psc/pm_service.h new file mode 100644 index 000000000..08e14c6f8 --- /dev/null +++ b/src/core/hle/service/psc/pm_service.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Service::PSC { + +class IPmModule; + +class IPmService final : public ServiceFramework<IPmService> { +public: + explicit IPmService(Core::System& system_); + ~IPmService() override; + +private: + Result GetPmModule(Out<SharedPointer<IPmModule>> out_module); +}; + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp index 44310756b..e1762d694 100644 --- a/src/core/hle/service/psc/psc.cpp +++ b/src/core/hle/service/psc/psc.cpp @@ -1,11 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include <memory> - -#include "common/logging/log.h" -#include "core/core.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/psc/ovln/receiver_service.h" +#include "core/hle/service/psc/ovln/sender_service.h" +#include "core/hle/service/psc/pm_control.h" +#include "core/hle/service/psc/pm_service.h" #include "core/hle/service/psc/psc.h" #include "core/hle/service/psc/time/manager.h" #include "core/hle/service/psc/time/power_state_service.h" @@ -15,71 +14,13 @@ namespace Service::PSC { -class IPmControl final : public ServiceFramework<IPmControl> { -public: - explicit IPmControl(Core::System& system_) : ServiceFramework{system_, "psc:c"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "Initialize"}, - {1, nullptr, "DispatchRequest"}, - {2, nullptr, "GetResult"}, - {3, nullptr, "GetState"}, - {4, nullptr, "Cancel"}, - {5, nullptr, "PrintModuleInformation"}, - {6, nullptr, "GetModuleInformation"}, - {10, nullptr, "AcquireStateLock"}, - {11, nullptr, "HasStateLock"}, - }; - // clang-format on - - RegisterHandlers(functions); - } -}; - -class IPmModule final : public ServiceFramework<IPmModule> { -public: - explicit IPmModule(Core::System& system_) : ServiceFramework{system_, "IPmModule"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "Initialize"}, - {1, nullptr, "GetRequest"}, - {2, nullptr, "Acknowledge"}, - {3, nullptr, "Finalize"}, - {4, nullptr, "AcknowledgeEx"}, - }; - // clang-format on - - RegisterHandlers(functions); - } -}; - -class IPmService final : public ServiceFramework<IPmService> { -public: - explicit IPmService(Core::System& system_) : ServiceFramework{system_, "psc:m"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IPmService::GetPmModule, "GetPmModule"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void GetPmModule(HLERequestContext& ctx) { - LOG_DEBUG(Service_PSC, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IPmModule>(system); - } -}; - void LoopProcess(Core::System& system) { auto server_manager = std::make_unique<ServerManager>(system); server_manager->RegisterNamedService("psc:c", std::make_shared<IPmControl>(system)); server_manager->RegisterNamedService("psc:m", std::make_shared<IPmService>(system)); + server_manager->RegisterNamedService("ovln:rcv", std::make_shared<IReceiverService>(system)); + server_manager->RegisterNamedService("ovln:snd", std::make_shared<ISenderService>(system)); auto time = std::make_shared<Time::TimeManager>(system); diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h index 459137f42..c83d07ca8 100644 --- a/src/core/hle/service/psc/psc.h +++ b/src/core/hle/service/psc/psc.h @@ -7,10 +7,6 @@ namespace Core { class System; } -namespace Service::SM { -class ServiceManager; -} - namespace Service::PSC { void LoopProcess(Core::System& system); diff --git a/src/core/hle/service/vi/container.cpp b/src/core/hle/service/vi/container.cpp index 310a207f1..9074f4ae0 100644 --- a/src/core/hle/service/vi/container.cpp +++ b/src/core/hle/service/vi/container.cpp @@ -43,11 +43,7 @@ void Container::OnTerminate() { m_is_shut_down = true; - m_layers.ForEachLayer([&](auto& layer) { - if (layer.IsOpen()) { - this->DestroyBufferQueueLocked(&layer); - } - }); + m_layers.ForEachLayer([&](auto& layer) { this->DestroyLayerLocked(layer.GetId()); }); m_displays.ForEachDisplay( [&](auto& display) { m_surface_flinger->RemoveDisplay(display.GetId()); }); @@ -161,16 +157,29 @@ Result Container::CreateLayerLocked(u64* out_layer_id, u64 display_id, u64 owner auto* const display = m_displays.GetDisplayById(display_id); R_UNLESS(display != nullptr, VI::ResultNotFound); - auto* const layer = m_layers.CreateLayer(owner_aruid, display); + s32 consumer_binder_id, producer_binder_id; + m_surface_flinger->CreateBufferQueue(&consumer_binder_id, &producer_binder_id); + + auto* const layer = + m_layers.CreateLayer(owner_aruid, display, consumer_binder_id, producer_binder_id); R_UNLESS(layer != nullptr, VI::ResultNotFound); + m_surface_flinger->CreateLayer(consumer_binder_id); + *out_layer_id = layer->GetId(); R_SUCCEED(); } Result Container::DestroyLayerLocked(u64 layer_id) { - R_SUCCEED_IF(m_layers.DestroyLayer(layer_id)); - R_THROW(VI::ResultNotFound); + auto* const layer = m_layers.GetLayerById(layer_id); + R_UNLESS(layer != nullptr, VI::ResultNotFound); + + m_surface_flinger->DestroyLayer(layer->GetConsumerBinderId()); + m_surface_flinger->DestroyBufferQueue(layer->GetConsumerBinderId(), + layer->GetProducerBinderId()); + m_layers.DestroyLayer(layer_id); + + R_SUCCEED(); } Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid) { @@ -181,7 +190,12 @@ Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 R_UNLESS(!layer->IsOpen(), VI::ResultOperationFailed); R_UNLESS(layer->GetOwnerAruid() == aruid, VI::ResultPermissionDenied); - this->CreateBufferQueueLocked(layer); + layer->Open(); + + if (auto* display = layer->GetDisplay(); display != nullptr) { + m_surface_flinger->AddLayerToDisplayStack(display->GetId(), layer->GetConsumerBinderId()); + } + *out_producer_binder_id = layer->GetProducerBinderId(); R_SUCCEED(); @@ -192,30 +206,14 @@ Result Container::CloseLayerLocked(u64 layer_id) { R_UNLESS(layer != nullptr, VI::ResultNotFound); R_UNLESS(layer->IsOpen(), VI::ResultOperationFailed); - this->DestroyBufferQueueLocked(layer); - - R_SUCCEED(); -} - -void Container::CreateBufferQueueLocked(Layer* layer) { - s32 consumer_binder_id, producer_binder_id; - m_surface_flinger->CreateBufferQueue(&consumer_binder_id, &producer_binder_id); - layer->Open(consumer_binder_id, producer_binder_id); - - if (auto* display = layer->GetDisplay(); display != nullptr) { - m_surface_flinger->AddLayerToDisplayStack(display->GetId(), consumer_binder_id); - } -} - -void Container::DestroyBufferQueueLocked(Layer* layer) { if (auto* display = layer->GetDisplay(); display != nullptr) { m_surface_flinger->RemoveLayerFromDisplayStack(display->GetId(), layer->GetConsumerBinderId()); } layer->Close(); - m_surface_flinger->DestroyBufferQueue(layer->GetConsumerBinderId(), - layer->GetProducerBinderId()); + + R_SUCCEED(); } bool Container::ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, diff --git a/src/core/hle/service/vi/container.h b/src/core/hle/service/vi/container.h index cd0d2ca86..5eac4d77d 100644 --- a/src/core/hle/service/vi/container.h +++ b/src/core/hle/service/vi/container.h @@ -72,9 +72,6 @@ private: Result OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid); Result CloseLayerLocked(u64 layer_id); - void CreateBufferQueueLocked(Layer* layer); - void DestroyBufferQueueLocked(Layer* layer); - public: bool ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id); diff --git a/src/core/hle/service/vi/layer.h b/src/core/hle/service/vi/layer.h index b85c8df61..e4c9c9864 100644 --- a/src/core/hle/service/vi/layer.h +++ b/src/core/hle/service/vi/layer.h @@ -13,29 +13,31 @@ class Layer { public: constexpr Layer() = default; - void Initialize(u64 id, u64 owner_aruid, Display* display) { + void Initialize(u64 id, u64 owner_aruid, Display* display, s32 consumer_binder_id, + s32 producer_binder_id) { m_id = id; m_owner_aruid = owner_aruid; m_display = display; + m_consumer_binder_id = consumer_binder_id; + m_producer_binder_id = producer_binder_id; m_is_initialized = true; } void Finalize() { m_id = {}; + m_owner_aruid = {}; m_display = {}; + m_consumer_binder_id = {}; + m_producer_binder_id = {}; m_is_initialized = {}; } - void Open(s32 consumer_binder_id, s32 producer_binder_id) { - m_consumer_binder_id = consumer_binder_id; - m_producer_binder_id = producer_binder_id; + void Open() { m_is_open = true; } void Close() { - m_producer_binder_id = {}; - m_consumer_binder_id = {}; - m_is_open = {}; + m_is_open = false; } u64 GetId() const { diff --git a/src/core/hle/service/vi/layer_list.h b/src/core/hle/service/vi/layer_list.h index 1738ede9a..4afca6f40 100644 --- a/src/core/hle/service/vi/layer_list.h +++ b/src/core/hle/service/vi/layer_list.h @@ -11,13 +11,15 @@ class LayerList { public: constexpr LayerList() = default; - Layer* CreateLayer(u64 owner_aruid, Display* display) { + Layer* CreateLayer(u64 owner_aruid, Display* display, s32 consumer_binder_id, + s32 producer_binder_id) { Layer* const layer = GetFreeLayer(); if (!layer) { return nullptr; } - layer->Initialize(++m_next_id, owner_aruid, display); + layer->Initialize(++m_next_id, owner_aruid, display, consumer_binder_id, + producer_binder_id); return layer; } diff --git a/src/core/hle/service/vi/shared_buffer_manager.cpp b/src/core/hle/service/vi/shared_buffer_manager.cpp index 869b18961..12cba16fa 100644 --- a/src/core/hle/service/vi/shared_buffer_manager.cpp +++ b/src/core/hle/service/vi/shared_buffer_manager.cpp @@ -285,7 +285,7 @@ void SharedBufferManager::DestroySession(Kernel::KProcess* owner_process) { auto& session = it->second; // Destroy the layer. - R_ASSERT(m_container.DestroyStrayLayer(session.layer_id)); + m_container.DestroyStrayLayer(session.layer_id); // Close nvmap handle. FreeHandle(session.buffer_nvmap_handle, *m_nvdrv, session.nvmap_fd); @@ -322,8 +322,6 @@ Result SharedBufferManager::GetSharedBufferMemoryHandleId(u64* out_buffer_size, Result SharedBufferManager::AcquireSharedFrameBuffer(android::Fence* out_fence, std::array<s32, 4>& out_slot_indexes, s64* out_target_slot, u64 layer_id) { - std::scoped_lock lk{m_guard}; - // Get the producer. std::shared_ptr<android::BufferQueueProducer> producer; R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); @@ -347,8 +345,6 @@ Result SharedBufferManager::PresentSharedFrameBuffer(android::Fence fence, Common::Rectangle<s32> crop_region, u32 transform, s32 swap_interval, u64 layer_id, s64 slot) { - std::scoped_lock lk{m_guard}; - // Get the producer. std::shared_ptr<android::BufferQueueProducer> producer; R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); @@ -379,8 +375,6 @@ Result SharedBufferManager::PresentSharedFrameBuffer(android::Fence fence, } Result SharedBufferManager::CancelSharedFrameBuffer(u64 layer_id, s64 slot) { - std::scoped_lock lk{m_guard}; - // Get the producer. std::shared_ptr<android::BufferQueueProducer> producer; R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); @@ -394,8 +388,6 @@ Result SharedBufferManager::CancelSharedFrameBuffer(u64 layer_id, s64 slot) { Result SharedBufferManager::GetSharedFrameBufferAcquirableEvent(Kernel::KReadableEvent** out_event, u64 layer_id) { - std::scoped_lock lk{m_guard}; - // Get the producer. std::shared_ptr<android::BufferQueueProducer> producer; R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); |