Properly implement NFC result codes

This commit is contained in:
GaryOderNichts 2024-05-18 16:38:52 +02:00
parent 41fe598e33
commit 8fe69cd0fb
5 changed files with 153 additions and 88 deletions

View File

@ -7,27 +7,25 @@
#include "TagV0.h"
#include "ndef.h"
// TODO move errors to header and allow ntag to convert them
#define NFC_MODE_INVALID -1
#define NFC_MODE_IDLE 0
#define NFC_MODE_ACTIVE 1
#define NFC_MODE_INVALID -1
#define NFC_MODE_IDLE 0
#define NFC_MODE_ACTIVE 1
#define NFC_STATE_UNINITIALIZED 0x0
#define NFC_STATE_INITIALIZED 0x1
#define NFC_STATE_IDLE 0x2
#define NFC_STATE_READ 0x3
#define NFC_STATE_WRITE 0x4
#define NFC_STATE_ABORT 0x5
#define NFC_STATE_FORMAT 0x6
#define NFC_STATE_SET_READ_ONLY 0x7
#define NFC_STATE_TAG_PRESENT 0x8
#define NFC_STATE_DETECT 0x9
#define NFC_STATE_SEND_RAW_DATA 0xA
#define NFC_STATE_UNINITIALIZED 0x0
#define NFC_STATE_INITIALIZED 0x1
#define NFC_STATE_IDLE 0x2
#define NFC_STATE_READ 0x3
#define NFC_STATE_WRITE 0x4
#define NFC_STATE_ABORT 0x5
#define NFC_STATE_FORMAT 0x6
#define NFC_STATE_SET_READ_ONLY 0x7
#define NFC_STATE_TAG_PRESENT 0x8
#define NFC_STATE_DETECT 0x9
#define NFC_STATE_RAW 0xA
#define NFC_STATUS_COMMAND_COMPLETE 0x1
#define NFC_STATUS_READY 0x2
#define NFC_STATUS_HAS_TAG 0x4
#define NFC_STATUS_COMMAND_COMPLETE 0x1
#define NFC_STATUS_READY 0x2
#define NFC_STATUS_HAS_TAG 0x4
namespace nfc
{
@ -107,7 +105,7 @@ namespace nfc
ctx->isInitialized = true;
ctx->state = NFC_STATE_INITIALIZED;
return 0;
return NFC_RESULT_SUCCESS;
}
sint32 NFCShutdown(uint32 chan)
@ -118,7 +116,7 @@ namespace nfc
__NFCClearContext(ctx);
return 0;
return NFC_RESULT_SUCCESS;
}
bool NFCIsInit(uint32 chan)
@ -183,26 +181,26 @@ namespace nfc
lockedDataSize = ctx->tag->GetLockedArea().size();
memcpy(lockedData.GetPointer(), ctx->tag->GetLockedArea().data(), lockedDataSize);
result = 0;
result = NFC_RESULT_SUCCESS;
}
else
{
result = -0xBFE;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_TAG_PARSE, NFC_RESULT_INVALID_TAG);
}
}
else
{
result = -0xBFE;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_TAG_PARSE, NFC_RESULT_INVALID_TAG);
}
}
else
{
result = -0x1F6;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_READ, NFC_RESULT_UID_MISMATCH);
}
}
else
{
result = -0x1DD;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_READ, NFC_RESULT_NO_TAG);
}
PPCCoreCallback(ctx->readCallback, chan, result, uid.GetPointer(), readOnly, dataSize, data.GetPointer(), lockedDataSize, lockedData.GetPointer(), ctx->readContext);
@ -231,13 +229,13 @@ namespace nfc
{
newPath += ".bak";
}
cemuLog_log(LogType::Force, "Saving tag as {}...", newPath.string());
cemuLog_log(LogType::NFC, "Saving tag as {}...", newPath.string());
// open file for writing
FileStream* fs = FileStream::createFile2(newPath);
if (!fs)
{
result = -0x2DE;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_WRITE, 0x22);
}
else
{
@ -245,17 +243,17 @@ namespace nfc
fs->writeData(tagBytes.data(), tagBytes.size());
delete fs;
result = 0;
result = NFC_RESULT_SUCCESS;
}
}
else
{
result = -0x2F6;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_WRITE, NFC_RESULT_UID_MISMATCH);
}
}
else
{
result = -0x2DD;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_WRITE, NFC_RESULT_NO_TAG);
}
PPCCoreCallback(ctx->writeCallback, chan, result, ctx->writeContext);
@ -279,11 +277,11 @@ namespace nfc
sint32 result;
if (ctx->nfcStatus & NFC_STATUS_HAS_TAG)
{
result = 0;
result = NFC_RESULT_SUCCESS;
}
else
{
result = -0x9DD;
result = NFC_MAKE_RESULT(NFC_RESULT_BASE_SEND_RAW_DATA, NFC_RESULT_NO_TAG);
}
// We don't actually send any commands/responses
@ -379,12 +377,15 @@ namespace nfc
case NFC_STATE_ABORT:
__NFCHandleAbort(chan);
break;
case NFC_STATE_RAW:
case NFC_STATE_SEND_RAW_DATA:
__NFCHandleRaw(chan);
break;
default:
break;
}
// Return back to idle mode
ctx->mode = NFC_MODE_IDLE;
}
}
@ -410,17 +411,17 @@ namespace nfc
if (!NFCIsInit(chan))
{
return -0xAE0;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_SET_MODE, NFC_RESULT_UNINITIALIZED);
}
if (ctx->state == NFC_STATE_UNINITIALIZED)
{
return -0xADF;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_SET_MODE, NFC_RESULT_INVALID_STATE);
}
ctx->mode = mode;
return 0;
return NFC_RESULT_SUCCESS;
}
void NFCSetTagDetectCallback(uint32 chan, MPTR callback, void* context)
@ -440,19 +441,30 @@ namespace nfc
if (!NFCIsInit(chan))
{
return -0x6E0;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_ABORT, NFC_RESULT_UNINITIALIZED);
}
if (ctx->state <= NFC_STATE_IDLE)
{
return -0x6DF;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_ABORT, NFC_RESULT_INVALID_STATE);
}
ctx->state = NFC_STATE_ABORT;
ctx->abortCallback = callback;
ctx->abortContext = context;
return 0;
return NFC_RESULT_SUCCESS;
}
sint32 __NFCConvertGetTagInfoResult(sint32 result)
{
if (result == NFC_MAKE_RESULT(NFC_RESULT_BASE_SEND_RAW_DATA, NFC_RESULT_NO_TAG))
{
return NFC_MAKE_RESULT(NFC_RESULT_BASE_GET_TAG_INFO, NFC_RESULT_TAG_INFO_TIMEOUT);
}
// TODO convert the rest of the results
return result;
}
void __NFCGetTagInfoCallback(PPCInterpreter_t* hCPU)
@ -465,8 +477,7 @@ namespace nfc
NFCContext* ctx = &gNFCContexts[chan];
// TODO convert error
error = error;
error = __NFCConvertGetTagInfoResult(error);
if (error == 0 && ctx->tag)
{
// this is usually parsed from response data
@ -496,7 +507,7 @@ namespace nfc
ctx->getTagInfoCallback = callback;
sint32 result = NFCSendRawData(chan, true, discoveryTimeout, 1000U, 0, 0, nullptr, RPLLoader_MakePPCCallable(__NFCGetTagInfoCallback), context);
return result; // TODO convert result
return __NFCConvertGetTagInfoResult(result);
}
sint32 NFCSendRawData(uint32 chan, bool startDiscovery, uint32 discoveryTimeout, uint32 commandTimeout, uint32 commandSize, uint32 responseSize, void* commandData, MPTR callback, void* context)
@ -507,26 +518,26 @@ namespace nfc
if (!NFCIsInit(chan))
{
return -0x9E0;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_SEND_RAW_DATA, NFC_RESULT_UNINITIALIZED);
}
// Only allow discovery
if (!startDiscovery)
{
return -0x9DC;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_SEND_RAW_DATA, NFC_RESULT_INVALID_MODE);
}
if (NFCGetMode(chan) == NFC_MODE_ACTIVE && NFCSetMode(chan, NFC_MODE_IDLE) < 0)
{
return -0x9DC;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_SEND_RAW_DATA, NFC_RESULT_INVALID_MODE);
}
if (ctx->state != NFC_STATE_IDLE)
{
return -0x9DF;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_SEND_RAW_DATA, NFC_RESULT_INVALID_STATE);
}
ctx->state = NFC_STATE_RAW;
ctx->state = NFC_STATE_SEND_RAW_DATA;
ctx->rawCallback = callback;
ctx->rawContext = context;
@ -540,7 +551,7 @@ namespace nfc
ctx->discoveryTimeout = std::chrono::system_clock::now() + std::chrono::milliseconds(discoveryTimeout);
}
return 0;
return NFC_RESULT_SUCCESS;
}
sint32 NFCRead(uint32 chan, uint32 discoveryTimeout, NFCUid* uid, NFCUid* uidMask, MPTR callback, void* context)
@ -551,21 +562,19 @@ namespace nfc
if (!NFCIsInit(chan))
{
return -0x1E0;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_READ, NFC_RESULT_UNINITIALIZED);
}
if (NFCGetMode(chan) == NFC_MODE_ACTIVE && NFCSetMode(chan, NFC_MODE_IDLE) < 0)
{
return -0x1DC;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_READ, NFC_RESULT_INVALID_MODE);
}
if (ctx->state != NFC_STATE_IDLE)
{
return -0x1DF;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_READ, NFC_RESULT_INVALID_STATE);
}
cemuLog_log(LogType::NFC, "starting read");
ctx->state = NFC_STATE_READ;
ctx->readCallback = callback;
ctx->readContext = context;
@ -583,7 +592,7 @@ namespace nfc
memcpy(&ctx->filter.uid, uid, sizeof(*uid));
memcpy(&ctx->filter.mask, uidMask, sizeof(*uidMask));
return 0;
return NFC_RESULT_SUCCESS;
}
sint32 NFCWrite(uint32 chan, uint32 discoveryTimeout, NFCUid* uid, NFCUid* uidMask, uint32 size, void* data, MPTR callback, void* context)
@ -594,17 +603,17 @@ namespace nfc
if (!NFCIsInit(chan))
{
return -0x2e0;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_WRITE, NFC_RESULT_UNINITIALIZED);
}
if (NFCGetMode(chan) == NFC_MODE_ACTIVE && NFCSetMode(chan, NFC_MODE_IDLE) < 0)
{
return -0x2dc;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_WRITE, NFC_RESULT_INVALID_MODE);
}
if (ctx->state != NFC_STATE_IDLE)
{
return -0x1df;
return NFC_MAKE_RESULT(NFC_RESULT_BASE_WRITE, NFC_RESULT_INVALID_STATE);
}
// Create unknown record which contains the rw area
@ -634,7 +643,7 @@ namespace nfc
memcpy(&ctx->filter.uid, uid, sizeof(*uid));
memcpy(&ctx->filter.mask, uidMask, sizeof(*uidMask));
return 0;
return NFC_RESULT_SUCCESS;
}
void Initialize()
@ -668,14 +677,14 @@ namespace nfc
auto nfcData = FileStream::LoadIntoMemory(filePath);
if (!nfcData)
{
*nfcError = NFC_ERROR_NO_ACCESS;
*nfcError = NFC_TOUCH_TAG_ERROR_NO_ACCESS;
return false;
}
ctx->tag = TagV0::FromBytes(std::as_bytes(std::span(nfcData->data(), nfcData->size())));
if (!ctx->tag)
{
*nfcError = NFC_ERROR_INVALID_FILE_FORMAT;
*nfcError = NFC_TOUCH_TAG_ERROR_INVALID_FILE_FORMAT;
return false;
}
@ -683,7 +692,7 @@ namespace nfc
ctx->tagPath = filePath;
ctx->touchTime = std::chrono::system_clock::now();
*nfcError = NFC_ERROR_NONE;
*nfcError = NFC_TOUCH_TAG_ERROR_NONE;
return true;
}
}

View File

@ -1,9 +1,39 @@
#pragma once
// CEMU NFC error codes
#define NFC_ERROR_NONE (0)
#define NFC_ERROR_NO_ACCESS (1)
#define NFC_ERROR_INVALID_FILE_FORMAT (2)
#define NFC_TOUCH_TAG_ERROR_NONE (0)
#define NFC_TOUCH_TAG_ERROR_NO_ACCESS (1)
#define NFC_TOUCH_TAG_ERROR_INVALID_FILE_FORMAT (2)
// NFC result base
#define NFC_RESULT_BASE_INIT (-0x100)
#define NFC_RESULT_BASE_READ (-0x200)
#define NFC_RESULT_BASE_WRITE (-0x300)
#define NFC_RESULT_BASE_FORMAT (-0x400)
#define NFC_RESULT_BASE_SET_READ_ONLY (-0x500)
#define NFC_RESULT_BASE_IS_TAG_PRESENT (-0x600)
#define NFC_RESULT_BASE_ABORT (-0x700)
#define NFC_RESULT_BASE_SHUTDOWN (-0x800)
#define NFC_RESULT_BASE_DETECT (-0x900)
#define NFC_RESULT_BASE_SEND_RAW_DATA (-0xA00)
#define NFC_RESULT_BASE_SET_MODE (-0xB00)
#define NFC_RESULT_BASE_TAG_PARSE (-0xC00)
#define NFC_RESULT_BASE_GET_TAG_INFO (-0x1400)
// NFC result status
#define NFC_RESULT_NO_TAG (0x01)
#define NFC_RESULT_INVALID_TAG (0x02)
#define NFC_RESULT_UID_MISMATCH (0x0A)
#define NFC_RESULT_UNINITIALIZED (0x20)
#define NFC_RESULT_INVALID_STATE (0x21)
#define NFC_RESULT_INVALID_MODE (0x24)
#define NFC_RESULT_TAG_INFO_TIMEOUT (0x7A)
// Result macros
#define NFC_RESULT_SUCCESS (0)
#define NFC_RESULT_BASE_MASK (0xFFFFFF00)
#define NFC_RESULT_MASK (0x000000FF)
#define NFC_MAKE_RESULT(base, result) ((base) | (result))
#define NFC_PROTOCOL_T1T 0x1
#define NFC_PROTOCOL_T2T 0x2

View File

@ -26,10 +26,27 @@ namespace ntag
MPTR gReadCallbacks[2];
MPTR gWriteCallbacks[2];
sint32 __NTAGConvertNFCError(sint32 error)
sint32 __NTAGConvertNFCResult(sint32 result)
{
// TODO
return error;
if (result == NFC_RESULT_SUCCESS)
{
return NTAG_RESULT_SUCCESS;
}
switch (result & NFC_RESULT_MASK)
{
case NFC_RESULT_UNINITIALIZED:
return NTAG_RESULT_UNINITIALIZED;
case NFC_RESULT_INVALID_STATE:
return NTAG_RESULT_INVALID_STATE;
case NFC_RESULT_NO_TAG:
return NTAG_RESULT_NO_TAG;
case NFC_RESULT_UID_MISMATCH:
return NTAG_RESULT_UID_MISMATCH;
}
// TODO convert more errors
return NTAG_RESULT_INVALID;
}
sint32 NTAGInit(uint32 chan)
@ -40,7 +57,7 @@ namespace ntag
sint32 NTAGInitEx(uint32 chan)
{
sint32 result = nfc::NFCInitEx(chan, 1);
return __NTAGConvertNFCError(result);
return __NTAGConvertNFCResult(result);
}
sint32 NTAGShutdown(uint32 chan)
@ -58,7 +75,7 @@ namespace ntag
gReadCallbacks[chan] = MPTR_NULL;
gWriteCallbacks[chan] = MPTR_NULL;
return __NTAGConvertNFCError(result);
return __NTAGConvertNFCResult(result);
}
bool NTAGIsInit(uint32 chan)
@ -105,7 +122,7 @@ namespace ntag
ppcDefineParamS32(error, 1);
ppcDefineParamPtr(context, void, 2);
PPCCoreCallback(gAbortCallbacks[chan], chan, __NTAGConvertNFCError(error), context);
PPCCoreCallback(gAbortCallbacks[chan], chan, __NTAGConvertNFCResult(error), context);
osLib_returnFromFunction(hCPU, 0);
}
@ -118,7 +135,7 @@ namespace ntag
gAbortCallbacks[chan] = callback;
sint32 result = nfc::NFCAbort(chan, RPLLoader_MakePPCCallable(__NTAGAbortCallback), context);
return __NTAGConvertNFCError(result);
return __NTAGConvertNFCResult(result);
}
bool __NTAGRawDataToNfcData(iosu::ccr_nfc::CCRNFCCryptData* raw, iosu::ccr_nfc::CCRNFCCryptData* nfc)
@ -370,7 +387,7 @@ namespace ntag
readResult->readOnly = readOnly;
error = __NTAGConvertNFCError(error);
error = __NTAGConvertNFCResult(error);
if (error == 0)
{
memset(rwData.GetPointer(), 0, 0x1C8);
@ -430,7 +447,7 @@ namespace ntag
}
sint32 result = nfc::NFCRead(chan, timeout, &_uid, &_uidMask, RPLLoader_MakePPCCallable(__NTAGReadCallback), context);
return __NTAGConvertNFCError(result);
return __NTAGConvertNFCResult(result);
}
sint32 __NTAGEncryptData(void* encryptedData, const void* rawData)
@ -512,7 +529,7 @@ namespace ntag
ppcDefineParamS32(error, 1);
ppcDefineParamPtr(context, void, 2);
PPCCoreCallback(gWriteCallbacks[chan], chan, __NTAGConvertNFCError(error), context);
PPCCoreCallback(gWriteCallbacks[chan], chan, __NTAGConvertNFCResult(error), context);
osLib_returnFromFunction(hCPU, 0);
}
@ -538,7 +555,7 @@ namespace ntag
NTAGAreaHeader roHeader;
uint8 writeBuffer[0x1C8]{};
error = __NTAGConvertNFCError(error);
error = __NTAGConvertNFCResult(error);
if (error == 0)
{
// Copy raw and locked data into a contigous buffer
@ -576,7 +593,7 @@ namespace ntag
return;
}
error = __NTAGConvertNFCError(error);
error = __NTAGConvertNFCResult(error);
}
PPCCoreCallback(gWriteCallbacks[chan], chan, error, context);
@ -600,7 +617,7 @@ namespace ntag
memcpy(gWriteData[chan].data, rwData, rwSize);
sint32 result = nfc::NFCRead(chan, timeout, &gWriteData[chan].uid, &gWriteData[chan].uidMask, RPLLoader_MakePPCCallable(__NTAGReadBeforeWriteCallback), context);
return __NTAGConvertNFCError(result);
return __NTAGConvertNFCResult(result);
}
sint32 NTAGFormat(uint32 chan, uint32 timeout, nfc::NFCUid* uid, uint32 rwSize, void* rwData, MPTR callback, void* context)
@ -608,7 +625,9 @@ namespace ntag
cemu_assert(chan < 2);
// TODO
return -1;
cemu_assert_debug(false);
return NTAG_RESULT_INVALID;
}
void Initialize()

View File

@ -1,6 +1,13 @@
#pragma once
#include "Cafe/OS/libs/nfc/nfc.h"
#define NTAG_RESULT_SUCCESS (0)
#define NTAG_RESULT_UNINITIALIZED (-0x3E7)
#define NTAG_RESULT_INVALID_STATE (-0x3E6)
#define NTAG_RESULT_NO_TAG (-0x3E5)
#define NTAG_RESULT_INVALID (-0x3E1)
#define NTAG_RESULT_UID_MISMATCH (-0x3DB)
namespace ntag
{
struct NTAGFormatSettings

View File

@ -269,10 +269,10 @@ public:
}
else
{
if (nfcError == NFC_ERROR_NO_ACCESS)
if (nfcError == NFC_TOUCH_TAG_ERROR_NO_ACCESS)
wxMessageBox(_("Cannot open file"), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
else if (nfcError == NFC_ERROR_INVALID_FILE_FORMAT)
wxMessageBox(_("Not a valid NFC NTAG215 file"), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
else if (nfcError == NFC_TOUCH_TAG_ERROR_INVALID_FILE_FORMAT)
wxMessageBox(_("Not a valid NFC file"), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
return false;
}
}
@ -751,10 +751,10 @@ void MainWindow::OnNFCMenu(wxCommandEvent& event)
uint32 nfcError;
if (nfc::TouchTagFromFile(_utf8ToPath(wxStrFilePath.utf8_string()), &nfcError) == false)
{
if (nfcError == NFC_ERROR_NO_ACCESS)
if (nfcError == NFC_TOUCH_TAG_ERROR_NO_ACCESS)
wxMessageBox(_("Cannot open file"));
else if (nfcError == NFC_ERROR_INVALID_FILE_FORMAT)
wxMessageBox(_("Not a valid NFC NTAG215 file"));
else if (nfcError == NFC_TOUCH_TAG_ERROR_INVALID_FILE_FORMAT)
wxMessageBox(_("Not a valid NFC file"));
}
else
{
@ -774,10 +774,10 @@ void MainWindow::OnNFCMenu(wxCommandEvent& event)
uint32 nfcError = 0;
if (nfc::TouchTagFromFile(_utf8ToPath(path), &nfcError) == false)
{
if (nfcError == NFC_ERROR_NO_ACCESS)
if (nfcError == NFC_TOUCH_TAG_ERROR_NO_ACCESS)
wxMessageBox(_("Cannot open file"));
else if (nfcError == NFC_ERROR_INVALID_FILE_FORMAT)
wxMessageBox(_("Not a valid NFC NTAG215 file"));
else if (nfcError == NFC_TOUCH_TAG_ERROR_INVALID_FILE_FORMAT)
wxMessageBox(_("Not a valid NFC file"));
}
else
{