nfc: Implement UID filter

This commit is contained in:
GaryOderNichts 2024-05-17 14:19:51 +02:00
parent 8e8431113a
commit 41fe598e33

View File

@ -41,6 +41,10 @@ namespace nfc
uint32 nfcStatus; uint32 nfcStatus;
std::chrono::time_point<std::chrono::system_clock> touchTime; std::chrono::time_point<std::chrono::system_clock> touchTime;
std::chrono::time_point<std::chrono::system_clock> discoveryTimeout; std::chrono::time_point<std::chrono::system_clock> discoveryTimeout;
struct {
NFCUid uid;
NFCUid mask;
} filter;
MPTR tagDetectCallback; MPTR tagDetectCallback;
void* tagDetectContext; void* tagDetectContext;
@ -124,6 +128,19 @@ namespace nfc
return gNFCContexts[chan].isInitialized; return gNFCContexts[chan].isInitialized;
} }
bool __NFCCompareUid(NFCUid* uid, NFCUid* filterUid, NFCUid* filterMask)
{
for (int i = 0; i < sizeof(uid->uid); i++)
{
if ((uid->uid[i] & filterMask->uid[i]) != filterUid->uid[i])
{
return false;
}
}
return true;
}
void __NFCHandleRead(uint32 chan) void __NFCHandleRead(uint32 chan)
{ {
NFCContext* ctx = &gNFCContexts[chan]; NFCContext* ctx = &gNFCContexts[chan];
@ -140,32 +157,38 @@ namespace nfc
if (ctx->tag) if (ctx->tag)
{ {
// Try to parse ndef message // Compare UID
auto ndefMsg = ndef::Message::FromBytes(ctx->tag->GetNDEFData()); memcpy(uid.GetPointer(), ctx->tag->GetUIDBlock().data(), sizeof(NFCUid));
if (ndefMsg) if (__NFCCompareUid(uid.GetPointer(), &ctx->filter.uid, &ctx->filter.mask))
{ {
// Look for the unknown TNF which contains the data we care about // Try to parse ndef message
for (const auto& rec : *ndefMsg) auto ndefMsg = ndef::Message::FromBytes(ctx->tag->GetNDEFData());
if (ndefMsg)
{ {
if (rec.GetTNF() == ndef::Record::NDEF_TNF_UNKNOWN) // Look for the unknown TNF which contains the data we care about
for (const auto& rec : *ndefMsg)
{ {
dataSize = rec.GetPayload().size(); if (rec.GetTNF() == ndef::Record::NDEF_TNF_UNKNOWN)
cemu_assert(dataSize < 0x200); {
memcpy(data.GetPointer(), rec.GetPayload().data(), dataSize); dataSize = rec.GetPayload().size();
break; cemu_assert(dataSize < 0x200);
memcpy(data.GetPointer(), rec.GetPayload().data(), dataSize);
break;
}
} }
}
if (dataSize) if (dataSize)
{ {
// Get locked data // Get locked data
lockedDataSize = ctx->tag->GetLockedArea().size(); lockedDataSize = ctx->tag->GetLockedArea().size();
memcpy(lockedData.GetPointer(), ctx->tag->GetLockedArea().data(), lockedDataSize); memcpy(lockedData.GetPointer(), ctx->tag->GetLockedArea().data(), lockedDataSize);
// Fill in uid result = 0;
memcpy(uid.GetPointer(), ctx->tag->GetUIDBlock().data(), sizeof(NFCUid)); }
else
result = 0; {
result = -0xBFE;
}
} }
else else
{ {
@ -174,7 +197,7 @@ namespace nfc
} }
else else
{ {
result = -0xBFE; result = -0x1F6;
} }
} }
else else
@ -195,30 +218,39 @@ namespace nfc
if (ctx->tag) if (ctx->tag)
{ {
// Update tag NDEF data NFCUid uid;
ctx->tag->SetNDEFData(ctx->writeMessage.ToBytes()); memcpy(&uid, ctx->tag->GetUIDBlock().data(), sizeof(NFCUid));
if (__NFCCompareUid(&uid, &ctx->filter.uid, &ctx->filter.mask))
// TODO remove this once writing is confirmed working
fs::path newPath = ctx->tagPath;
if (newPath.extension() != ".bak")
{ {
newPath += ".bak"; // Update tag NDEF data
} ctx->tag->SetNDEFData(ctx->writeMessage.ToBytes());
cemuLog_log(LogType::Force, "Saving tag as {}...", newPath.string());
// open file for writing // TODO remove this once writing is confirmed working
FileStream* fs = FileStream::createFile2(newPath); fs::path newPath = ctx->tagPath;
if (!fs) if (newPath.extension() != ".bak")
{ {
result = -0x2DE; newPath += ".bak";
}
cemuLog_log(LogType::Force, "Saving tag as {}...", newPath.string());
// open file for writing
FileStream* fs = FileStream::createFile2(newPath);
if (!fs)
{
result = -0x2DE;
}
else
{
auto tagBytes = ctx->tag->ToBytes();
fs->writeData(tagBytes.data(), tagBytes.size());
delete fs;
result = 0;
}
} }
else else
{ {
auto tagBytes = ctx->tag->ToBytes(); result = -0x2F6;
fs->writeData(tagBytes.data(), tagBytes.size());
delete fs;
result = 0;
} }
} }
else else
@ -548,7 +580,8 @@ namespace nfc
ctx->discoveryTimeout = std::chrono::system_clock::now() + std::chrono::milliseconds(discoveryTimeout); ctx->discoveryTimeout = std::chrono::system_clock::now() + std::chrono::milliseconds(discoveryTimeout);
} }
// TODO uid filter? memcpy(&ctx->filter.uid, uid, sizeof(*uid));
memcpy(&ctx->filter.mask, uidMask, sizeof(*uidMask));
return 0; return 0;
} }
@ -598,7 +631,8 @@ namespace nfc
ctx->discoveryTimeout = std::chrono::system_clock::now() + std::chrono::milliseconds(discoveryTimeout); ctx->discoveryTimeout = std::chrono::system_clock::now() + std::chrono::milliseconds(discoveryTimeout);
} }
// TODO uid filter? memcpy(&ctx->filter.uid, uid, sizeof(*uid));
memcpy(&ctx->filter.mask, uidMask, sizeof(*uidMask));
return 0; return 0;
} }