summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar german772023-06-04 15:50:44 -0600
committerGravatar Narr the Reg2023-06-06 17:06:21 -0600
commit107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e (patch)
tree409c20c05570bfd1ee86abe5e6c0cd2ec1069d17
parentMerge pull request #10651 from Morph1984/a (diff)
downloadyuzu-107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e.tar.gz
yuzu-107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e.tar.xz
yuzu-107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e.zip
service: nfc: Add backup support
-rw-r--r--src/common/fs/fs_paths.h1
-rw-r--r--src/common/fs/path_util.cpp1
-rw-r--r--src/common/fs/path_util.h1
-rw-r--r--src/core/hle/service/nfc/common/device.cpp160
-rw-r--r--src/core/hle/service/nfc/common/device.h10
-rw-r--r--src/core/hle/service/nfc/common/device_manager.cpp14
-rw-r--r--src/core/hle/service/nfc/nfc_interface.cpp8
-rw-r--r--src/core/hle/service/nfc/nfc_result.h20
-rw-r--r--src/core/hle/service/nfp/nfp_interface.cpp6
-rw-r--r--src/core/hle/service/nfp/nfp_result.h2
10 files changed, 184 insertions, 39 deletions
diff --git a/src/common/fs/fs_paths.h b/src/common/fs/fs_paths.h
index c77c112f1..61bac9eba 100644
--- a/src/common/fs/fs_paths.h
+++ b/src/common/fs/fs_paths.h
@@ -10,6 +10,7 @@
10 10
11// Sub-directories contained within a yuzu data directory 11// Sub-directories contained within a yuzu data directory
12 12
13#define AMIIBO_DIR "amiibo"
13#define CACHE_DIR "cache" 14#define CACHE_DIR "cache"
14#define CONFIG_DIR "config" 15#define CONFIG_DIR "config"
15#define DUMP_DIR "dump" 16#define DUMP_DIR "dump"
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index e026a13d9..d71cfacc6 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -114,6 +114,7 @@ public:
114#endif 114#endif
115 115
116 GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path); 116 GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path);
117 GenerateYuzuPath(YuzuPath::AmiiboDir, yuzu_path / AMIIBO_DIR);
117 GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache); 118 GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache);
118 GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config); 119 GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config);
119 GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR); 120 GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR);
diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h
index 7cfe85b70..ba28964d0 100644
--- a/src/common/fs/path_util.h
+++ b/src/common/fs/path_util.h
@@ -12,6 +12,7 @@ namespace Common::FS {
12 12
13enum class YuzuPath { 13enum class YuzuPath {
14 YuzuDir, // Where yuzu stores its data. 14 YuzuDir, // Where yuzu stores its data.
15 AmiiboDir, // Where Amiibo backups are stored.
15 CacheDir, // Where cached filesystem data is stored. 16 CacheDir, // Where cached filesystem data is stored.
16 ConfigDir, // Where config files are stored. 17 ConfigDir, // Where config files are stored.
17 DumpDir, // Where dumped data is stored. 18 DumpDir, // Where dumped data is stored.
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index 0bd7900e1..b14f682b5 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -12,6 +12,11 @@
12#pragma warning(pop) 12#pragma warning(pop)
13#endif 13#endif
14 14
15#include <fmt/format.h>
16
17#include "common/fs/file.h"
18#include "common/fs/fs.h"
19#include "common/fs/path_util.h"
15#include "common/input.h" 20#include "common/input.h"
16#include "common/logging/log.h" 21#include "common/logging/log.h"
17#include "common/string_util.h" 22#include "common/string_util.h"
@@ -136,7 +141,7 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) {
136 if (!NFP::AmiiboCrypto::IsKeyAvailable()) { 141 if (!NFP::AmiiboCrypto::IsKeyAvailable()) {
137 LOG_INFO(Service_NFC, "Loading amiibo without keys"); 142 LOG_INFO(Service_NFC, "Loading amiibo without keys");
138 memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); 143 memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
139 BuildAmiiboWithoutKeys(); 144 BuildAmiiboWithoutKeys(tag_data, encrypted_tag_data);
140 is_plain_amiibo = true; 145 is_plain_amiibo = true;
141 is_write_protected = true; 146 is_write_protected = true;
142 return true; 147 return true;
@@ -366,16 +371,25 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target
366 371
367 // The loaded amiibo is not encrypted 372 // The loaded amiibo is not encrypted
368 if (is_plain_amiibo) { 373 if (is_plain_amiibo) {
374 std::vector<u8> data(sizeof(NFP::NTAG215File));
375 memcpy(data.data(), &tag_data, sizeof(tag_data));
376 WriteBackupData(tag_data.uid, data);
377
369 device_state = DeviceState::TagMounted; 378 device_state = DeviceState::TagMounted;
370 mount_target = mount_target_; 379 mount_target = mount_target_;
371 return ResultSuccess; 380 return ResultSuccess;
372 } 381 }
373 382
374 if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { 383 if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) {
375 LOG_ERROR(Service_NFP, "Can't decode amiibo {}", device_state); 384 bool has_backup = HasBackup(encrypted_tag_data.uuid.uid).IsSuccess();
376 return ResultCorruptedData; 385 LOG_ERROR(Service_NFP, "Can't decode amiibo, has_backup= {}", has_backup);
386 return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData;
377 } 387 }
378 388
389 std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
390 memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
391 WriteBackupData(encrypted_tag_data.uuid.uid, data);
392
379 device_state = DeviceState::TagMounted; 393 device_state = DeviceState::TagMounted;
380 mount_target = mount_target_; 394 mount_target = mount_target_;
381 return ResultSuccess; 395 return ResultSuccess;
@@ -470,6 +484,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {
470 std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); 484 std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
471 if (is_plain_amiibo) { 485 if (is_plain_amiibo) {
472 memcpy(data.data(), &tag_data, sizeof(tag_data)); 486 memcpy(data.data(), &tag_data, sizeof(tag_data));
487 WriteBackupData(tag_data.uid, data);
473 } else { 488 } else {
474 if (!NFP::AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { 489 if (!NFP::AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
475 LOG_ERROR(Service_NFP, "Failed to encode data"); 490 LOG_ERROR(Service_NFP, "Failed to encode data");
@@ -477,6 +492,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {
477 } 492 }
478 493
479 memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); 494 memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
495 WriteBackupData(encrypted_tag_data.uuid.uid, data);
480 } 496 }
481 497
482 if (!npad_device->WriteNfc(data)) { 498 if (!npad_device->WriteNfc(data)) {
@@ -488,7 +504,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {
488} 504}
489 505
490Result NfcDevice::Restore() { 506Result NfcDevice::Restore() {
491 if (device_state != DeviceState::TagMounted) { 507 if (device_state != DeviceState::TagFound) {
492 LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); 508 LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
493 if (device_state == DeviceState::TagRemoved) { 509 if (device_state == DeviceState::TagRemoved) {
494 return ResultTagRemoved; 510 return ResultTagRemoved;
@@ -496,13 +512,59 @@ Result NfcDevice::Restore() {
496 return ResultWrongDeviceState; 512 return ResultWrongDeviceState;
497 } 513 }
498 514
499 if (mount_target == NFP::MountTarget::None || mount_target == NFP::MountTarget::Rom) { 515 NFC::TagInfo tag_info{};
500 LOG_ERROR(Service_NFC, "Amiibo is read only", device_state); 516 std::array<u8, sizeof(NFP::EncryptedNTAG215File)> data{};
501 return ResultWrongDeviceState; 517 Result result = GetTagInfo(tag_info, false);
518
519 if (result.IsError()) {
520 return result;
502 } 521 }
503 522
504 // TODO: Load amiibo from backup on system 523 result = ReadBackupData(tag_info.uuid, data);
505 LOG_ERROR(Service_NFP, "Not Implemented"); 524
525 if (result.IsError()) {
526 return result;
527 }
528
529 NFP::NTAG215File temporary_tag_data{};
530 NFP::EncryptedNTAG215File temporary_encrypted_tag_data{};
531
532 // Fallback for encrypted amiibos without keys
533 if (is_write_protected) {
534 return ResultWriteAmiiboFailed;
535 }
536
537 // Fallback for plain amiibos
538 if (is_plain_amiibo) {
539 LOG_INFO(Service_NFP, "Restoring backup of plain amiibo");
540 memcpy(&temporary_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
541 temporary_encrypted_tag_data = NFP::AmiiboCrypto::EncodedDataToNfcData(temporary_tag_data);
542 }
543
544 if (!is_plain_amiibo) {
545 LOG_INFO(Service_NFP, "Restoring backup of encrypted amiibo");
546 temporary_tag_data = {};
547 memcpy(&temporary_encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
548 }
549
550 if (!NFP::AmiiboCrypto::IsAmiiboValid(temporary_encrypted_tag_data)) {
551 return ResultNotAnAmiibo;
552 }
553
554 if (!is_plain_amiibo) {
555 if (!NFP::AmiiboCrypto::DecodeAmiibo(temporary_encrypted_tag_data, temporary_tag_data)) {
556 LOG_ERROR(Service_NFP, "Can't decode amiibo");
557 return ResultCorruptedData;
558 }
559 }
560
561 // Overwrite tag contents with backup and mount the tag
562 tag_data = temporary_tag_data;
563 encrypted_tag_data = temporary_encrypted_tag_data;
564 device_state = DeviceState::TagMounted;
565 mount_target = NFP::MountTarget::All;
566 is_data_moddified = true;
567
506 return ResultSuccess; 568 return ResultSuccess;
507} 569}
508 570
@@ -1132,13 +1194,69 @@ Result NfcDevice::BreakTag(NFP::BreakType break_type) {
1132 return FlushWithBreak(break_type); 1194 return FlushWithBreak(break_type);
1133} 1195}
1134 1196
1135Result NfcDevice::ReadBackupData(std::span<u8> data) const { 1197Result NfcDevice::HasBackup(const NFC::UniqueSerialNumber& uid) const {
1136 // Not implemented 1198 constexpr auto backup_dir = "backup";
1199 const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir);
1200 const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, ""));
1201
1202 if (!Common::FS::Exists(yuzu_amiibo_dir / backup_dir / file_name)) {
1203 return ResultUnableToAccessBackupFile;
1204 }
1205
1137 return ResultSuccess; 1206 return ResultSuccess;
1138} 1207}
1139 1208
1140Result NfcDevice::WriteBackupData(std::span<const u8> data) { 1209Result NfcDevice::ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u8> data) const {
1141 // Not implemented 1210 constexpr auto backup_dir = "backup";
1211 const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir);
1212 const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, ""));
1213
1214 const Common::FS::IOFile keys_file{yuzu_amiibo_dir / backup_dir / file_name,
1215 Common::FS::FileAccessMode::Read,
1216 Common::FS::FileType::BinaryFile};
1217
1218 if (!keys_file.IsOpen()) {
1219 LOG_ERROR(Service_NFP, "Failed to open amiibo backup");
1220 return ResultUnableToAccessBackupFile;
1221 }
1222
1223 if (keys_file.Read(data) != data.size()) {
1224 LOG_ERROR(Service_NFP, "Failed to read amiibo backup");
1225 return ResultUnableToAccessBackupFile;
1226 }
1227
1228 return ResultSuccess;
1229}
1230
1231Result NfcDevice::WriteBackupData(const NFC::UniqueSerialNumber& uid, std::span<const u8> data) {
1232 constexpr auto backup_dir = "backup";
1233 const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir);
1234 const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, ""));
1235
1236 if (HasBackup(uid).IsError()) {
1237 if (!Common::FS::CreateDir(yuzu_amiibo_dir / backup_dir)) {
1238 return ResultBackupPathAlreadyExist;
1239 }
1240
1241 if (!Common::FS::NewFile(yuzu_amiibo_dir / backup_dir / file_name)) {
1242 return ResultBackupPathAlreadyExist;
1243 }
1244 }
1245
1246 const Common::FS::IOFile keys_file{yuzu_amiibo_dir / backup_dir / file_name,
1247 Common::FS::FileAccessMode::ReadWrite,
1248 Common::FS::FileType::BinaryFile};
1249
1250 if (!keys_file.IsOpen()) {
1251 LOG_ERROR(Service_NFP, "Failed to open amiibo backup");
1252 return ResultUnableToAccessBackupFile;
1253 }
1254
1255 if (keys_file.Write(data) != data.size()) {
1256 LOG_ERROR(Service_NFP, "Failed to write amiibo backup");
1257 return ResultUnableToAccessBackupFile;
1258 }
1259
1142 return ResultSuccess; 1260 return ResultSuccess;
1143} 1261}
1144 1262
@@ -1177,7 +1295,8 @@ NFP::AmiiboName NfcDevice::GetAmiiboName(const NFP::AmiiboSettings& settings) co
1177 return amiibo_name; 1295 return amiibo_name;
1178} 1296}
1179 1297
1180void NfcDevice::SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name) { 1298void NfcDevice::SetAmiiboName(NFP::AmiiboSettings& settings,
1299 const NFP::AmiiboName& amiibo_name) const {
1181 std::array<char16_t, NFP::amiibo_name_length> settings_amiibo_name{}; 1300 std::array<char16_t, NFP::amiibo_name_length> settings_amiibo_name{};
1182 1301
1183 // Convert from utf8 to utf16 1302 // Convert from utf8 to utf16
@@ -1258,22 +1377,23 @@ void NfcDevice::UpdateRegisterInfoCrc() {
1258 tag_data.register_info_crc = crc.checksum(); 1377 tag_data.register_info_crc = crc.checksum();
1259} 1378}
1260 1379
1261void NfcDevice::BuildAmiiboWithoutKeys() { 1380void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data,
1381 const NFP::EncryptedNTAG215File& encrypted_file) const {
1262 Service::Mii::MiiManager manager; 1382 Service::Mii::MiiManager manager;
1263 auto& settings = tag_data.settings; 1383 auto& settings = stubbed_tag_data.settings;
1264 1384
1265 tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_tag_data); 1385 stubbed_tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_file);
1266 1386
1267 // Common info 1387 // Common info
1268 tag_data.write_counter = 0; 1388 stubbed_tag_data.write_counter = 0;
1269 tag_data.amiibo_version = 0; 1389 stubbed_tag_data.amiibo_version = 0;
1270 settings.write_date = GetAmiiboDate(GetCurrentPosixTime()); 1390 settings.write_date = GetAmiiboDate(GetCurrentPosixTime());
1271 1391
1272 // Register info 1392 // Register info
1273 SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); 1393 SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'});
1274 settings.settings.font_region.Assign(0); 1394 settings.settings.font_region.Assign(0);
1275 settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); 1395 settings.init_date = GetAmiiboDate(GetCurrentPosixTime());
1276 tag_data.owner_mii = manager.BuildFromStoreData(manager.BuildDefault(0)); 1396 stubbed_tag_data.owner_mii = manager.BuildFromStoreData(manager.BuildDefault(0));
1277 1397
1278 // Admin info 1398 // Admin info
1279 settings.settings.amiibo_initialized.Assign(1); 1399 settings.settings.amiibo_initialized.Assign(1);
diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h
index 6a37e8458..6f049b687 100644
--- a/src/core/hle/service/nfc/common/device.h
+++ b/src/core/hle/service/nfc/common/device.h
@@ -86,8 +86,9 @@ public:
86 Result GetAll(NFP::NfpData& data) const; 86 Result GetAll(NFP::NfpData& data) const;
87 Result SetAll(const NFP::NfpData& data); 87 Result SetAll(const NFP::NfpData& data);
88 Result BreakTag(NFP::BreakType break_type); 88 Result BreakTag(NFP::BreakType break_type);
89 Result ReadBackupData(std::span<u8> data) const; 89 Result HasBackup(const NFC::UniqueSerialNumber& uid) const;
90 Result WriteBackupData(std::span<const u8> data); 90 Result ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u8> data) const;
91 Result WriteBackupData(const NFC::UniqueSerialNumber& uid, std::span<const u8> data);
91 Result WriteNtf(std::span<const u8> data); 92 Result WriteNtf(std::span<const u8> data);
92 93
93 u64 GetHandle() const; 94 u64 GetHandle() const;
@@ -103,14 +104,15 @@ private:
103 void CloseNfcTag(); 104 void CloseNfcTag();
104 105
105 NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; 106 NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const;
106 void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name); 107 void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name) const;
107 NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const; 108 NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const;
108 u64 GetCurrentPosixTime() const; 109 u64 GetCurrentPosixTime() const;
109 u64 RemoveVersionByte(u64 application_id) const; 110 u64 RemoveVersionByte(u64 application_id) const;
110 void UpdateSettingsCrc(); 111 void UpdateSettingsCrc();
111 void UpdateRegisterInfoCrc(); 112 void UpdateRegisterInfoCrc();
112 113
113 void BuildAmiiboWithoutKeys(); 114 void BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data,
115 const NFP::EncryptedNTAG215File& encrypted_file) const;
114 116
115 bool is_controller_set{}; 117 bool is_controller_set{};
116 int callback_key; 118 int callback_key;
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index d5deaaf27..cffd602df 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -543,9 +543,14 @@ Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) cons
543 543
544 std::shared_ptr<NfcDevice> device = nullptr; 544 std::shared_ptr<NfcDevice> device = nullptr;
545 auto result = GetDeviceHandle(device_handle, device); 545 auto result = GetDeviceHandle(device_handle, device);
546 NFC::TagInfo tag_info{};
546 547
547 if (result.IsSuccess()) { 548 if (result.IsSuccess()) {
548 result = device->ReadBackupData(data); 549 result = device->GetTagInfo(tag_info, false);
550 }
551
552 if (result.IsSuccess()) {
553 result = device->ReadBackupData(tag_info.uuid, data);
549 result = VerifyDeviceResult(device, result); 554 result = VerifyDeviceResult(device, result);
550 } 555 }
551 556
@@ -557,9 +562,14 @@ Result DeviceManager::WriteBackupData(u64 device_handle, std::span<const u8> dat
557 562
558 std::shared_ptr<NfcDevice> device = nullptr; 563 std::shared_ptr<NfcDevice> device = nullptr;
559 auto result = GetDeviceHandle(device_handle, device); 564 auto result = GetDeviceHandle(device_handle, device);
565 NFC::TagInfo tag_info{};
566
567 if (result.IsSuccess()) {
568 result = device->GetTagInfo(tag_info, false);
569 }
560 570
561 if (result.IsSuccess()) { 571 if (result.IsSuccess()) {
562 result = device->WriteBackupData(data); 572 result = device->WriteBackupData(tag_info.uuid, data);
563 result = VerifyDeviceResult(device, result); 573 result = VerifyDeviceResult(device, result);
564 } 574 }
565 575
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp
index 0fa29d398..198d0f2b9 100644
--- a/src/core/hle/service/nfc/nfc_interface.cpp
+++ b/src/core/hle/service/nfc/nfc_interface.cpp
@@ -302,7 +302,7 @@ Result NfcInterface::TranslateResultToServiceError(Result result) const {
302 return TranslateResultToNfp(result); 302 return TranslateResultToNfp(result);
303 } 303 }
304 default: 304 default:
305 if (result != ResultUnknown216) { 305 if (result != ResultBackupPathAlreadyExist) {
306 return result; 306 return result;
307 } 307 }
308 return ResultUnknown74; 308 return ResultUnknown74;
@@ -343,6 +343,9 @@ Result NfcInterface::TranslateResultToNfp(Result result) const {
343 if (result == ResultApplicationAreaIsNotInitialized) { 343 if (result == ResultApplicationAreaIsNotInitialized) {
344 return NFP::ResultApplicationAreaIsNotInitialized; 344 return NFP::ResultApplicationAreaIsNotInitialized;
345 } 345 }
346 if (result == ResultCorruptedDataWithBackup) {
347 return NFP::ResultCorruptedDataWithBackup;
348 }
346 if (result == ResultCorruptedData) { 349 if (result == ResultCorruptedData) {
347 return NFP::ResultCorruptedData; 350 return NFP::ResultCorruptedData;
348 } 351 }
@@ -355,6 +358,9 @@ Result NfcInterface::TranslateResultToNfp(Result result) const {
355 if (result == ResultNotAnAmiibo) { 358 if (result == ResultNotAnAmiibo) {
356 return NFP::ResultNotAnAmiibo; 359 return NFP::ResultNotAnAmiibo;
357 } 360 }
361 if (result == ResultUnableToAccessBackupFile) {
362 return NFP::ResultUnableToAccessBackupFile;
363 }
358 LOG_WARNING(Service_NFC, "Result conversion not handled"); 364 LOG_WARNING(Service_NFC, "Result conversion not handled");
359 return result; 365 return result;
360} 366}
diff --git a/src/core/hle/service/nfc/nfc_result.h b/src/core/hle/service/nfc/nfc_result.h
index 917d79ef8..59a808740 100644
--- a/src/core/hle/service/nfc/nfc_result.h
+++ b/src/core/hle/service/nfc/nfc_result.h
@@ -9,20 +9,22 @@ namespace Service::NFC {
9 9
10constexpr Result ResultDeviceNotFound(ErrorModule::NFC, 64); 10constexpr Result ResultDeviceNotFound(ErrorModule::NFC, 64);
11constexpr Result ResultInvalidArgument(ErrorModule::NFC, 65); 11constexpr Result ResultInvalidArgument(ErrorModule::NFC, 65);
12constexpr Result ResultWrongApplicationAreaSize(ErrorModule::NFP, 68); 12constexpr Result ResultWrongApplicationAreaSize(ErrorModule::NFC, 68);
13constexpr Result ResultWrongDeviceState(ErrorModule::NFC, 73); 13constexpr Result ResultWrongDeviceState(ErrorModule::NFC, 73);
14constexpr Result ResultUnknown74(ErrorModule::NFC, 74); 14constexpr Result ResultUnknown74(ErrorModule::NFC, 74);
15constexpr Result ResultUnknown76(ErrorModule::NFC, 76); 15constexpr Result ResultUnknown76(ErrorModule::NFC, 76);
16constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77); 16constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77);
17constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); 17constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80);
18constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFP, 88); 18constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88);
19constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); 19constexpr Result ResultTagRemoved(ErrorModule::NFC, 97);
20constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120); 20constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113);
21constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); 21constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120);
22constexpr Result ResultCorruptedData(ErrorModule::NFP, 144); 22constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128);
23constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152); 23constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);
24constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168); 24constexpr Result ResultCorruptedData(ErrorModule::NFC, 144);
25constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178); 25constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFC, 152);
26constexpr Result ResultUnknown216(ErrorModule::NFC, 216); 26constexpr Result ResultApplicationAreaExist(ErrorModule::NFC, 168);
27constexpr Result ResultNotAnAmiibo(ErrorModule::NFC, 178);
28constexpr Result ResultBackupPathAlreadyExist(ErrorModule::NFC, 216);
27 29
28} // namespace Service::NFC 30} // namespace Service::NFC
diff --git a/src/core/hle/service/nfp/nfp_interface.cpp b/src/core/hle/service/nfp/nfp_interface.cpp
index 21d159154..34ef9d82d 100644
--- a/src/core/hle/service/nfp/nfp_interface.cpp
+++ b/src/core/hle/service/nfp/nfp_interface.cpp
@@ -126,7 +126,7 @@ void Interface::Flush(HLERequestContext& ctx) {
126void Interface::Restore(HLERequestContext& ctx) { 126void Interface::Restore(HLERequestContext& ctx) {
127 IPC::RequestParser rp{ctx}; 127 IPC::RequestParser rp{ctx};
128 const auto device_handle{rp.Pop<u64>()}; 128 const auto device_handle{rp.Pop<u64>()};
129 LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); 129 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
130 130
131 auto result = GetManager()->Restore(device_handle); 131 auto result = GetManager()->Restore(device_handle);
132 result = TranslateResultToServiceError(result); 132 result = TranslateResultToServiceError(result);
@@ -394,7 +394,7 @@ void Interface::BreakTag(HLERequestContext& ctx) {
394void Interface::ReadBackupData(HLERequestContext& ctx) { 394void Interface::ReadBackupData(HLERequestContext& ctx) {
395 IPC::RequestParser rp{ctx}; 395 IPC::RequestParser rp{ctx};
396 const auto device_handle{rp.Pop<u64>()}; 396 const auto device_handle{rp.Pop<u64>()};
397 LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); 397 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
398 398
399 std::vector<u8> backup_data{}; 399 std::vector<u8> backup_data{};
400 auto result = GetManager()->ReadBackupData(device_handle, backup_data); 400 auto result = GetManager()->ReadBackupData(device_handle, backup_data);
@@ -412,7 +412,7 @@ void Interface::WriteBackupData(HLERequestContext& ctx) {
412 IPC::RequestParser rp{ctx}; 412 IPC::RequestParser rp{ctx};
413 const auto device_handle{rp.Pop<u64>()}; 413 const auto device_handle{rp.Pop<u64>()};
414 const auto backup_data_buffer{ctx.ReadBuffer()}; 414 const auto backup_data_buffer{ctx.ReadBuffer()};
415 LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); 415 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
416 416
417 auto result = GetManager()->WriteBackupData(device_handle, backup_data_buffer); 417 auto result = GetManager()->WriteBackupData(device_handle, backup_data_buffer);
418 result = TranslateResultToServiceError(result); 418 result = TranslateResultToServiceError(result);
diff --git a/src/core/hle/service/nfp/nfp_result.h b/src/core/hle/service/nfp/nfp_result.h
index 4c126cd81..618533843 100644
--- a/src/core/hle/service/nfp/nfp_result.h
+++ b/src/core/hle/service/nfp/nfp_result.h
@@ -17,9 +17,11 @@ constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFP, 88);
17constexpr Result ResultTagRemoved(ErrorModule::NFP, 97); 17constexpr Result ResultTagRemoved(ErrorModule::NFP, 97);
18constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120); 18constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120);
19constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); 19constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128);
20constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFP, 136);
20constexpr Result ResultCorruptedData(ErrorModule::NFP, 144); 21constexpr Result ResultCorruptedData(ErrorModule::NFP, 144);
21constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152); 22constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152);
22constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168); 23constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168);
23constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178); 24constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178);
25constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFP, 200);
24 26
25} // namespace Service::NFP 27} // namespace Service::NFP