[NFC] Tag events

This commit is contained in:
wheremyfoodat 2023-04-24 21:58:35 +03:00
parent 3935820c05
commit 0add6b7d7a
3 changed files with 56 additions and 4 deletions

View file

@ -4,16 +4,25 @@
#include "logger.hpp"
#include "memory.hpp"
// You know the drill
class Kernel;
class NFCService {
Handle handle = KernelHandles::NFC;
Memory& mem;
Kernel& kernel;
MAKE_LOG_FUNCTION(log, nfcLogger)
// Kernel events signaled when an NFC tag goes in and out of range respectively
std::optional<Handle> tagInRangeEvent, tagOutOfRangeEvent;
// Service commands
void initialize(u32 messagePointer);
void getTagInRangeEvent(u32 messagePointer);
void getTagOutOfRangeEvent(u32 messagePointer);
public:
NFCService(Memory& mem) : mem(mem) {}
NFCService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {}
void reset();
void handleSyncRequest(u32 messagePointer);
};

View file

@ -1,9 +1,12 @@
#include "services/nfc.hpp"
#include "ipc.hpp"
#include "kernel.hpp"
namespace NFCCommands {
enum : u32 {
Initialize = 0x00010040
Initialize = 0x00010040,
GetTagInRangeEvent = 0x000B0000,
GetTagOutOfRangeEvent = 0x000C0000
};
}
@ -13,12 +16,17 @@ namespace Result {
};
}
void NFCService::reset() {}
void NFCService::reset() {
tagInRangeEvent = std::nullopt;
tagOutOfRangeEvent = std::nullopt;
}
void NFCService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer);
switch (command) {
case NFCCommands::Initialize: initialize(messagePointer); break;
case NFCCommands::GetTagInRangeEvent: getTagInRangeEvent(messagePointer); break;
case NFCCommands::GetTagOutOfRangeEvent: getTagOutOfRangeEvent(messagePointer); break;
default: Helpers::panic("NFC service requested. Command: %08X\n", command);
}
}
@ -30,4 +38,39 @@ void NFCService::initialize(u32 messagePointer) {
// TODO: This should error if already initialized. Also sanitize type.
mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}
/*
The NFC service provides userland with 2 events. One that is signaled when an NFC tag gets in range,
And one that is signaled when it gets out of range. Userland can have a thread sleep on this so it will be alerted
Whenever an Amiibo or misc NFC tag is presented or removed.
These events are retrieved via the GetTagInRangeEvent and GetTagOutOfRangeEvent function respectively
*/
void NFCService::getTagInRangeEvent(u32 messagePointer) {
log("NFC::GetTagInRangeEvent\n");
// Create event if it doesn't exist
if (!tagInRangeEvent.has_value()) {
tagInRangeEvent = kernel.makeEvent(ResetType::OneShot);
}
mem.write32(messagePointer, IPC::responseHeader(0x0B, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
// TODO: Translation descriptor here
mem.write32(messagePointer + 12, tagInRangeEvent.value());
}
void NFCService::getTagOutOfRangeEvent(u32 messagePointer) {
log("NFC::GetTagOutOfRangeEvent\n");
// Create event if it doesn't exist
if (!tagOutOfRangeEvent.has_value()) {
tagOutOfRangeEvent = kernel.makeEvent(ResetType::OneShot);
}
mem.write32(messagePointer, IPC::responseHeader(0x0C, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
// TODO: Translation descriptor here
mem.write32(messagePointer + 12, tagOutOfRangeEvent.value());
}

View file

@ -6,7 +6,7 @@
ServiceManager::ServiceManager(std::array<u32, 16>& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel)
: regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem), cecd(mem),
cfg(mem), dsp(mem, kernel), hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem),
ldr(mem), mic(mem), nfc(mem), nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {}
ldr(mem), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {}
static constexpr int MAX_NOTIFICATION_COUNT = 16;