summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar liamwhite2023-07-21 09:21:48 -0400
committerGravatar GitHub2023-07-21 09:21:48 -0400
commitc0202da9ac8301f86086ea898e6789dae981b13f (patch)
tree0d9ecb6a93fcde52d5a56aa80ce686bb3e1ab9ad /src
parentMerge pull request #11116 from lat9nq/clang-shadowing (diff)
parentservice: nfc: Update Implementation to match with latest RE (diff)
downloadyuzu-c0202da9ac8301f86086ea898e6789dae981b13f.tar.gz
yuzu-c0202da9ac8301f86086ea898e6789dae981b13f.tar.xz
yuzu-c0202da9ac8301f86086ea898e6789dae981b13f.zip
Merge pull request #11096 from german77/amiibooo
service: nfc: Update Implementation to match with latest RE
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nfc/common/amiibo_crypto.cpp2
-rw-r--r--src/core/hle/service/nfc/common/amiibo_crypto.h2
-rw-r--r--src/core/hle/service/nfc/common/device.cpp3
-rw-r--r--src/core/hle/service/nfc/common/device_manager.cpp135
-rw-r--r--src/core/hle/service/nfc/common/device_manager.h34
-rw-r--r--src/core/hle/service/nfc/nfc_interface.cpp18
-rw-r--r--src/core/hle/service/nfc/nfc_result.h3
7 files changed, 143 insertions, 54 deletions
diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.cpp b/src/core/hle/service/nfc/common/amiibo_crypto.cpp
index bc232c334..9556e9193 100644
--- a/src/core/hle/service/nfc/common/amiibo_crypto.cpp
+++ b/src/core/hle/service/nfc/common/amiibo_crypto.cpp
@@ -180,7 +180,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
180} 180}
181 181
182void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, 182void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
183 const std::vector<u8>& seed) { 183 std::span<const u8> seed) {
184 // Initialize context 184 // Initialize context
185 ctx.used = false; 185 ctx.used = false;
186 ctx.counter = 0; 186 ctx.counter = 0;
diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.h b/src/core/hle/service/nfc/common/amiibo_crypto.h
index 6a3e0841e..2cc0e4d51 100644
--- a/src/core/hle/service/nfc/common/amiibo_crypto.h
+++ b/src/core/hle/service/nfc/common/amiibo_crypto.h
@@ -75,7 +75,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
75 75
76// Initializes mbedtls context 76// Initializes mbedtls context
77void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, 77void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
78 const std::vector<u8>& seed); 78 std::span<const u8> seed);
79 79
80// Feeds data to mbedtls context to generate the derived key 80// Feeds data to mbedtls context to generate the derived key
81void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output); 81void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output);
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index 2d633b03f..49446bc42 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -34,8 +34,6 @@
34#include "core/hle/service/nfc/mifare_result.h" 34#include "core/hle/service/nfc/mifare_result.h"
35#include "core/hle/service/nfc/nfc_result.h" 35#include "core/hle/service/nfc/nfc_result.h"
36#include "core/hle/service/time/time_manager.h" 36#include "core/hle/service/time/time_manager.h"
37#include "core/hle/service/time/time_zone_content_manager.h"
38#include "core/hle/service/time/time_zone_types.h"
39 37
40namespace Service::NFC { 38namespace Service::NFC {
41NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, 39NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
@@ -1486,6 +1484,7 @@ DeviceState NfcDevice::GetCurrentState() const {
1486} 1484}
1487 1485
1488Result NfcDevice::GetNpadId(Core::HID::NpadIdType& out_npad_id) const { 1486Result NfcDevice::GetNpadId(Core::HID::NpadIdType& out_npad_id) const {
1487 // TODO: This should get the npad id from nn::hid::system::GetXcdHandleForNpadWithNfc
1489 out_npad_id = npad_id; 1488 out_npad_id = npad_id;
1490 return ResultSuccess; 1489 return ResultSuccess;
1491} 1490}
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 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include <algorithm>
5
4#include "common/logging/log.h" 6#include "common/logging/log.h"
5#include "core/core.h" 7#include "core/core.h"
6#include "core/hid/hid_types.h" 8#include "core/hid/hid_types.h"
@@ -10,6 +12,7 @@
10#include "core/hle/service/nfc/common/device_manager.h" 12#include "core/hle/service/nfc/common/device_manager.h"
11#include "core/hle/service/nfc/nfc_result.h" 13#include "core/hle/service/nfc/nfc_result.h"
12#include "core/hle/service/time/clock_types.h" 14#include "core/hle/service/time/clock_types.h"
15#include "core/hle/service/time/time_manager.h"
13 16
14namespace Service::NFC { 17namespace Service::NFC {
15 18
@@ -51,22 +54,53 @@ Result DeviceManager::Finalize() {
51 return ResultSuccess; 54 return ResultSuccess;
52} 55}
53 56
54Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, 57Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices,
55 std::size_t max_allowed_devices) const { 58 bool skip_fatal_errors) const {
59 std::scoped_lock lock{mutex};
60 if (max_allowed_devices < 1) {
61 return ResultInvalidArgument;
62 }
63
64 Result result = IsNfcParameterSet();
65 if (result.IsError()) {
66 return result;
67 }
68
69 result = IsNfcEnabled();
70 if (result.IsError()) {
71 return result;
72 }
73
74 result = IsNfcInitialized();
75 if (result.IsError()) {
76 return result;
77 }
78
56 for (auto& device : devices) { 79 for (auto& device : devices) {
57 if (nfp_devices.size() >= max_allowed_devices) { 80 if (nfp_devices.size() >= max_allowed_devices) {
58 continue; 81 continue;
59 } 82 }
60 if (device->GetCurrentState() != DeviceState::Unavailable) { 83 if (skip_fatal_errors) {
61 nfp_devices.push_back(device->GetHandle()); 84 constexpr u64 MinimumRecoveryTime = 60;
85 auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()};
86 const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point -
87 time_since_last_error;
88
89 if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) {
90 continue;
91 }
62 } 92 }
93 if (device->GetCurrentState() == DeviceState::Unavailable) {
94 continue;
95 }
96 nfp_devices.push_back(device->GetHandle());
63 } 97 }
64 98
65 if (nfp_devices.empty()) { 99 if (nfp_devices.empty()) {
66 return ResultDeviceNotFound; 100 return ResultDeviceNotFound;
67 } 101 }
68 102
69 return ResultSuccess; 103 return result;
70} 104}
71 105
72DeviceState DeviceManager::GetDeviceState(u64 device_handle) const { 106DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
@@ -79,10 +113,10 @@ DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
79 return device->GetCurrentState(); 113 return device->GetCurrentState();
80 } 114 }
81 115
82 return DeviceState::Unavailable; 116 return DeviceState::Finalized;
83} 117}
84 118
85Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const { 119Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) {
86 std::scoped_lock lock{mutex}; 120 std::scoped_lock lock{mutex};
87 121
88 std::shared_ptr<NfcDevice> device = nullptr; 122 std::shared_ptr<NfcDevice> device = nullptr;
@@ -128,7 +162,7 @@ Result DeviceManager::StopDetection(u64 device_handle) {
128 return result; 162 return result;
129} 163}
130 164
131Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const { 165Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) {
132 std::scoped_lock lock{mutex}; 166 std::scoped_lock lock{mutex};
133 167
134 std::shared_ptr<NfcDevice> device = nullptr; 168 std::shared_ptr<NfcDevice> device = nullptr;
@@ -142,24 +176,46 @@ Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const {
142 return result; 176 return result;
143} 177}
144 178
145Kernel::KReadableEvent& DeviceManager::AttachActivateEvent(u64 device_handle) const { 179Result DeviceManager::AttachActivateEvent(Kernel::KReadableEvent** out_event,
146 std::scoped_lock lock{mutex}; 180 u64 device_handle) const {
147 181 std::vector<u64> nfp_devices;
148 std::shared_ptr<NfcDevice> device = nullptr; 182 std::shared_ptr<NfcDevice> device = nullptr;
149 GetDeviceFromHandle(device_handle, device, false); 183 Result result = ListDevices(nfp_devices, 9, false);
150 184
151 // TODO: Return proper error code on failure 185 if (result.IsSuccess()) {
152 return device->GetActivateEvent(); 186 result = CheckHandleOnList(device_handle, nfp_devices);
153} 187 }
154 188
155Kernel::KReadableEvent& DeviceManager::AttachDeactivateEvent(u64 device_handle) const { 189 if (result.IsSuccess()) {
156 std::scoped_lock lock{mutex}; 190 result = GetDeviceFromHandle(device_handle, device, false);
191 }
192
193 if (result.IsSuccess()) {
194 *out_event = &device->GetActivateEvent();
195 }
196
197 return result;
198}
157 199
200Result DeviceManager::AttachDeactivateEvent(Kernel::KReadableEvent** out_event,
201 u64 device_handle) const {
202 std::vector<u64> nfp_devices;
158 std::shared_ptr<NfcDevice> device = nullptr; 203 std::shared_ptr<NfcDevice> device = nullptr;
159 GetDeviceFromHandle(device_handle, device, false); 204 Result result = ListDevices(nfp_devices, 9, false);
160 205
161 // TODO: Return proper error code on failure 206 if (result.IsSuccess()) {
162 return device->GetDeactivateEvent(); 207 result = CheckHandleOnList(device_handle, nfp_devices);
208 }
209
210 if (result.IsSuccess()) {
211 result = GetDeviceFromHandle(device_handle, device, false);
212 }
213
214 if (result.IsSuccess()) {
215 *out_event = &device->GetDeactivateEvent();
216 }
217
218 return result;
163} 219}
164 220
165Result DeviceManager::ReadMifare(u64 device_handle, 221Result DeviceManager::ReadMifare(u64 device_handle,
@@ -253,7 +309,7 @@ Result DeviceManager::OpenApplicationArea(u64 device_handle, u32 access_id) {
253 return result; 309 return result;
254} 310}
255 311
256Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) const { 312Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) {
257 std::scoped_lock lock{mutex}; 313 std::scoped_lock lock{mutex};
258 314
259 std::shared_ptr<NfcDevice> device = nullptr; 315 std::shared_ptr<NfcDevice> device = nullptr;
@@ -324,7 +380,7 @@ Result DeviceManager::CreateApplicationArea(u64 device_handle, u32 access_id,
324 return result; 380 return result;
325} 381}
326 382
327Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const { 383Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) {
328 std::scoped_lock lock{mutex}; 384 std::scoped_lock lock{mutex};
329 385
330 std::shared_ptr<NfcDevice> device = nullptr; 386 std::shared_ptr<NfcDevice> device = nullptr;
@@ -338,7 +394,7 @@ Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& regi
338 return result; 394 return result;
339} 395}
340 396
341Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const { 397Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) {
342 std::scoped_lock lock{mutex}; 398 std::scoped_lock lock{mutex};
343 399
344 std::shared_ptr<NfcDevice> device = nullptr; 400 std::shared_ptr<NfcDevice> device = nullptr;
@@ -352,7 +408,7 @@ Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_i
352 return result; 408 return result;
353} 409}
354 410
355Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const { 411Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) {
356 std::scoped_lock lock{mutex}; 412 std::scoped_lock lock{mutex};
357 413
358 std::shared_ptr<NfcDevice> device = nullptr; 414 std::shared_ptr<NfcDevice> device = nullptr;
@@ -399,7 +455,7 @@ Result DeviceManager::Format(u64 device_handle) {
399 return result; 455 return result;
400} 456}
401 457
402Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const { 458Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) {
403 std::scoped_lock lock{mutex}; 459 std::scoped_lock lock{mutex};
404 460
405 std::shared_ptr<NfcDevice> device = nullptr; 461 std::shared_ptr<NfcDevice> device = nullptr;
@@ -414,7 +470,7 @@ Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info
414} 470}
415 471
416Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle, 472Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle,
417 NFP::RegisterInfoPrivate& register_info) const { 473 NFP::RegisterInfoPrivate& register_info) {
418 std::scoped_lock lock{mutex}; 474 std::scoped_lock lock{mutex};
419 475
420 std::shared_ptr<NfcDevice> device = nullptr; 476 std::shared_ptr<NfcDevice> device = nullptr;
@@ -471,7 +527,7 @@ Result DeviceManager::DeleteApplicationArea(u64 device_handle) {
471 return result; 527 return result;
472} 528}
473 529
474Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) const { 530Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) {
475 std::scoped_lock lock{mutex}; 531 std::scoped_lock lock{mutex};
476 532
477 std::shared_ptr<NfcDevice> device = nullptr; 533 std::shared_ptr<NfcDevice> device = nullptr;
@@ -485,7 +541,7 @@ Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_applica
485 return result; 541 return result;
486} 542}
487 543
488Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) const { 544Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) {
489 std::scoped_lock lock{mutex}; 545 std::scoped_lock lock{mutex};
490 546
491 std::shared_ptr<NfcDevice> device = nullptr; 547 std::shared_ptr<NfcDevice> device = nullptr;
@@ -541,7 +597,7 @@ Result DeviceManager::BreakTag(u64 device_handle, NFP::BreakType break_type) {
541 return result; 597 return result;
542} 598}
543 599
544Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) const { 600Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) {
545 std::scoped_lock lock{mutex}; 601 std::scoped_lock lock{mutex};
546 602
547 std::shared_ptr<NfcDevice> device = nullptr; 603 std::shared_ptr<NfcDevice> device = nullptr;
@@ -593,6 +649,19 @@ Result DeviceManager::WriteNtf(u64 device_handle, NFP::WriteType, std::span<cons
593 return result; 649 return result;
594} 650}
595 651
652Result DeviceManager::CheckHandleOnList(u64 device_handle,
653 const std::span<const u64> device_list) const {
654 if (device_list.size() < 1) {
655 return ResultDeviceNotFound;
656 }
657
658 if (std::find(device_list.begin(), device_list.end(), device_handle) != device_list.end()) {
659 return ResultSuccess;
660 }
661
662 return ResultDeviceNotFound;
663}
664
596Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device, 665Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device,
597 bool check_state) const { 666 bool check_state) const {
598 if (check_state) { 667 if (check_state) {
@@ -647,7 +716,7 @@ Result DeviceManager::GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& de
647} 716}
648 717
649Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, 718Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
650 Result operation_result) const { 719 Result operation_result) {
651 if (operation_result.IsSuccess()) { 720 if (operation_result.IsSuccess()) {
652 return operation_result; 721 return operation_result;
653 } 722 }
@@ -669,6 +738,12 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
669 return device_state; 738 return device_state;
670 } 739 }
671 740
741 if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 ||
742 operation_result == ResultUnknown115) {
743 auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()};
744 time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point;
745 }
746
672 return operation_result; 747 return operation_result;
673} 748}
674 749
diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h
index c61ba0cf3..c9f038e32 100644
--- a/src/core/hle/service/nfc/common/device_manager.h
+++ b/src/core/hle/service/nfc/common/device_manager.h
@@ -27,15 +27,16 @@ public:
27 // Nfc device manager 27 // Nfc device manager
28 Result Initialize(); 28 Result Initialize();
29 Result Finalize(); 29 Result Finalize();
30 Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices) const; 30 Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices,
31 bool skip_fatal_errors) const;
31 DeviceState GetDeviceState(u64 device_handle) const; 32 DeviceState GetDeviceState(u64 device_handle) const;
32 Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const; 33 Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id);
33 Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const; 34 Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const;
34 Result StartDetection(u64 device_handle, NfcProtocol tag_protocol); 35 Result StartDetection(u64 device_handle, NfcProtocol tag_protocol);
35 Result StopDetection(u64 device_handle); 36 Result StopDetection(u64 device_handle);
36 Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const; 37 Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info);
37 Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const; 38 Result AttachActivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
38 Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const; 39 Result AttachDeactivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
39 Result ReadMifare(u64 device_handle, 40 Result ReadMifare(u64 device_handle,
40 const std::span<const MifareReadBlockParameter> read_parameters, 41 const std::span<const MifareReadBlockParameter> read_parameters,
41 std::span<MifareReadBlockData> read_data); 42 std::span<MifareReadBlockData> read_data);
@@ -48,28 +49,28 @@ public:
48 Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target); 49 Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target);
49 Result Unmount(u64 device_handle); 50 Result Unmount(u64 device_handle);
50 Result OpenApplicationArea(u64 device_handle, u32 access_id); 51 Result OpenApplicationArea(u64 device_handle, u32 access_id);
51 Result GetApplicationArea(u64 device_handle, std::span<u8> data) const; 52 Result GetApplicationArea(u64 device_handle, std::span<u8> data);
52 Result SetApplicationArea(u64 device_handle, std::span<const u8> data); 53 Result SetApplicationArea(u64 device_handle, std::span<const u8> data);
53 Result Flush(u64 device_handle); 54 Result Flush(u64 device_handle);
54 Result Restore(u64 device_handle); 55 Result Restore(u64 device_handle);
55 Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); 56 Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
56 Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const; 57 Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info);
57 Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const; 58 Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info);
58 Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const; 59 Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info);
59 u32 GetApplicationAreaSize() const; 60 u32 GetApplicationAreaSize() const;
60 Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); 61 Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
61 Result Format(u64 device_handle); 62 Result Format(u64 device_handle);
62 Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const; 63 Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info);
63 Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info) const; 64 Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info);
64 Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info); 65 Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info);
65 Result DeleteRegisterInfo(u64 device_handle); 66 Result DeleteRegisterInfo(u64 device_handle);
66 Result DeleteApplicationArea(u64 device_handle); 67 Result DeleteApplicationArea(u64 device_handle);
67 Result ExistsApplicationArea(u64 device_handle, bool& has_application_area) const; 68 Result ExistsApplicationArea(u64 device_handle, bool& has_application_area);
68 Result GetAll(u64 device_handle, NFP::NfpData& nfp_data) const; 69 Result GetAll(u64 device_handle, NFP::NfpData& nfp_data);
69 Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data); 70 Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data);
70 Result FlushDebug(u64 device_handle); 71 Result FlushDebug(u64 device_handle);
71 Result BreakTag(u64 device_handle, NFP::BreakType break_type); 72 Result BreakTag(u64 device_handle, NFP::BreakType break_type);
72 Result ReadBackupData(u64 device_handle, std::span<u8> data) const; 73 Result ReadBackupData(u64 device_handle, std::span<u8> data);
73 Result WriteBackupData(u64 device_handle, std::span<const u8> data); 74 Result WriteBackupData(u64 device_handle, std::span<const u8> data);
74 Result WriteNtf(u64 device_handle, NFP::WriteType, std::span<const u8> data); 75 Result WriteNtf(u64 device_handle, NFP::WriteType, std::span<const u8> data);
75 76
@@ -78,17 +79,20 @@ private:
78 Result IsNfcParameterSet() const; 79 Result IsNfcParameterSet() const;
79 Result IsNfcInitialized() const; 80 Result IsNfcInitialized() const;
80 81
82 Result CheckHandleOnList(u64 device_handle, std::span<const u64> device_list) const;
83
81 Result GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& device, 84 Result GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& device,
82 bool check_state) const; 85 bool check_state) const;
83 86
84 Result GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& device) const; 87 Result GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& device) const;
85 Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result) const; 88 Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result);
86 Result CheckDeviceState(std::shared_ptr<NfcDevice> device) const; 89 Result CheckDeviceState(std::shared_ptr<NfcDevice> device) const;
87 90
88 std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle); 91 std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
89 const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const; 92 const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const;
90 93
91 bool is_initialized = false; 94 bool is_initialized = false;
95 u64 time_since_last_error = 0;
92 mutable std::mutex mutex; 96 mutable std::mutex mutex;
93 std::array<std::shared_ptr<NfcDevice>, 10> devices{}; 97 std::array<std::shared_ptr<NfcDevice>, 10> devices{};
94 98
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp
index e7ca7582e..179c7ba2c 100644
--- a/src/core/hle/service/nfc/nfc_interface.cpp
+++ b/src/core/hle/service/nfc/nfc_interface.cpp
@@ -79,7 +79,7 @@ void NfcInterface::ListDevices(HLERequestContext& ctx) {
79 const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>(); 79 const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>();
80 LOG_DEBUG(Service_NFC, "called"); 80 LOG_DEBUG(Service_NFC, "called");
81 81
82 auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices); 82 auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices, true);
83 result = TranslateResultToServiceError(result); 83 result = TranslateResultToServiceError(result);
84 84
85 if (result.IsError()) { 85 if (result.IsError()) {
@@ -190,9 +190,13 @@ void NfcInterface::AttachActivateEvent(HLERequestContext& ctx) {
190 const auto device_handle{rp.Pop<u64>()}; 190 const auto device_handle{rp.Pop<u64>()};
191 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 191 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
192 192
193 Kernel::KReadableEvent* out_event = nullptr;
194 auto result = GetManager()->AttachActivateEvent(&out_event, device_handle);
195 result = TranslateResultToServiceError(result);
196
193 IPC::ResponseBuilder rb{ctx, 2, 1}; 197 IPC::ResponseBuilder rb{ctx, 2, 1};
194 rb.Push(ResultSuccess); 198 rb.Push(result);
195 rb.PushCopyObjects(GetManager()->AttachActivateEvent(device_handle)); 199 rb.PushCopyObjects(out_event);
196} 200}
197 201
198void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { 202void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
@@ -200,9 +204,13 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
200 const auto device_handle{rp.Pop<u64>()}; 204 const auto device_handle{rp.Pop<u64>()};
201 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 205 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
202 206
207 Kernel::KReadableEvent* out_event = nullptr;
208 auto result = GetManager()->AttachDeactivateEvent(&out_event, device_handle);
209 result = TranslateResultToServiceError(result);
210
203 IPC::ResponseBuilder rb{ctx, 2, 1}; 211 IPC::ResponseBuilder rb{ctx, 2, 1};
204 rb.Push(ResultSuccess); 212 rb.Push(result);
205 rb.PushCopyObjects(GetManager()->AttachDeactivateEvent(device_handle)); 213 rb.PushCopyObjects(out_event);
206} 214}
207 215
208void NfcInterface::ReadMifare(HLERequestContext& ctx) { 216void NfcInterface::ReadMifare(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/nfc/nfc_result.h b/src/core/hle/service/nfc/nfc_result.h
index 715c0e80c..464b5fd69 100644
--- a/src/core/hle/service/nfc/nfc_result.h
+++ b/src/core/hle/service/nfc/nfc_result.h
@@ -17,7 +17,10 @@ constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77);
17constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); 17constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80);
18constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88); 18constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88);
19constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); 19constexpr Result ResultTagRemoved(ErrorModule::NFC, 97);
20constexpr Result ResultUnknown112(ErrorModule::NFC, 112);
20constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113); 21constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113);
22constexpr Result ResultUnknown114(ErrorModule::NFC, 114);
23constexpr Result ResultUnknown115(ErrorModule::NFC, 115);
21constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120); 24constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120);
22constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128); 25constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128);
23constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136); 26constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);