diff options
author | liamwhite <liamwhite@users.noreply.github.com> | 2023-06-23 15:27:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-23 15:27:00 +0200 |
commit | 87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77 (patch) | |
tree | 4239b5df2c866aa26e123719fe838bd6eb0e0394 /src/core | |
parent | Merge pull request #10884 from liamwhite/spaghetti-vfs (diff) | |
parent | input_common: Implement native mifare support (diff) | |
download | yuzu-87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77.tar yuzu-87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77.tar.gz yuzu-87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77.tar.bz2 yuzu-87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77.tar.lz yuzu-87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77.tar.xz yuzu-87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77.tar.zst yuzu-87b9b5d10fa4a30c8eb56f9de44ba0c24d57ae77.zip |
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/hid/emulated_controller.cpp | 82 | ||||
-rw-r--r-- | src/core/hid/emulated_controller.h | 28 | ||||
-rw-r--r-- | src/core/hid/input_converter.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_cabinet.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/nfc/common/device.cpp | 182 | ||||
-rw-r--r-- | src/core/hle/service/nfc/common/device.h | 10 | ||||
-rw-r--r-- | src/core/hle/service/nfc/common/device_manager.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/nfc/common/device_manager.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/nfc/mifare_types.h | 11 | ||||
-rw-r--r-- | src/core/hle/service/nfc/nfc_interface.cpp | 7 |
10 files changed, 209 insertions, 132 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 0a7777732..c937495f9 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -149,12 +149,16 @@ void EmulatedController::LoadDevices() { camera_params[0] = right_joycon; camera_params[0].Set("camera", true); - camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"}; - ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"}; - nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"}; nfc_params[1] = right_joycon; nfc_params[1].Set("nfc", true); + // Only map virtual devices to the first controller + if (npad_id_type == NpadIdType::Player1 || npad_id_type == NpadIdType::Handheld) { + camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"}; + ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"}; + nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"}; + } + output_params[LeftIndex] = left_joycon; output_params[RightIndex] = right_joycon; output_params[2] = camera_params[1]; @@ -1176,10 +1180,7 @@ void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) { return; } - controller.nfc_state = { - controller.nfc_values.state, - controller.nfc_values.data, - }; + controller.nfc_state = controller.nfc_values; } bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { @@ -1308,6 +1309,73 @@ bool EmulatedController::HasNfc() const { return is_connected && (has_virtual_nfc && is_virtual_nfc_supported); } +bool EmulatedController::AddNfcHandle() { + nfc_handles++; + return SetPollingMode(EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::NFC) == + Common::Input::DriverResult::Success; +} + +bool EmulatedController::RemoveNfcHandle() { + nfc_handles--; + if (nfc_handles <= 0) { + return SetPollingMode(EmulatedDeviceIndex::RightIndex, + Common::Input::PollingMode::Active) == + Common::Input::DriverResult::Success; + } + return true; +} + +bool EmulatedController::StartNfcPolling() { + auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; + auto& nfc_virtual_output_device = output_devices[3]; + + return nfc_output_device->StartNfcPolling() == Common::Input::NfcState::Success || + nfc_virtual_output_device->StartNfcPolling() == Common::Input::NfcState::Success; +} + +bool EmulatedController::StopNfcPolling() { + auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; + auto& nfc_virtual_output_device = output_devices[3]; + + return nfc_output_device->StopNfcPolling() == Common::Input::NfcState::Success || + nfc_virtual_output_device->StopNfcPolling() == Common::Input::NfcState::Success; +} + +bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) { + auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; + auto& nfc_virtual_output_device = output_devices[3]; + + if (nfc_output_device->ReadAmiiboData(data) == Common::Input::NfcState::Success) { + return true; + } + + return nfc_virtual_output_device->ReadAmiiboData(data) == Common::Input::NfcState::Success; +} + +bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& request, + Common::Input::MifareRequest& out_data) { + auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; + auto& nfc_virtual_output_device = output_devices[3]; + + if (nfc_output_device->ReadMifareData(request, out_data) == Common::Input::NfcState::Success) { + return true; + } + + return nfc_virtual_output_device->ReadMifareData(request, out_data) == + Common::Input::NfcState::Success; +} + +bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& request) { + auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; + auto& nfc_virtual_output_device = output_devices[3]; + + if (nfc_output_device->WriteMifareData(request) == Common::Input::NfcState::Success) { + return true; + } + + return nfc_virtual_output_device->WriteMifareData(request) == Common::Input::NfcState::Success; +} + bool EmulatedController::WriteNfc(const std::vector<u8>& data) { auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; auto& nfc_virtual_output_device = output_devices[3]; diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 09fe1a0ab..d511e5fac 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h @@ -97,10 +97,7 @@ struct RingSensorForce { f32 force; }; -struct NfcState { - Common::Input::NfcState state{}; - std::vector<u8> data{}; -}; +using NfcState = Common::Input::NfcStatus; struct ControllerMotion { Common::Vec3f accel{}; @@ -393,9 +390,31 @@ public: /// Returns true if the device has nfc support bool HasNfc() const; + /// Sets the joycon in nfc mode and increments the handle count + bool AddNfcHandle(); + + /// Decrements the handle count if zero sets the joycon in active mode + bool RemoveNfcHandle(); + + /// Start searching for nfc tags + bool StartNfcPolling(); + + /// Stop searching for nfc tags + bool StopNfcPolling(); + + /// Returns true if the nfc tag was readable + bool ReadAmiiboData(std::vector<u8>& data); + /// Returns true if the nfc tag was written bool WriteNfc(const std::vector<u8>& data); + /// Returns true if the nfc tag was readable + bool ReadMifareData(const Common::Input::MifareRequest& request, + Common::Input::MifareRequest& out_data); + + /// Returns true if the nfc tag was written + bool WriteMifareData(const Common::Input::MifareRequest& request); + /// Returns the led pattern corresponding to this emulated controller LedPattern GetLedPattern() const; @@ -532,6 +551,7 @@ private: bool system_buttons_enabled{true}; f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; u32 turbo_button_state{0}; + std::size_t nfc_handles{0}; // Temporary values to avoid doing changes while the controller is in configuring mode NpadStyleIndex tmp_npad_type{NpadStyleIndex::None}; diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp index 4ccb1c596..a05716fd8 100644 --- a/src/core/hid/input_converter.cpp +++ b/src/core/hid/input_converter.cpp @@ -299,11 +299,7 @@ Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& cal Common::Input::NfcStatus nfc{}; switch (callback.type) { case Common::Input::InputType::Nfc: - nfc = { - .state = callback.nfc_status, - .data = callback.raw_data, - }; - break; + return callback.nfc_status; default: LOG_ERROR(Input, "Conversion from type {} to NFC not implemented", callback.type); break; diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 8b754e9d4..19ed184e8 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -141,7 +141,7 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) applet_output.device_handle = applet_input_common.device_handle; applet_output.result = CabinetResult::Cancel; const auto reg_result = nfp_device->GetRegisterInfo(applet_output.register_info); - const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info, false); + const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info); nfp_device->Finalize(); if (reg_result.IsSuccess()) { diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index f4b180b06..5bf289818 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -93,7 +93,8 @@ void NfcDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { const auto nfc_status = npad_device->GetNfc(); switch (nfc_status.state) { case Common::Input::NfcState::NewAmiibo: - LoadNfcTag(nfc_status.data); + LoadNfcTag(nfc_status.protocol, nfc_status.tag_type, nfc_status.uuid_length, + nfc_status.uuid); break; case Common::Input::NfcState::AmiiboRemoved: if (device_state == DeviceState::Initialized || device_state == DeviceState::TagRemoved) { @@ -108,28 +109,46 @@ void NfcDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { } } -bool NfcDevice::LoadNfcTag(std::span<const u8> data) { +bool NfcDevice::LoadNfcTag(u8 protocol, u8 tag_type, u8 uuid_length, UniqueSerialNumber uuid) { if (device_state != DeviceState::SearchingForTag) { LOG_ERROR(Service_NFC, "Game is not looking for nfc tag, current state {}", device_state); return false; } + if ((protocol & static_cast<u8>(allowed_protocols)) == 0) { + LOG_ERROR(Service_NFC, "Protocol not supported {}", protocol); + return false; + } + + real_tag_info = { + .uuid = uuid, + .uuid_length = uuid_length, + .protocol = static_cast<NfcProtocol>(protocol), + .tag_type = static_cast<TagType>(tag_type), + }; + + device_state = DeviceState::TagFound; + deactivate_event->GetReadableEvent().Clear(); + activate_event->Signal(); + return true; +} + +bool NfcDevice::LoadAmiiboData() { + std::vector<u8> data{}; + + if (!npad_device->ReadAmiiboData(data)) { + return false; + } + if (data.size() < sizeof(NFP::EncryptedNTAG215File)) { LOG_ERROR(Service_NFC, "Not an amiibo, size={}", data.size()); return false; } - mifare_data.resize(data.size()); - memcpy(mifare_data.data(), data.data(), data.size()); - memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data); is_write_protected = false; - device_state = DeviceState::TagFound; - deactivate_event->GetReadableEvent().Clear(); - activate_event->Signal(); - // Fallback for plain amiibos if (is_plain_amiibo) { LOG_INFO(Service_NFP, "Using plain amiibo"); @@ -147,6 +166,7 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) { return true; } + LOG_INFO(Service_NFP, "Using encrypted amiibo"); tag_data = {}; memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); return true; @@ -162,7 +182,6 @@ void NfcDevice::CloseNfcTag() { device_state = DeviceState::TagRemoved; encrypted_tag_data = {}; tag_data = {}; - mifare_data = {}; activate_event->GetReadableEvent().Clear(); deactivate_event->Signal(); } @@ -179,8 +198,12 @@ void NfcDevice::Initialize() { device_state = npad_device->HasNfc() ? DeviceState::Initialized : DeviceState::Unavailable; encrypted_tag_data = {}; tag_data = {}; - mifare_data = {}; - is_initalized = true; + + if (device_state != DeviceState::Initialized) { + return; + } + + is_initalized = npad_device->AddNfcHandle(); } void NfcDevice::Finalize() { @@ -190,6 +213,11 @@ void NfcDevice::Finalize() { if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { StopDetection(); } + + if (device_state != DeviceState::Unavailable) { + npad_device->RemoveNfcHandle(); + } + device_state = DeviceState::Unavailable; is_initalized = false; } @@ -200,10 +228,8 @@ Result NfcDevice::StartDetection(NfcProtocol allowed_protocol) { return ResultWrongDeviceState; } - if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, - Common::Input::PollingMode::NFC) != - Common::Input::DriverResult::Success) { - LOG_ERROR(Service_NFC, "Nfc not supported"); + if (!npad_device->StartNfcPolling()) { + LOG_ERROR(Service_NFC, "Nfc polling not supported"); return ResultNfcDisabled; } @@ -213,9 +239,6 @@ Result NfcDevice::StartDetection(NfcProtocol allowed_protocol) { } Result NfcDevice::StopDetection() { - npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, - Common::Input::PollingMode::Active); - if (device_state == DeviceState::Initialized) { return ResultSuccess; } @@ -225,6 +248,7 @@ Result NfcDevice::StopDetection() { } if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { + npad_device->StopNfcPolling(); device_state = DeviceState::Initialized; return ResultSuccess; } @@ -233,7 +257,7 @@ Result NfcDevice::StopDetection() { return ResultWrongDeviceState; } -Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { +Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info) const { if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) { LOG_ERROR(Service_NFC, "Wrong device state {}", device_state); if (device_state == DeviceState::TagRemoved) { @@ -242,41 +266,15 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { return ResultWrongDeviceState; } - UniqueSerialNumber uuid{}; - u8 uuid_length{}; - NfcProtocol protocol{NfcProtocol::TypeA}; - TagType tag_type{TagType::Type2}; - - if (is_mifare) { - tag_type = TagType::Mifare; - uuid_length = sizeof(NFP::NtagTagUuid); - memcpy(uuid.data(), mifare_data.data(), uuid_length); - } else { - tag_type = TagType::Type2; - uuid_length = sizeof(NFP::NtagTagUuid); - NFP::NtagTagUuid nUuid{ - .part1 = encrypted_tag_data.uuid.part1, - .part2 = encrypted_tag_data.uuid.part2, - .nintendo_id = encrypted_tag_data.uuid.nintendo_id, - }; - memcpy(uuid.data(), &nUuid, uuid_length); + tag_info = real_tag_info; - // Generate random UUID to bypass amiibo load limits - if (Settings::values.random_amiibo_id) { - Common::TinyMT rng{}; - rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); - rng.GenerateRandomBytes(uuid.data(), uuid_length); - } + // Generate random UUID to bypass amiibo load limits + if (real_tag_info.tag_type == TagType::Type2 && Settings::values.random_amiibo_id) { + Common::TinyMT rng{}; + rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); + rng.GenerateRandomBytes(tag_info.uuid.data(), tag_info.uuid_length); } - // Protocol and tag type may change here - tag_info = { - .uuid = uuid, - .uuid_length = uuid_length, - .protocol = protocol, - .tag_type = tag_type, - }; - return ResultSuccess; } @@ -293,7 +291,7 @@ Result NfcDevice::ReadMifare(std::span<const MifareReadBlockParameter> parameter Result result = ResultSuccess; TagInfo tag_info{}; - result = GetTagInfo(tag_info, true); + result = GetTagInfo(tag_info); if (result.IsError()) { return result; @@ -307,6 +305,8 @@ Result NfcDevice::ReadMifare(std::span<const MifareReadBlockParameter> parameter return ResultInvalidArgument; } + Common::Input::MifareRequest request{}; + Common::Input::MifareRequest out_data{}; const auto unknown = parameters[0].sector_key.unknown; for (std::size_t i = 0; i < parameters.size(); i++) { if (unknown != parameters[i].sector_key.unknown) { @@ -315,25 +315,29 @@ Result NfcDevice::ReadMifare(std::span<const MifareReadBlockParameter> parameter } for (std::size_t i = 0; i < parameters.size(); i++) { - result = ReadMifare(parameters[i], read_block_data[i]); - if (result.IsError()) { - break; + if (parameters[i].sector_key.command == MifareCmd::None) { + continue; } + request.data[i].command = static_cast<u8>(parameters[i].sector_key.command); + request.data[i].sector = parameters[i].sector_number; + memcpy(request.data[i].key.data(), parameters[i].sector_key.sector_key.data(), + sizeof(KeyData)); } - return result; -} - -Result NfcDevice::ReadMifare(const MifareReadBlockParameter& parameter, - MifareReadBlockData& read_block_data) const { - const std::size_t sector_index = parameter.sector_number * sizeof(DataBlock); - read_block_data.sector_number = parameter.sector_number; - if (mifare_data.size() < sector_index + sizeof(DataBlock)) { + if (!npad_device->ReadMifareData(request, out_data)) { return ResultMifareError288; } - // TODO: Use parameter.sector_key to read encrypted data - memcpy(read_block_data.data.data(), mifare_data.data() + sector_index, sizeof(DataBlock)); + for (std::size_t i = 0; i < read_block_data.size(); i++) { + if (static_cast<MifareCmd>(out_data.data[i].command) == MifareCmd::None) { + continue; + } + + read_block_data[i] = { + .data = out_data.data[i].data, + .sector_number = out_data.data[i].sector, + }; + } return ResultSuccess; } @@ -342,7 +346,7 @@ Result NfcDevice::WriteMifare(std::span<const MifareWriteBlockParameter> paramet Result result = ResultSuccess; TagInfo tag_info{}; - result = GetTagInfo(tag_info, true); + result = GetTagInfo(tag_info); if (result.IsError()) { return result; @@ -363,42 +367,25 @@ Result NfcDevice::WriteMifare(std::span<const MifareWriteBlockParameter> paramet } } + Common::Input::MifareRequest request{}; for (std::size_t i = 0; i < parameters.size(); i++) { - result = WriteMifare(parameters[i]); - if (result.IsError()) { - break; + if (parameters[i].sector_key.command == MifareCmd::None) { + continue; } + request.data[i].command = static_cast<u8>(parameters[i].sector_key.command); + request.data[i].sector = parameters[i].sector_number; + memcpy(request.data[i].key.data(), parameters[i].sector_key.sector_key.data(), + sizeof(KeyData)); + memcpy(request.data[i].data.data(), parameters[i].data.data(), sizeof(KeyData)); } - if (!npad_device->WriteNfc(mifare_data)) { - LOG_ERROR(Service_NFP, "Error writing to file"); + if (!npad_device->WriteMifareData(request)) { return ResultMifareError288; } return result; } -Result NfcDevice::WriteMifare(const MifareWriteBlockParameter& parameter) { - const std::size_t sector_index = parameter.sector_number * sizeof(DataBlock); - - if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) { - LOG_ERROR(Service_NFC, "Wrong device state {}", device_state); - if (device_state == DeviceState::TagRemoved) { - return ResultTagRemoved; - } - return ResultWrongDeviceState; - } - - if (mifare_data.size() < sector_index + sizeof(DataBlock)) { - return ResultMifareError288; - } - - // TODO: Use parameter.sector_key to encrypt the data - memcpy(mifare_data.data() + sector_index, parameter.data.data(), sizeof(DataBlock)); - - return ResultSuccess; -} - Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, std::span<const u8> command_data, std::span<u8> out_data) { @@ -412,6 +399,11 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target return ResultWrongDeviceState; } + if (!LoadAmiiboData()) { + LOG_ERROR(Service_NFP, "Not an amiibo"); + return ResultInvalidTagType; + } + if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { LOG_ERROR(Service_NFP, "Not an amiibo"); return ResultInvalidTagType; @@ -562,7 +554,7 @@ Result NfcDevice::Restore() { NFC::TagInfo tag_info{}; std::array<u8, sizeof(NFP::EncryptedNTAG215File)> data{}; - Result result = GetTagInfo(tag_info, false); + Result result = GetTagInfo(tag_info); if (result.IsError()) { return result; @@ -635,7 +627,7 @@ Result NfcDevice::GetCommonInfo(NFP::CommonInfo& common_info) const { // TODO: Validate this data common_info = { .last_write_date = settings.write_date.GetWriteDate(), - .write_counter = tag_data.write_counter, + .write_counter = tag_data.application_write_counter, .version = tag_data.amiibo_version, .application_area_size = sizeof(NFP::ApplicationArea), }; diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h index 7560210d6..0ed1ff34c 100644 --- a/src/core/hle/service/nfc/common/device.h +++ b/src/core/hle/service/nfc/common/device.h @@ -42,15 +42,12 @@ public: Result StartDetection(NfcProtocol allowed_protocol); Result StopDetection(); - Result GetTagInfo(TagInfo& tag_info, bool is_mifare) const; + Result GetTagInfo(TagInfo& tag_info) const; Result ReadMifare(std::span<const MifareReadBlockParameter> parameters, std::span<MifareReadBlockData> read_block_data) const; - Result ReadMifare(const MifareReadBlockParameter& parameter, - MifareReadBlockData& read_block_data) const; Result WriteMifare(std::span<const MifareWriteBlockParameter> parameters); - Result WriteMifare(const MifareWriteBlockParameter& parameter); Result SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, std::span<const u8> command_data, std::span<u8> out_data); @@ -105,7 +102,8 @@ public: private: void NpadUpdate(Core::HID::ControllerTriggerType type); - bool LoadNfcTag(std::span<const u8> data); + bool LoadNfcTag(u8 protocol, u8 tag_type, u8 uuid_length, UniqueSerialNumber uuid); + bool LoadAmiiboData(); void CloseNfcTag(); NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; @@ -140,8 +138,8 @@ private: bool is_write_protected{}; NFP::MountTarget mount_target{NFP::MountTarget::None}; + TagInfo real_tag_info{}; NFP::NTAG215File tag_data{}; - std::vector<u8> mifare_data{}; NFP::EncryptedNTAG215File encrypted_tag_data{}; }; diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index b0456508e..562f3a28e 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -29,6 +29,9 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex } DeviceManager ::~DeviceManager() { + if (is_initialized) { + Finalize(); + } service_context.CloseEvent(availability_change_event); } @@ -125,14 +128,14 @@ Result DeviceManager::StopDetection(u64 device_handle) { return result; } -Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info, bool is_mifare) const { +Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; auto result = GetDeviceHandle(device_handle, device); if (result.IsSuccess()) { - result = device->GetTagInfo(tag_info, is_mifare); + result = device->GetTagInfo(tag_info); result = VerifyDeviceResult(device, result); } @@ -546,7 +549,7 @@ Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) cons NFC::TagInfo tag_info{}; if (result.IsSuccess()) { - result = device->GetTagInfo(tag_info, false); + result = device->GetTagInfo(tag_info); } if (result.IsSuccess()) { @@ -565,7 +568,7 @@ Result DeviceManager::WriteBackupData(u64 device_handle, std::span<const u8> dat NFC::TagInfo tag_info{}; if (result.IsSuccess()) { - result = device->GetTagInfo(tag_info, false); + result = device->GetTagInfo(tag_info); } if (result.IsSuccess()) { diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h index 2971e280f..c61ba0cf3 100644 --- a/src/core/hle/service/nfc/common/device_manager.h +++ b/src/core/hle/service/nfc/common/device_manager.h @@ -33,7 +33,7 @@ public: Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const; Result StartDetection(u64 device_handle, NfcProtocol tag_protocol); Result StopDetection(u64 device_handle); - Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info, bool is_mifare) const; + Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const; Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const; Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const; Result ReadMifare(u64 device_handle, diff --git a/src/core/hle/service/nfc/mifare_types.h b/src/core/hle/service/nfc/mifare_types.h index 75b59f021..467937399 100644 --- a/src/core/hle/service/nfc/mifare_types.h +++ b/src/core/hle/service/nfc/mifare_types.h @@ -11,9 +11,10 @@ namespace Service::NFC { enum class MifareCmd : u8 { + None = 0x00, + Read = 0x30, AuthA = 0x60, AuthB = 0x61, - Read = 0x30, Write = 0xA0, Transfer = 0xB0, Decrement = 0xC0, @@ -35,17 +36,17 @@ static_assert(sizeof(SectorKey) == 0x10, "SectorKey is an invalid size"); // This is nn::nfc::MifareReadBlockParameter struct MifareReadBlockParameter { - u8 sector_number; + u8 sector_number{}; INSERT_PADDING_BYTES(0x7); - SectorKey sector_key; + SectorKey sector_key{}; }; static_assert(sizeof(MifareReadBlockParameter) == 0x18, "MifareReadBlockParameter is an invalid size"); // This is nn::nfc::MifareReadBlockData struct MifareReadBlockData { - DataBlock data; - u8 sector_number; + DataBlock data{}; + u8 sector_number{}; INSERT_PADDING_BYTES(0x7); }; static_assert(sizeof(MifareReadBlockData) == 0x18, "MifareReadBlockData is an invalid size"); diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp index 130fb7f78..e7ca7582e 100644 --- a/src/core/hle/service/nfc/nfc_interface.cpp +++ b/src/core/hle/service/nfc/nfc_interface.cpp @@ -174,8 +174,7 @@ void NfcInterface::GetTagInfo(HLERequestContext& ctx) { LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); TagInfo tag_info{}; - auto result = - GetManager()->GetTagInfo(device_handle, tag_info, backend_type == BackendType::Mifare); + auto result = GetManager()->GetTagInfo(device_handle, tag_info); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { @@ -216,8 +215,8 @@ void NfcInterface::ReadMifare(HLERequestContext& ctx) { memcpy(read_commands.data(), buffer.data(), number_of_commands * sizeof(MifareReadBlockParameter)); - LOG_INFO(Service_NFC, "(STUBBED) called, device_handle={}, read_commands_size={}", - device_handle, number_of_commands); + LOG_INFO(Service_NFC, "called, device_handle={}, read_commands_size={}", device_handle, + number_of_commands); std::vector<MifareReadBlockData> out_data(number_of_commands); auto result = GetManager()->ReadMifare(device_handle, read_commands, out_data); |