diff options
| author | 2023-06-04 15:50:44 -0600 | |
|---|---|---|
| committer | 2023-06-06 17:06:21 -0600 | |
| commit | 107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e (patch) | |
| tree | 409c20c05570bfd1ee86abe5e6c0cd2ec1069d17 | |
| parent | Merge pull request #10651 from Morph1984/a (diff) | |
| download | yuzu-107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e.tar.gz yuzu-107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e.tar.xz yuzu-107aa52cdbf9c6e7dc4a6e95da3ae18bc382778e.zip | |
service: nfc: Add backup support
| -rw-r--r-- | src/common/fs/fs_paths.h | 1 | ||||
| -rw-r--r-- | src/common/fs/path_util.cpp | 1 | ||||
| -rw-r--r-- | src/common/fs/path_util.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device.cpp | 160 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device.h | 10 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device_manager.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/nfc_interface.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/nfc_result.h | 20 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_interface.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_result.h | 2 |
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 | ||
| 13 | enum class YuzuPath { | 13 | enum 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 | ||
| 490 | Result NfcDevice::Restore() { | 506 | Result 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 | ||
| 1135 | Result NfcDevice::ReadBackupData(std::span<u8> data) const { | 1197 | Result 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 | ||
| 1140 | Result NfcDevice::WriteBackupData(std::span<const u8> data) { | 1209 | Result 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 | |||
| 1231 | Result 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 | ||
| 1180 | void NfcDevice::SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name) { | 1298 | void 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 | ||
| 1261 | void NfcDevice::BuildAmiiboWithoutKeys() { | 1380 | void 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 | ||
| 10 | constexpr Result ResultDeviceNotFound(ErrorModule::NFC, 64); | 10 | constexpr Result ResultDeviceNotFound(ErrorModule::NFC, 64); |
| 11 | constexpr Result ResultInvalidArgument(ErrorModule::NFC, 65); | 11 | constexpr Result ResultInvalidArgument(ErrorModule::NFC, 65); |
| 12 | constexpr Result ResultWrongApplicationAreaSize(ErrorModule::NFP, 68); | 12 | constexpr Result ResultWrongApplicationAreaSize(ErrorModule::NFC, 68); |
| 13 | constexpr Result ResultWrongDeviceState(ErrorModule::NFC, 73); | 13 | constexpr Result ResultWrongDeviceState(ErrorModule::NFC, 73); |
| 14 | constexpr Result ResultUnknown74(ErrorModule::NFC, 74); | 14 | constexpr Result ResultUnknown74(ErrorModule::NFC, 74); |
| 15 | constexpr Result ResultUnknown76(ErrorModule::NFC, 76); | 15 | constexpr Result ResultUnknown76(ErrorModule::NFC, 76); |
| 16 | constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77); | 16 | constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77); |
| 17 | constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); | 17 | constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); |
| 18 | constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFP, 88); | 18 | constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88); |
| 19 | constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); | 19 | constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); |
| 20 | constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120); | 20 | constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113); |
| 21 | constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); | 21 | constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120); |
| 22 | constexpr Result ResultCorruptedData(ErrorModule::NFP, 144); | 22 | constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128); |
| 23 | constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152); | 23 | constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136); |
| 24 | constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168); | 24 | constexpr Result ResultCorruptedData(ErrorModule::NFC, 144); |
| 25 | constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178); | 25 | constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFC, 152); |
| 26 | constexpr Result ResultUnknown216(ErrorModule::NFC, 216); | 26 | constexpr Result ResultApplicationAreaExist(ErrorModule::NFC, 168); |
| 27 | constexpr Result ResultNotAnAmiibo(ErrorModule::NFC, 178); | ||
| 28 | constexpr 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) { | |||
| 126 | void Interface::Restore(HLERequestContext& ctx) { | 126 | void 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) { | |||
| 394 | void Interface::ReadBackupData(HLERequestContext& ctx) { | 394 | void 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); | |||
| 17 | constexpr Result ResultTagRemoved(ErrorModule::NFP, 97); | 17 | constexpr Result ResultTagRemoved(ErrorModule::NFP, 97); |
| 18 | constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120); | 18 | constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120); |
| 19 | constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); | 19 | constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); |
| 20 | constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFP, 136); | ||
| 20 | constexpr Result ResultCorruptedData(ErrorModule::NFP, 144); | 21 | constexpr Result ResultCorruptedData(ErrorModule::NFP, 144); |
| 21 | constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152); | 22 | constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152); |
| 22 | constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168); | 23 | constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168); |
| 23 | constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178); | 24 | constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178); |
| 25 | constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFP, 200); | ||
| 24 | 26 | ||
| 25 | } // namespace Service::NFP | 27 | } // namespace Service::NFP |