diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/nfc/common/device_manager.cpp | 135 |
1 files changed, 105 insertions, 30 deletions
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index 562f3a28e..a71d26157 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +#include <algorithm> + #include "common/logging/log.h" #include "core/core.h" #include "core/hid/hid_types.h" @@ -10,6 +12,7 @@ #include "core/hle/service/nfc/common/device_manager.h" #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/time/clock_types.h" +#include "core/hle/service/time/time_manager.h" namespace Service::NFC { @@ -51,22 +54,53 @@ Result DeviceManager::Finalize() { return ResultSuccess; } -Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, - std::size_t max_allowed_devices) const { +Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices, + bool skip_fatal_errors) const { + std::scoped_lock lock{mutex}; + if (max_allowed_devices < 1) { + return ResultInvalidArgument; + } + + Result result = IsNfcParameterSet(); + if (result.IsError()) { + return result; + } + + result = IsNfcEnabled(); + if (result.IsError()) { + return result; + } + + result = IsNfcInitialized(); + if (result.IsError()) { + return result; + } + for (auto& device : devices) { if (nfp_devices.size() >= max_allowed_devices) { continue; } - if (device->GetCurrentState() != DeviceState::Unavailable) { - nfp_devices.push_back(device->GetHandle()); + if (skip_fatal_errors) { + constexpr u64 MinimumRecoveryTime = 60; + auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point - + time_since_last_error; + + if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) { + continue; + } } + if (device->GetCurrentState() == DeviceState::Unavailable) { + continue; + } + nfp_devices.push_back(device->GetHandle()); } if (nfp_devices.empty()) { return ResultDeviceNotFound; } - return ResultSuccess; + return result; } DeviceState DeviceManager::GetDeviceState(u64 device_handle) const { @@ -79,10 +113,10 @@ DeviceState DeviceManager::GetDeviceState(u64 device_handle) const { return device->GetCurrentState(); } - return DeviceState::Unavailable; + return DeviceState::Finalized; } -Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const { +Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -128,7 +162,7 @@ Result DeviceManager::StopDetection(u64 device_handle) { return result; } -Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const { +Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -142,24 +176,46 @@ Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const { return result; } -Kernel::KReadableEvent& DeviceManager::AttachActivateEvent(u64 device_handle) const { - std::scoped_lock lock{mutex}; - +Result DeviceManager::AttachActivateEvent(Kernel::KReadableEvent** out_event, + u64 device_handle) const { + std::vector<u64> nfp_devices; std::shared_ptr<NfcDevice> device = nullptr; - GetDeviceFromHandle(device_handle, device, false); + Result result = ListDevices(nfp_devices, 9, false); - // TODO: Return proper error code on failure - return device->GetActivateEvent(); -} + if (result.IsSuccess()) { + result = CheckHandleOnList(device_handle, nfp_devices); + } -Kernel::KReadableEvent& DeviceManager::AttachDeactivateEvent(u64 device_handle) const { - std::scoped_lock lock{mutex}; + if (result.IsSuccess()) { + result = GetDeviceFromHandle(device_handle, device, false); + } + + if (result.IsSuccess()) { + *out_event = &device->GetActivateEvent(); + } + + return result; +} +Result DeviceManager::AttachDeactivateEvent(Kernel::KReadableEvent** out_event, + u64 device_handle) const { + std::vector<u64> nfp_devices; std::shared_ptr<NfcDevice> device = nullptr; - GetDeviceFromHandle(device_handle, device, false); + Result result = ListDevices(nfp_devices, 9, false); - // TODO: Return proper error code on failure - return device->GetDeactivateEvent(); + if (result.IsSuccess()) { + result = CheckHandleOnList(device_handle, nfp_devices); + } + + if (result.IsSuccess()) { + result = GetDeviceFromHandle(device_handle, device, false); + } + + if (result.IsSuccess()) { + *out_event = &device->GetDeactivateEvent(); + } + + return result; } Result DeviceManager::ReadMifare(u64 device_handle, @@ -253,7 +309,7 @@ Result DeviceManager::OpenApplicationArea(u64 device_handle, u32 access_id) { return result; } -Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) const { +Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -324,7 +380,7 @@ Result DeviceManager::CreateApplicationArea(u64 device_handle, u32 access_id, return result; } -Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const { +Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -338,7 +394,7 @@ Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& regi return result; } -Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const { +Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -352,7 +408,7 @@ Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_i return result; } -Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const { +Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -399,7 +455,7 @@ Result DeviceManager::Format(u64 device_handle) { return result; } -Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const { +Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -414,7 +470,7 @@ Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info } Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle, - NFP::RegisterInfoPrivate& register_info) const { + NFP::RegisterInfoPrivate& register_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -471,7 +527,7 @@ Result DeviceManager::DeleteApplicationArea(u64 device_handle) { return result; } -Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) const { +Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -485,7 +541,7 @@ Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_applica return result; } -Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) const { +Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -541,7 +597,7 @@ Result DeviceManager::BreakTag(u64 device_handle, NFP::BreakType break_type) { return result; } -Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) const { +Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -593,6 +649,19 @@ Result DeviceManager::WriteNtf(u64 device_handle, NFP::WriteType, std::span<cons return result; } +Result DeviceManager::CheckHandleOnList(u64 device_handle, + const std::span<const u64> device_list) const { + if (device_list.size() < 1) { + return ResultDeviceNotFound; + } + + if (std::find(device_list.begin(), device_list.end(), device_handle) != device_list.end()) { + return ResultSuccess; + } + + return ResultDeviceNotFound; +} + Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device, bool check_state) const { if (check_state) { @@ -647,7 +716,7 @@ Result DeviceManager::GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& de } Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, - Result operation_result) const { + Result operation_result) { if (operation_result.IsSuccess()) { return operation_result; } @@ -669,6 +738,12 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, return device_state; } + if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 || + operation_result == ResultUnknown115) { + auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point; + } + return operation_result; } |