mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-22 09:09:18 +01:00
nfc: Implement UID filter
This commit is contained in:
parent
8e8431113a
commit
41fe598e33
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user