diff --git a/include/services/nfc.hpp b/include/services/nfc.hpp index 59e8f362..dabee9a9 100644 --- a/include/services/nfc.hpp +++ b/include/services/nfc.hpp @@ -14,10 +14,19 @@ class NFCService { Kernel& kernel; MAKE_LOG_FUNCTION(log, nfcLogger) + enum class Old3DSAdapterStatus : s32 { + AttemptingToInitialize = 1, + InitializationComplete = 2, + // Other values are errors according to 3DBrew, set the not initialized error to -1 until we find out what it should be + NotInitialized = -1, + }; + // Kernel events signaled when an NFC tag goes in and out of range respectively std::optional tagInRangeEvent, tagOutOfRangeEvent; + Old3DSAdapterStatus adapterStatus; // Service commands + void communicationGetStatus(u32 messagePointer); void initialize(u32 messagePointer); void getTagInRangeEvent(u32 messagePointer); void getTagOutOfRangeEvent(u32 messagePointer); diff --git a/src/core/services/nfc.cpp b/src/core/services/nfc.cpp index c6ed363d..31f0ff7f 100644 --- a/src/core/services/nfc.cpp +++ b/src/core/services/nfc.cpp @@ -6,18 +6,22 @@ namespace NFCCommands { enum : u32 { Initialize = 0x00010040, GetTagInRangeEvent = 0x000B0000, - GetTagOutOfRangeEvent = 0x000C0000 + GetTagOutOfRangeEvent = 0x000C0000, + CommunicationGetStatus = 0x000F0000, }; } void NFCService::reset() { tagInRangeEvent = std::nullopt; tagOutOfRangeEvent = std::nullopt; + + adapterStatus = Old3DSAdapterStatus::NotInitialized; } void NFCService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { + case NFCCommands::CommunicationGetStatus: communicationGetStatus(messagePointer); break; case NFCCommands::Initialize: initialize(messagePointer); break; case NFCCommands::GetTagInRangeEvent: getTagInRangeEvent(messagePointer); break; case NFCCommands::GetTagOutOfRangeEvent: getTagOutOfRangeEvent(messagePointer); break; @@ -29,6 +33,7 @@ void NFCService::initialize(u32 messagePointer) { const u8 type = mem.read8(messagePointer + 4); log("NFC::Initialize (type = %d)\n", type); + adapterStatus = Old3DSAdapterStatus::InitializationComplete; // TODO: This should error if already initialized. Also sanitize type. mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0)); mem.write32(messagePointer + 4, Result::Success); @@ -67,4 +72,16 @@ void NFCService::getTagOutOfRangeEvent(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); // TODO: Translation descriptor here mem.write32(messagePointer + 12, tagOutOfRangeEvent.value()); +} + +void NFCService::communicationGetStatus(u32 messagePointer) { + log("NFC::CommunicationGetStatus"); + + if (adapterStatus != Old3DSAdapterStatus::InitializationComplete) { + Helpers::warn("NFC::CommunicationGetStatus: Old 3DS NFC Adapter not initialized\n"); + } + + mem.write32(messagePointer, IPC::responseHeader(0xF, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write8(messagePointer + 8, static_cast(adapterStatus)); } \ No newline at end of file