mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #4893 from wwylele/nfc-state
NFC: extract frontend-facing tag state
This commit is contained in:
		
						commit
						7bfd829c77
					
				
					 2 changed files with 36 additions and 16 deletions
				
			
		|  | @ -53,7 +53,7 @@ void Module::Interface::Initialize(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     if (nfc->nfc_tag_state != TagState::NotInitialized) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|         return; | ||||
|  | @ -99,13 +99,14 @@ void Module::Interface::StartTagScanning(Kernel::HLERequestContext& ctx) { | |||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     if (nfc->nfc_tag_state != TagState::NotScanning && | ||||
|         nfc->nfc_tag_state != TagState::TagOutOfRange) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     nfc->nfc_tag_state = TagState::Scanning; | ||||
|     nfc->SyncTagState(); | ||||
| 
 | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     LOG_WARNING(Service_NFC, "(STUBBED) called, in_val={:04x}", in_val); | ||||
|  | @ -116,7 +117,7 @@ void Module::Interface::GetTagInfo(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     if (nfc->nfc_tag_state != TagState::TagInRange && | ||||
|         nfc->nfc_tag_state != TagState::TagDataLoaded && nfc->nfc_tag_state != TagState::Unknown6) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|  | @ -163,7 +164,7 @@ void Module::Interface::StopTagScanning(Kernel::HLERequestContext& ctx) { | |||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     if (nfc->nfc_tag_state == TagState::NotInitialized || | ||||
|         nfc->nfc_tag_state == TagState::NotScanning) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|         return; | ||||
|  | @ -192,13 +193,14 @@ void Module::Interface::ResetTagScanState(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     if (nfc->nfc_tag_state != TagState::TagDataLoaded && nfc->nfc_tag_state != TagState::Unknown6) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     nfc->nfc_tag_state = TagState::TagInRange; | ||||
|     nfc->SyncTagState(); | ||||
| 
 | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     LOG_DEBUG(Service_NFC, "called"); | ||||
|  | @ -208,7 +210,7 @@ void Module::Interface::GetTagInRangeEvent(Kernel::HLERequestContext& ctx) { | |||
|     IPC::RequestParser rp(ctx, 0x0B, 0, 0); | ||||
| 
 | ||||
|     if (nfc->nfc_tag_state != TagState::NotScanning) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|  | @ -225,7 +227,7 @@ void Module::Interface::GetTagOutOfRangeEvent(Kernel::HLERequestContext& ctx) { | |||
|     IPC::RequestParser rp(ctx, 0x0C, 0, 0); | ||||
| 
 | ||||
|     if (nfc->nfc_tag_state != TagState::NotScanning) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|  | @ -243,7 +245,7 @@ void Module::Interface::GetTagState(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     rb.PushEnum(nfc->nfc_tag_state.load()); | ||||
|     rb.PushEnum(nfc->nfc_tag_state); | ||||
|     LOG_DEBUG(Service_NFC, "called"); | ||||
| } | ||||
| 
 | ||||
|  | @ -261,7 +263,7 @@ void Module::Interface::Unknown0x1A(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     if (nfc->nfc_tag_state != TagState::TagInRange) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|         return; | ||||
|  | @ -277,7 +279,7 @@ void Module::Interface::GetIdentificationBlock(Kernel::HLERequestContext& ctx) { | |||
|     IPC::RequestParser rp(ctx, 0x1B, 0, 0); | ||||
| 
 | ||||
|     if (nfc->nfc_tag_state != TagState::TagDataLoaded && nfc->nfc_tag_state != TagState::Unknown6) { | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load())); | ||||
|         LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state)); | ||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|         rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC, | ||||
|                            ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||
|  | @ -304,15 +306,29 @@ std::shared_ptr<Module> Module::Interface::GetModule() const { | |||
| void Module::Interface::LoadAmiibo(const AmiiboData& amiibo_data) { | ||||
|     std::lock_guard lock(HLE::g_hle_lock); | ||||
|     nfc->amiibo_data = amiibo_data; | ||||
|     nfc->nfc_tag_state = Service::NFC::TagState::TagInRange; | ||||
|     nfc->tag_in_range_event->Signal(); | ||||
|     nfc->amiibo_in_range = true; | ||||
|     nfc->SyncTagState(); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::RemoveAmiibo() { | ||||
|     std::lock_guard lock(HLE::g_hle_lock); | ||||
|     nfc->nfc_tag_state = Service::NFC::TagState::TagOutOfRange; | ||||
|     nfc->tag_out_of_range_event->Signal(); | ||||
|     nfc->amiibo_data = {}; | ||||
|     nfc->amiibo_in_range = false; | ||||
|     nfc->SyncTagState(); | ||||
| } | ||||
| 
 | ||||
| void Module::SyncTagState() { | ||||
|     if (amiibo_in_range && | ||||
|         (nfc_tag_state == TagState::TagOutOfRange || nfc_tag_state == TagState::Scanning)) { | ||||
|         // TODO (wwylele): Should TagOutOfRange->TagInRange transition only happen on the same tag
 | ||||
|         // detected on Scanning->TagInRange?
 | ||||
|         nfc_tag_state = TagState::TagInRange; | ||||
|         tag_in_range_event->Signal(); | ||||
|     } else if (!amiibo_in_range && nfc_tag_state == TagState::TagInRange) { | ||||
|         nfc_tag_state = TagState::TagOutOfRange; | ||||
|         // TODO (wwylele): If a tag is removed during TagDataLoaded/Unknown6, should this event
 | ||||
|         // signals early?
 | ||||
|         tag_out_of_range_event->Signal(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Module::Interface::Interface(std::shared_ptr<Module> nfc, const char* name, u32 max_session) | ||||
|  |  | |||
|  | @ -231,12 +231,16 @@ public: | |||
|     }; | ||||
| 
 | ||||
| private: | ||||
|     // Sync nfc_tag_state with amiibo_in_range and signal events on state change.
 | ||||
|     void SyncTagState(); | ||||
| 
 | ||||
|     std::shared_ptr<Kernel::Event> tag_in_range_event; | ||||
|     std::shared_ptr<Kernel::Event> tag_out_of_range_event; | ||||
|     std::atomic<TagState> nfc_tag_state = TagState::NotInitialized; | ||||
|     TagState nfc_tag_state = TagState::NotInitialized; | ||||
|     CommunicationStatus nfc_status = CommunicationStatus::NfcInitialized; | ||||
| 
 | ||||
|     AmiiboData amiibo_data{}; | ||||
|     bool amiibo_in_range = false; | ||||
| }; | ||||
| 
 | ||||
| void InstallInterfaces(Core::System& system); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue