diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nfp/amiibo_crypto.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_device.cpp | 99 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_device.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_types.h | 24 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_user.cpp | 2 |
5 files changed, 124 insertions, 19 deletions
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp index 9e06970a4..ce0bc3f75 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.cpp +++ b/src/core/hle/service/nfp/amiibo_crypto.cpp | |||
| @@ -58,8 +58,9 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) { | |||
| 58 | if (amiibo_data.model_info.constant_value != 0x02) { | 58 | if (amiibo_data.model_info.constant_value != 0x02) { |
| 59 | return false; | 59 | return false; |
| 60 | } | 60 | } |
| 61 | // dynamic_lock value apparently is not constant | 61 | if ((ntag_file.dynamic_lock & 0xFFFFFF) != 0x0F0001U) { |
| 62 | // ntag_file.dynamic_lock == 0x0F0001 | 62 | return false; |
| 63 | } | ||
| 63 | if (ntag_file.CFG0 != 0x04000000U) { | 64 | if (ntag_file.CFG0 != 0x04000000U) { |
| 64 | return false; | 65 | return false; |
| 65 | } | 66 | } |
| @@ -85,7 +86,7 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { | |||
| 85 | encoded_data.applicaton_write_counter = nfc_data.user_memory.applicaton_write_counter; | 86 | encoded_data.applicaton_write_counter = nfc_data.user_memory.applicaton_write_counter; |
| 86 | encoded_data.application_area_id = nfc_data.user_memory.application_area_id; | 87 | encoded_data.application_area_id = nfc_data.user_memory.application_area_id; |
| 87 | encoded_data.unknown = nfc_data.user_memory.unknown; | 88 | encoded_data.unknown = nfc_data.user_memory.unknown; |
| 88 | encoded_data.hash = nfc_data.user_memory.hash; | 89 | encoded_data.unknown2 = nfc_data.user_memory.unknown2; |
| 89 | encoded_data.application_area = nfc_data.user_memory.application_area; | 90 | encoded_data.application_area = nfc_data.user_memory.application_area; |
| 90 | encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag; | 91 | encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag; |
| 91 | encoded_data.lock_bytes = nfc_data.uuid.lock_bytes; | 92 | encoded_data.lock_bytes = nfc_data.uuid.lock_bytes; |
| @@ -116,7 +117,7 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) { | |||
| 116 | nfc_data.user_memory.applicaton_write_counter = encoded_data.applicaton_write_counter; | 117 | nfc_data.user_memory.applicaton_write_counter = encoded_data.applicaton_write_counter; |
| 117 | nfc_data.user_memory.application_area_id = encoded_data.application_area_id; | 118 | nfc_data.user_memory.application_area_id = encoded_data.application_area_id; |
| 118 | nfc_data.user_memory.unknown = encoded_data.unknown; | 119 | nfc_data.user_memory.unknown = encoded_data.unknown; |
| 119 | nfc_data.user_memory.hash = encoded_data.hash; | 120 | nfc_data.user_memory.unknown2 = encoded_data.unknown2; |
| 120 | nfc_data.user_memory.application_area = encoded_data.application_area; | 121 | nfc_data.user_memory.application_area = encoded_data.application_area; |
| 121 | nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag; | 122 | nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag; |
| 122 | nfc_data.user_memory.model_info = encoded_data.model_info; | 123 | nfc_data.user_memory.model_info = encoded_data.model_info; |
| @@ -181,7 +182,6 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed | |||
| 181 | 182 | ||
| 182 | void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, | 183 | void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, |
| 183 | const std::vector<u8>& seed) { | 184 | const std::vector<u8>& seed) { |
| 184 | |||
| 185 | // Initialize context | 185 | // Initialize context |
| 186 | ctx.used = false; | 186 | ctx.used = false; |
| 187 | ctx.counter = 0; | 187 | ctx.counter = 0; |
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index f0eaa7df2..0d4ffd3a5 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp | |||
| @@ -85,7 +85,7 @@ void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { | |||
| 85 | } | 85 | } |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | bool NfpDevice::LoadAmiibo(const std::vector<u8>& data) { | 88 | bool NfpDevice::LoadAmiibo(std::span<const u8> data) { |
| 89 | if (device_state != DeviceState::SearchingForTag) { | 89 | if (device_state != DeviceState::SearchingForTag) { |
| 90 | LOG_ERROR(Service_NFP, "Game is not looking for amiibos, current state {}", device_state); | 90 | LOG_ERROR(Service_NFP, "Game is not looking for amiibos, current state {}", device_state); |
| 91 | return false; | 91 | return false; |
| @@ -176,6 +176,19 @@ Result NfpDevice::StopDetection() { | |||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | Result NfpDevice::Flush() { | 178 | Result NfpDevice::Flush() { |
| 179 | if (device_state != DeviceState::TagMounted) { | ||
| 180 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | ||
| 181 | if (device_state == DeviceState::TagRemoved) { | ||
| 182 | return TagRemoved; | ||
| 183 | } | ||
| 184 | return WrongDeviceState; | ||
| 185 | } | ||
| 186 | |||
| 187 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 188 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 189 | return WrongDeviceState; | ||
| 190 | } | ||
| 191 | |||
| 179 | auto& settings = tag_data.settings; | 192 | auto& settings = tag_data.settings; |
| 180 | 193 | ||
| 181 | const auto& current_date = GetAmiiboDate(current_posix_time); | 194 | const auto& current_date = GetAmiiboDate(current_posix_time); |
| @@ -206,7 +219,7 @@ Result NfpDevice::Flush() { | |||
| 206 | return ResultSuccess; | 219 | return ResultSuccess; |
| 207 | } | 220 | } |
| 208 | 221 | ||
| 209 | Result NfpDevice::Mount() { | 222 | Result NfpDevice::Mount(MountTarget mount_target_) { |
| 210 | if (device_state != DeviceState::TagFound) { | 223 | if (device_state != DeviceState::TagFound) { |
| 211 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 224 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 212 | return WrongDeviceState; | 225 | return WrongDeviceState; |
| @@ -218,6 +231,7 @@ Result NfpDevice::Mount() { | |||
| 218 | } | 231 | } |
| 219 | 232 | ||
| 220 | device_state = DeviceState::TagMounted; | 233 | device_state = DeviceState::TagMounted; |
| 234 | mount_target = mount_target_; | ||
| 221 | return ResultSuccess; | 235 | return ResultSuccess; |
| 222 | } | 236 | } |
| 223 | 237 | ||
| @@ -233,6 +247,9 @@ Result NfpDevice::Unmount() { | |||
| 233 | } | 247 | } |
| 234 | 248 | ||
| 235 | device_state = DeviceState::TagFound; | 249 | device_state = DeviceState::TagFound; |
| 250 | mount_target = MountTarget::None; | ||
| 251 | is_app_area_open = false; | ||
| 252 | |||
| 236 | return ResultSuccess; | 253 | return ResultSuccess; |
| 237 | } | 254 | } |
| 238 | 255 | ||
| @@ -245,8 +262,8 @@ Result NfpDevice::GetTagInfo(TagInfo& tag_info) const { | |||
| 245 | tag_info = { | 262 | tag_info = { |
| 246 | .uuid = encrypted_tag_data.uuid.uid, | 263 | .uuid = encrypted_tag_data.uuid.uid, |
| 247 | .uuid_length = static_cast<u8>(encrypted_tag_data.uuid.uid.size()), | 264 | .uuid_length = static_cast<u8>(encrypted_tag_data.uuid.uid.size()), |
| 248 | .protocol = 1, | 265 | .protocol = TagProtocol::TypeA, |
| 249 | .tag_type = 2, | 266 | .tag_type = TagType::Type2, |
| 250 | }; | 267 | }; |
| 251 | 268 | ||
| 252 | return ResultSuccess; | 269 | return ResultSuccess; |
| @@ -255,6 +272,14 @@ Result NfpDevice::GetTagInfo(TagInfo& tag_info) const { | |||
| 255 | Result NfpDevice::GetCommonInfo(CommonInfo& common_info) const { | 272 | Result NfpDevice::GetCommonInfo(CommonInfo& common_info) const { |
| 256 | if (device_state != DeviceState::TagMounted) { | 273 | if (device_state != DeviceState::TagMounted) { |
| 257 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 274 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 275 | if (device_state == DeviceState::TagRemoved) { | ||
| 276 | return TagRemoved; | ||
| 277 | } | ||
| 278 | return WrongDeviceState; | ||
| 279 | } | ||
| 280 | |||
| 281 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 282 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 258 | return WrongDeviceState; | 283 | return WrongDeviceState; |
| 259 | } | 284 | } |
| 260 | 285 | ||
| @@ -301,6 +326,11 @@ Result NfpDevice::GetRegisterInfo(RegisterInfo& register_info) const { | |||
| 301 | return WrongDeviceState; | 326 | return WrongDeviceState; |
| 302 | } | 327 | } |
| 303 | 328 | ||
| 329 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 330 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 331 | return WrongDeviceState; | ||
| 332 | } | ||
| 333 | |||
| 304 | if (tag_data.settings.settings.amiibo_initialized == 0) { | 334 | if (tag_data.settings.settings.amiibo_initialized == 0) { |
| 305 | return RegistrationIsNotInitialized; | 335 | return RegistrationIsNotInitialized; |
| 306 | } | 336 | } |
| @@ -333,6 +363,11 @@ Result NfpDevice::SetNicknameAndOwner(const AmiiboName& amiibo_name) { | |||
| 333 | return WrongDeviceState; | 363 | return WrongDeviceState; |
| 334 | } | 364 | } |
| 335 | 365 | ||
| 366 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 367 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 368 | return WrongDeviceState; | ||
| 369 | } | ||
| 370 | |||
| 336 | Service::Mii::MiiManager manager; | 371 | Service::Mii::MiiManager manager; |
| 337 | auto& settings = tag_data.settings; | 372 | auto& settings = tag_data.settings; |
| 338 | 373 | ||
| @@ -350,6 +385,19 @@ Result NfpDevice::SetNicknameAndOwner(const AmiiboName& amiibo_name) { | |||
| 350 | } | 385 | } |
| 351 | 386 | ||
| 352 | Result NfpDevice::RestoreAmiibo() { | 387 | Result NfpDevice::RestoreAmiibo() { |
| 388 | if (device_state != DeviceState::TagMounted) { | ||
| 389 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | ||
| 390 | if (device_state == DeviceState::TagRemoved) { | ||
| 391 | return TagRemoved; | ||
| 392 | } | ||
| 393 | return WrongDeviceState; | ||
| 394 | } | ||
| 395 | |||
| 396 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 397 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 398 | return WrongDeviceState; | ||
| 399 | } | ||
| 400 | |||
| 353 | // TODO: Load amiibo from backup on system | 401 | // TODO: Load amiibo from backup on system |
| 354 | LOG_ERROR(Service_NFP, "Not Implemented"); | 402 | LOG_ERROR(Service_NFP, "Not Implemented"); |
| 355 | return ResultSuccess; | 403 | return ResultSuccess; |
| @@ -385,6 +433,11 @@ Result NfpDevice::OpenApplicationArea(u32 access_id) { | |||
| 385 | return WrongDeviceState; | 433 | return WrongDeviceState; |
| 386 | } | 434 | } |
| 387 | 435 | ||
| 436 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 437 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 438 | return WrongDeviceState; | ||
| 439 | } | ||
| 440 | |||
| 388 | if (tag_data.settings.settings.appdata_initialized.Value() == 0) { | 441 | if (tag_data.settings.settings.appdata_initialized.Value() == 0) { |
| 389 | LOG_WARNING(Service_NFP, "Application area is not initialized"); | 442 | LOG_WARNING(Service_NFP, "Application area is not initialized"); |
| 390 | return ApplicationAreaIsNotInitialized; | 443 | return ApplicationAreaIsNotInitialized; |
| @@ -395,6 +448,8 @@ Result NfpDevice::OpenApplicationArea(u32 access_id) { | |||
| 395 | return WrongApplicationAreaId; | 448 | return WrongApplicationAreaId; |
| 396 | } | 449 | } |
| 397 | 450 | ||
| 451 | is_app_area_open = true; | ||
| 452 | |||
| 398 | return ResultSuccess; | 453 | return ResultSuccess; |
| 399 | } | 454 | } |
| 400 | 455 | ||
| @@ -407,6 +462,16 @@ Result NfpDevice::GetApplicationArea(std::vector<u8>& data) const { | |||
| 407 | return WrongDeviceState; | 462 | return WrongDeviceState; |
| 408 | } | 463 | } |
| 409 | 464 | ||
| 465 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 466 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 467 | return WrongDeviceState; | ||
| 468 | } | ||
| 469 | |||
| 470 | if (!is_app_area_open) { | ||
| 471 | LOG_ERROR(Service_NFP, "Application area is not open"); | ||
| 472 | return WrongDeviceState; | ||
| 473 | } | ||
| 474 | |||
| 410 | if (tag_data.settings.settings.appdata_initialized.Value() == 0) { | 475 | if (tag_data.settings.settings.appdata_initialized.Value() == 0) { |
| 411 | LOG_ERROR(Service_NFP, "Application area is not initialized"); | 476 | LOG_ERROR(Service_NFP, "Application area is not initialized"); |
| 412 | return ApplicationAreaIsNotInitialized; | 477 | return ApplicationAreaIsNotInitialized; |
| @@ -422,7 +487,7 @@ Result NfpDevice::GetApplicationArea(std::vector<u8>& data) const { | |||
| 422 | return ResultSuccess; | 487 | return ResultSuccess; |
| 423 | } | 488 | } |
| 424 | 489 | ||
| 425 | Result NfpDevice::SetApplicationArea(const std::vector<u8>& data) { | 490 | Result NfpDevice::SetApplicationArea(std::span<const u8> data) { |
| 426 | if (device_state != DeviceState::TagMounted) { | 491 | if (device_state != DeviceState::TagMounted) { |
| 427 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 492 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 428 | if (device_state == DeviceState::TagRemoved) { | 493 | if (device_state == DeviceState::TagRemoved) { |
| @@ -431,6 +496,16 @@ Result NfpDevice::SetApplicationArea(const std::vector<u8>& data) { | |||
| 431 | return WrongDeviceState; | 496 | return WrongDeviceState; |
| 432 | } | 497 | } |
| 433 | 498 | ||
| 499 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 500 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 501 | return WrongDeviceState; | ||
| 502 | } | ||
| 503 | |||
| 504 | if (!is_app_area_open) { | ||
| 505 | LOG_ERROR(Service_NFP, "Application area is not open"); | ||
| 506 | return WrongDeviceState; | ||
| 507 | } | ||
| 508 | |||
| 434 | if (tag_data.settings.settings.appdata_initialized.Value() == 0) { | 509 | if (tag_data.settings.settings.appdata_initialized.Value() == 0) { |
| 435 | LOG_ERROR(Service_NFP, "Application area is not initialized"); | 510 | LOG_ERROR(Service_NFP, "Application area is not initialized"); |
| 436 | return ApplicationAreaIsNotInitialized; | 511 | return ApplicationAreaIsNotInitialized; |
| @@ -442,8 +517,10 @@ Result NfpDevice::SetApplicationArea(const std::vector<u8>& data) { | |||
| 442 | } | 517 | } |
| 443 | 518 | ||
| 444 | Common::TinyMT rng{}; | 519 | Common::TinyMT rng{}; |
| 445 | rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(ApplicationArea)); | ||
| 446 | std::memcpy(tag_data.application_area.data(), data.data(), data.size()); | 520 | std::memcpy(tag_data.application_area.data(), data.data(), data.size()); |
| 521 | // HW seems to fill excess data with garbage | ||
| 522 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), | ||
| 523 | sizeof(ApplicationArea) - data.size()); | ||
| 447 | 524 | ||
| 448 | tag_data.applicaton_write_counter++; | 525 | tag_data.applicaton_write_counter++; |
| 449 | is_data_moddified = true; | 526 | is_data_moddified = true; |
| @@ -477,6 +554,11 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat | |||
| 477 | return WrongDeviceState; | 554 | return WrongDeviceState; |
| 478 | } | 555 | } |
| 479 | 556 | ||
| 557 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 558 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 559 | return WrongDeviceState; | ||
| 560 | } | ||
| 561 | |||
| 480 | if (data.size() > sizeof(ApplicationArea)) { | 562 | if (data.size() > sizeof(ApplicationArea)) { |
| 481 | LOG_ERROR(Service_NFP, "Wrong data size {}", data.size()); | 563 | LOG_ERROR(Service_NFP, "Wrong data size {}", data.size()); |
| 482 | return ResultUnknown; | 564 | return ResultUnknown; |
| @@ -508,6 +590,11 @@ Result NfpDevice::DeleteApplicationArea() { | |||
| 508 | return WrongDeviceState; | 590 | return WrongDeviceState; |
| 509 | } | 591 | } |
| 510 | 592 | ||
| 593 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | ||
| 594 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 595 | return WrongDeviceState; | ||
| 596 | } | ||
| 597 | |||
| 511 | Common::TinyMT rng{}; | 598 | Common::TinyMT rng{}; |
| 512 | rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(ApplicationArea)); | 599 | rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(ApplicationArea)); |
| 513 | rng.GenerateRandomBytes(&tag_data.title_id, sizeof(u64)); | 600 | rng.GenerateRandomBytes(&tag_data.title_id, sizeof(u64)); |
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index c020506a6..a5b72cf19 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h | |||
| @@ -40,7 +40,7 @@ public: | |||
| 40 | 40 | ||
| 41 | Result StartDetection(s32 protocol_); | 41 | Result StartDetection(s32 protocol_); |
| 42 | Result StopDetection(); | 42 | Result StopDetection(); |
| 43 | Result Mount(); | 43 | Result Mount(MountTarget mount_target); |
| 44 | Result Unmount(); | 44 | Result Unmount(); |
| 45 | Result Flush(); | 45 | Result Flush(); |
| 46 | 46 | ||
| @@ -55,7 +55,7 @@ public: | |||
| 55 | 55 | ||
| 56 | Result OpenApplicationArea(u32 access_id); | 56 | Result OpenApplicationArea(u32 access_id); |
| 57 | Result GetApplicationArea(std::vector<u8>& data) const; | 57 | Result GetApplicationArea(std::vector<u8>& data) const; |
| 58 | Result SetApplicationArea(const std::vector<u8>& data); | 58 | Result SetApplicationArea(std::span<const u8> data); |
| 59 | Result CreateApplicationArea(u32 access_id, std::span<const u8> data); | 59 | Result CreateApplicationArea(u32 access_id, std::span<const u8> data); |
| 60 | Result RecreateApplicationArea(u32 access_id, std::span<const u8> data); | 60 | Result RecreateApplicationArea(u32 access_id, std::span<const u8> data); |
| 61 | Result DeleteApplicationArea(); | 61 | Result DeleteApplicationArea(); |
| @@ -70,7 +70,7 @@ public: | |||
| 70 | 70 | ||
| 71 | private: | 71 | private: |
| 72 | void NpadUpdate(Core::HID::ControllerTriggerType type); | 72 | void NpadUpdate(Core::HID::ControllerTriggerType type); |
| 73 | bool LoadAmiibo(const std::vector<u8>& data); | 73 | bool LoadAmiibo(std::span<const u8> data); |
| 74 | void CloseAmiibo(); | 74 | void CloseAmiibo(); |
| 75 | 75 | ||
| 76 | AmiiboName GetAmiiboName(const AmiiboSettings& settings) const; | 76 | AmiiboName GetAmiiboName(const AmiiboSettings& settings) const; |
| @@ -88,8 +88,10 @@ private: | |||
| 88 | Kernel::KEvent* availability_change_event = nullptr; | 88 | Kernel::KEvent* availability_change_event = nullptr; |
| 89 | 89 | ||
| 90 | bool is_data_moddified{}; | 90 | bool is_data_moddified{}; |
| 91 | bool is_app_area_open{}; | ||
| 91 | s32 protocol{}; | 92 | s32 protocol{}; |
| 92 | s64 current_posix_time{}; | 93 | s64 current_posix_time{}; |
| 94 | MountTarget mount_target{MountTarget::None}; | ||
| 93 | DeviceState device_state{DeviceState::Unavailable}; | 95 | DeviceState device_state{DeviceState::Unavailable}; |
| 94 | 96 | ||
| 95 | NTAG215File tag_data{}; | 97 | NTAG215File tag_data{}; |
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index 448791846..dd4525b61 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h | |||
| @@ -75,6 +75,22 @@ enum class AmiiboSeries : u8 { | |||
| 75 | Diablo, | 75 | Diablo, |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | enum class TagType : u32 { | ||
| 79 | None, | ||
| 80 | Type1, // ISO14443A RW 96-2k bytes 106kbit/s | ||
| 81 | Type2, // ISO14443A RW/RO 540 bytes 106kbit/s | ||
| 82 | Type3, // Sony Felica RW/RO 2k bytes 212kbit/s | ||
| 83 | Type4, // ISO14443A RW/RO 4k-32k bytes 424kbit/s | ||
| 84 | Type5, // ISO15693 RW/RO 540 bytes 106kbit/s | ||
| 85 | }; | ||
| 86 | |||
| 87 | enum class TagProtocol : u32 { | ||
| 88 | None, | ||
| 89 | TypeA, // ISO14443A | ||
| 90 | TypeB, // ISO14443B | ||
| 91 | TypeF, // Sony Felica | ||
| 92 | }; | ||
| 93 | |||
| 78 | using UniqueSerialNumber = std::array<u8, 7>; | 94 | using UniqueSerialNumber = std::array<u8, 7>; |
| 79 | using LockBytes = std::array<u8, 2>; | 95 | using LockBytes = std::array<u8, 2>; |
| 80 | using HashData = std::array<u8, 0x20>; | 96 | using HashData = std::array<u8, 0x20>; |
| @@ -174,7 +190,7 @@ struct EncryptedAmiiboFile { | |||
| 174 | u16_be applicaton_write_counter; // Encrypted Counter | 190 | u16_be applicaton_write_counter; // Encrypted Counter |
| 175 | u32_be application_area_id; // Encrypted Game id | 191 | u32_be application_area_id; // Encrypted Game id |
| 176 | std::array<u8, 0x2> unknown; | 192 | std::array<u8, 0x2> unknown; |
| 177 | HashData hash; // Probably a SHA256-HMAC hash? | 193 | std::array<u32, 0x8> unknown2; |
| 178 | ApplicationArea application_area; // Encrypted Game data | 194 | ApplicationArea application_area; // Encrypted Game data |
| 179 | }; | 195 | }; |
| 180 | static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size"); | 196 | static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size"); |
| @@ -193,7 +209,7 @@ struct NTAG215File { | |||
| 193 | u16_be applicaton_write_counter; // Encrypted Counter | 209 | u16_be applicaton_write_counter; // Encrypted Counter |
| 194 | u32_be application_area_id; | 210 | u32_be application_area_id; |
| 195 | std::array<u8, 0x2> unknown; | 211 | std::array<u8, 0x2> unknown; |
| 196 | HashData hash; // Probably a SHA256-HMAC hash? | 212 | std::array<u32, 0x8> unknown2; |
| 197 | ApplicationArea application_area; // Encrypted Game data | 213 | ApplicationArea application_area; // Encrypted Game data |
| 198 | HashData hmac_tag; // Hash | 214 | HashData hmac_tag; // Hash |
| 199 | UniqueSerialNumber uid; // Unique serial number | 215 | UniqueSerialNumber uid; // Unique serial number |
| @@ -228,8 +244,8 @@ struct TagInfo { | |||
| 228 | INSERT_PADDING_BYTES(0x3); | 244 | INSERT_PADDING_BYTES(0x3); |
| 229 | u8 uuid_length; | 245 | u8 uuid_length; |
| 230 | INSERT_PADDING_BYTES(0x15); | 246 | INSERT_PADDING_BYTES(0x15); |
| 231 | s32 protocol; | 247 | TagProtocol protocol; |
| 232 | u32 tag_type; | 248 | TagType tag_type; |
| 233 | INSERT_PADDING_BYTES(0x30); | 249 | INSERT_PADDING_BYTES(0x30); |
| 234 | }; | 250 | }; |
| 235 | static_assert(sizeof(TagInfo) == 0x58, "TagInfo is an invalid size"); | 251 | static_assert(sizeof(TagInfo) == 0x58, "TagInfo is an invalid size"); |
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp index f8f1975db..c61df9401 100644 --- a/src/core/hle/service/nfp/nfp_user.cpp +++ b/src/core/hle/service/nfp/nfp_user.cpp | |||
| @@ -189,7 +189,7 @@ void IUser::Mount(Kernel::HLERequestContext& ctx) { | |||
| 189 | return; | 189 | return; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | const auto result = device.value()->Mount(); | 192 | const auto result = device.value()->Mount(mount_target); |
| 193 | IPC::ResponseBuilder rb{ctx, 2}; | 193 | IPC::ResponseBuilder rb{ctx, 2}; |
| 194 | rb.Push(result); | 194 | rb.Push(result); |
| 195 | } | 195 | } |