mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	service: nfc: Keep tag alive while it's being used (#6687)
This commit is contained in:
		
							parent
							
								
									d702915624
								
							
						
					
					
						commit
						8eebb83c2c
					
				
					 3 changed files with 45 additions and 10 deletions
				
			
		|  | @ -175,6 +175,8 @@ void Module::Interface::Mount(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     ResultCode result = RESULT_SUCCESS; |     ResultCode result = RESULT_SUCCESS; | ||||||
|     switch (nfc->nfc_mode) { |     switch (nfc->nfc_mode) { | ||||||
|     case CommunicationMode::Ntag: |     case CommunicationMode::Ntag: | ||||||
|  | @ -310,6 +312,8 @@ void Module::Interface::GetTagInfo2(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode == CommunicationMode::TrainTag) { |     if (nfc->nfc_mode == CommunicationMode::TrainTag) { | ||||||
|         LOG_ERROR(Service_NFC, "CommunicationMode  {} not implemented", nfc->nfc_mode); |         LOG_ERROR(Service_NFC, "CommunicationMode  {} not implemented", nfc->nfc_mode); | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(26, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(26, 0); | ||||||
|  | @ -330,6 +334,8 @@ void Module::Interface::GetTagInfo(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode == CommunicationMode::TrainTag) { |     if (nfc->nfc_mode == CommunicationMode::TrainTag) { | ||||||
|         LOG_ERROR(Service_NFC, "CommunicationMode  {} not implemented", nfc->nfc_mode); |         LOG_ERROR(Service_NFC, "CommunicationMode  {} not implemented", nfc->nfc_mode); | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(12, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(12, 0); | ||||||
|  | @ -360,6 +366,8 @@ void Module::Interface::OpenApplicationArea(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called, access_id={}", access_id); |     LOG_INFO(Service_NFC, "called, access_id={}", access_id); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode != CommunicationMode::Amiibo) { |     if (nfc->nfc_mode != CommunicationMode::Amiibo) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|         rb.Push(ResultInvalidOperation); |         rb.Push(ResultInvalidOperation); | ||||||
|  | @ -397,6 +405,8 @@ void Module::Interface::ReadApplicationArea(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode != CommunicationMode::Amiibo) { |     if (nfc->nfc_mode != CommunicationMode::Amiibo) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|         rb.Push(ResultInvalidOperation); |         rb.Push(ResultInvalidOperation); | ||||||
|  | @ -436,6 +446,8 @@ void Module::Interface::GetNfpRegisterInfo(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode != CommunicationMode::Amiibo) { |     if (nfc->nfc_mode != CommunicationMode::Amiibo) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|         rb.Push(ResultInvalidOperation); |         rb.Push(ResultInvalidOperation); | ||||||
|  | @ -455,6 +467,8 @@ void Module::Interface::GetNfpCommonInfo(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode != CommunicationMode::Amiibo) { |     if (nfc->nfc_mode != CommunicationMode::Amiibo) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|         rb.Push(ResultInvalidOperation); |         rb.Push(ResultInvalidOperation); | ||||||
|  | @ -515,6 +529,8 @@ void Module::Interface::GetIdentificationBlock(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode != CommunicationMode::Amiibo) { |     if (nfc->nfc_mode != CommunicationMode::Amiibo) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|         rb.Push(ResultInvalidOperation); |         rb.Push(ResultInvalidOperation); | ||||||
|  | @ -548,6 +564,8 @@ void Module::Interface::GetAdminInfo(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Service_NFC, "called"); |     LOG_INFO(Service_NFC, "called"); | ||||||
| 
 | 
 | ||||||
|  |     nfc->device->RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     if (nfc->nfc_mode != CommunicationMode::Amiibo) { |     if (nfc->nfc_mode != CommunicationMode::Amiibo) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|         rb.Push(ResultInvalidOperation); |         rb.Push(ResultInvalidOperation); | ||||||
|  |  | ||||||
|  | @ -38,10 +38,7 @@ void NfcDevice::serialize(Archive& ar, const unsigned int) { | ||||||
| } | } | ||||||
| SERIALIZE_IMPL(NfcDevice) | SERIALIZE_IMPL(NfcDevice) | ||||||
| 
 | 
 | ||||||
| /// The interval at which the amiibo will be removed automatically 1.5s
 | NfcDevice::NfcDevice(Core::System& system_) : system{system_} { | ||||||
| static constexpr u64 amiibo_removal_interval_us = 268 * 1000 * 1000; |  | ||||||
| 
 |  | ||||||
| NfcDevice::NfcDevice(Core::System& system) { |  | ||||||
|     tag_in_range_event = |     tag_in_range_event = | ||||||
|         system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NFC::tag_in_range_event"); |         system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NFC::tag_in_range_event"); | ||||||
|     tag_out_of_range_event = |     tag_out_of_range_event = | ||||||
|  | @ -88,8 +85,7 @@ bool NfcDevice::LoadAmiibo(std::string filename) { | ||||||
|     tag_out_of_range_event->Clear(); |     tag_out_of_range_event->Clear(); | ||||||
|     tag_in_range_event->Signal(); |     tag_in_range_event->Signal(); | ||||||
| 
 | 
 | ||||||
|     Core::System::GetInstance().CoreTiming().ScheduleEvent(amiibo_removal_interval_us, |     RescheduleTagRemoveEvent(); | ||||||
|                                                            remove_amiibo_event); |  | ||||||
| 
 | 
 | ||||||
|     // Fallback for plain amiibos
 |     // Fallback for plain amiibos
 | ||||||
|     if (is_plain_amiibo) { |     if (is_plain_amiibo) { | ||||||
|  | @ -270,6 +266,9 @@ ResultCode NfcDevice::Flush() { | ||||||
|         return connection_result; |         return connection_result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Ensure the tag will not be removed in the middle of a write
 | ||||||
|  |     RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
|     auto& settings = tag.file.settings; |     auto& settings = tag.file.settings; | ||||||
| 
 | 
 | ||||||
|     const auto& current_date = GetAmiiboDate(); |     const auto& current_date = GetAmiiboDate(); | ||||||
|  | @ -888,8 +887,7 @@ ResultCode NfcDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     u64 application_id{}; |     u64 application_id{}; | ||||||
|     if (Core::System::GetInstance().GetAppLoader().ReadProgramId(application_id) == |     if (system.GetAppLoader().ReadProgramId(application_id) == Loader::ResultStatus::Success) { | ||||||
|         Loader::ResultStatus::Success) { |  | ||||||
|         tag.file.application_id_byte = |         tag.file.application_id_byte = | ||||||
|             static_cast<u8>(application_id >> application_id_version_offset & 0xf); |             static_cast<u8>(application_id >> application_id_version_offset & 0xf); | ||||||
|         tag.file.application_id = |         tag.file.application_id = | ||||||
|  | @ -1008,7 +1006,7 @@ void NfcDevice::SetAmiiboName(AmiiboSettings& settings, const AmiiboName& amiibo | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| time_t NfcDevice::GetCurrentTime() const { | time_t NfcDevice::GetCurrentTime() const { | ||||||
|     auto& share_page = Core::System::GetInstance().Kernel().GetSharedPageHandler(); |     auto& share_page = system.Kernel().GetSharedPageHandler(); | ||||||
|     const auto console_time = share_page.GetSharedPage().date_time_1.date_time / 1000; |     const auto console_time = share_page.GetSharedPage().date_time_1.date_time / 1000; | ||||||
| 
 | 
 | ||||||
|     // 3DS console time uses Jan 1 1900 as internal epoch,
 |     // 3DS console time uses Jan 1 1900 as internal epoch,
 | ||||||
|  | @ -1111,4 +1109,18 @@ void NfcDevice::BuildAmiiboWithoutKeys() { | ||||||
|     settings.settings.appdata_initialized.Assign(0); |     settings.settings.appdata_initialized.Assign(0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void NfcDevice::RescheduleTagRemoveEvent() { | ||||||
|  |     /// The interval at which the amiibo will be removed automatically 1.5s
 | ||||||
|  |     static constexpr u64 amiibo_removal_interval = nsToCycles(1500 * 1000 * 1000); | ||||||
|  | 
 | ||||||
|  |     system.CoreTiming().UnscheduleEvent(remove_amiibo_event, 0); | ||||||
|  | 
 | ||||||
|  |     if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted && | ||||||
|  |         device_state != DeviceState::TagPartiallyMounted) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     system.CoreTiming().ScheduleEvent(amiibo_removal_interval, remove_amiibo_event); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace Service::NFC
 | } // namespace Service::NFC
 | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ class KReadableEvent; | ||||||
| namespace Service::NFC { | namespace Service::NFC { | ||||||
| class NfcDevice { | class NfcDevice { | ||||||
| public: | public: | ||||||
|     NfcDevice(Core::System& system); |     NfcDevice(Core::System& system_); | ||||||
|     ~NfcDevice(); |     ~NfcDevice(); | ||||||
| 
 | 
 | ||||||
|     bool LoadAmiibo(std::string filename); |     bool LoadAmiibo(std::string filename); | ||||||
|  | @ -71,6 +71,10 @@ public: | ||||||
|     std::shared_ptr<Kernel::Event> GetActivateEvent() const; |     std::shared_ptr<Kernel::Event> GetActivateEvent() const; | ||||||
|     std::shared_ptr<Kernel::Event> GetDeactivateEvent() const; |     std::shared_ptr<Kernel::Event> GetDeactivateEvent() const; | ||||||
| 
 | 
 | ||||||
|  |     /// Automatically removes the nfc tag after x ammount of time.
 | ||||||
|  |     /// If called multiple times the counter will be restarted.
 | ||||||
|  |     void RescheduleTagRemoveEvent(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     time_t GetCurrentTime() const; |     time_t GetCurrentTime() const; | ||||||
|     void SetAmiiboName(AmiiboSettings& settings, const AmiiboName& amiibo_name); |     void SetAmiiboName(AmiiboSettings& settings, const AmiiboName& amiibo_name); | ||||||
|  | @ -100,6 +104,7 @@ private: | ||||||
| 
 | 
 | ||||||
|     SerializableAmiiboFile tag{}; |     SerializableAmiiboFile tag{}; | ||||||
|     SerializableEncryptedAmiiboFile encrypted_tag{}; |     SerializableEncryptedAmiiboFile encrypted_tag{}; | ||||||
|  |     Core::System& system; | ||||||
| 
 | 
 | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int); |     void serialize(Archive& ar, const unsigned int); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue