From cffb34740723e30f75446a6a2143e2db3221940d Mon Sep 17 00:00:00 2001 From: yellows8 Date: Thu, 16 Feb 2017 20:27:37 -0500 Subject: [PATCH] Added support for the NFC functionality implemented with system-version 10.0.0-X. --- libctru/include/3ds/services/nfc.h | 31 +++++++++++- libctru/source/services/nfc.c | 75 ++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/libctru/include/3ds/services/nfc.h b/libctru/include/3ds/services/nfc.h index f49bdeb..8fa9bf2 100644 --- a/libctru/include/3ds/services/nfc.h +++ b/libctru/include/3ds/services/nfc.h @@ -28,7 +28,8 @@ /// NFC operation type. typedef enum { NFC_OpType_1 = 1, /// Unknown. - NFC_OpType_NFCTag = 2 /// This is the default. + NFC_OpType_NFCTag = 2, /// This is the default. + NFC_OpType_RawNFC = 3 /// Use Raw NFC tag commands. Only available with >=10.0.0-X. } NFC_OpType; typedef enum { @@ -189,3 +190,31 @@ Result nfcGetAmiiboSettings(NFC_AmiiboSettings *out); */ Result nfcGetAmiiboConfig(NFC_AmiiboConfig *out); +/** + * @brief Starts scanning for NFC tags when initialized with NFC_OpType_RawNFC. See also: https://www.3dbrew.org/wiki/NFC:StartOtherTagScanning + * @param unk0 Same as nfcStartScanning() input. + * @param unk1 Unknown. + */ +Result nfcStartOtherTagScanning(u16 unk0, u32 unk1); + +/** + * @brief This sends a raw NFC command to the tag. This can only be used when initialized with NFC_OpType_RawNFC, and when the TagState is NFC_TagState_InRange. See also: https://www.3dbrew.org/wiki/NFC:SendTagCommand + * @param inbuf Input buffer. + * @param insize Size of the input buffer. + * @param outbuf Output buffer. + * @param outsize Size of the output buffer. + * @param actual_transfer_size Optional output ptr to write the actual output-size to, can be NULL. + * @param microseconds Timing-related field in microseconds. + */ +Result nfcSendTagCommand(const void *inbuf, size_t insize, void *outbuf, size_t outsize, size_t *actual_transfer_size, u64 microseconds); + +/** + * @brief Unknown. This can only be used when initialized with NFC_OpType_RawNFC, and when the TagState is NFC_TagState_InRange. + */ +Result nfcCmd21(void); + +/** + * @brief Unknown. This can only be used when initialized with NFC_OpType_RawNFC, and when the TagState is NFC_TagState_InRange. + */ +Result nfcCmd22(void); + diff --git a/libctru/source/services/nfc.c b/libctru/source/services/nfc.c index d11608a..99b229e 100644 --- a/libctru/source/services/nfc.c +++ b/libctru/source/services/nfc.c @@ -436,3 +436,78 @@ static Result NFC_GetAppDataInitStruct(NFC_AppDataInitStruct *out) return ret; } +Result nfcStartOtherTagScanning(u16 unk0, u32 unk1) +{ + Result ret=0; + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=IPC_MakeHeader(0x1F,2,0); // 0x1F0080 + cmdbuf[1] = unk0; + cmdbuf[2] = unk1; + + if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret; + ret = cmdbuf[1]; + + return ret; +} + +Result nfcSendTagCommand(const void *inbuf, size_t insize, void *outbuf, size_t outsize, size_t *actual_transfer_size, u64 microseconds) +{ + u32* cmdbuf=getThreadCommandBuffer(); + u32 saved_threadstorage[2]; + + cmdbuf[0]=IPC_MakeHeader(0x20,4,2); // 0x200102 + cmdbuf[1]=insize; + cmdbuf[2]=outsize; + cmdbuf[3]=(u32)(microseconds); + cmdbuf[4]=(u32)(microseconds>>32); + cmdbuf[5]=IPC_Desc_StaticBuffer(insize,0); + cmdbuf[6]=(u32)inbuf; + + u32 * staticbufs = getThreadStaticBuffers(); + saved_threadstorage[0] = staticbufs[0]; + saved_threadstorage[1] = staticbufs[1]; + + staticbufs[0] = IPC_Desc_StaticBuffer(outsize,0); + staticbufs[1] = (u32)outbuf; + + Result ret=0; + ret=svcSendSyncRequest(nfcHandle); + + staticbufs[0] = saved_threadstorage[0]; + staticbufs[1] = saved_threadstorage[1]; + + if(R_FAILED(ret))return ret; + + ret = cmdbuf[1]; + if(actual_transfer_size)*actual_transfer_size = cmdbuf[2]; + + return ret; +} + +Result nfcCmd21(void) +{ + Result ret=0; + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=IPC_MakeHeader(0x21,0,0); // 0x210000 + + if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret; + ret = cmdbuf[1]; + + return ret; +} + +Result nfcCmd22(void) +{ + Result ret=0; + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=IPC_MakeHeader(0x22,0,0); // 0x220000 + + if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret; + ret = cmdbuf[1]; + + return ret; +} +