Merge pull request #260 from javimadgit/master

Add basic NFC service support
This commit is contained in:
fincs 2016-02-04 17:53:31 +01:00
commit 42ce1d8792
2 changed files with 248 additions and 0 deletions

View File

@ -0,0 +1,79 @@
/**
* @file nfc.h
* @brief NFC service.
*/
#pragma once
/**
* @brief Initializes NFC.
*/
Result nfcInit(void);
/**
* @brief Shuts down NFC.
*/
void nfcExit(void);
/**
* @brief Gets the NFC service handle.
* @return The NFC service handle.
*/
Handle nfcGetSessionHandle(void);
/**
* @brief Initialize NFC module.
* @param type Unknown, can be either value 0x1 or 0x2.
*/
Result NFC_Initialize(u8 type);
/**
* @brief Shutdown NFC module.
* @param type Unknown.
*/
Result NFC_Shutdown(u8 type);
/**
* @brief O3DS starts communication with the O3DS NFC hardware. N3DS just checks state for this command.
*/
Result NFC_StartCommunication(void);
/**
* @brief O3DS stops communication with the O3DS NFC hardware. N3DS just uses code used internally by NFC:StopTagScanning for this.
*/
Result NFC_StopCommunication(void);
/**
* @brief Starts scanning for NFC tags.
* @param unknown Unknown.
*/
Result NFC_StartTagScanning(u16 unknown);
/**
* @brief Stops scanning for NFC tags.
*/
Result NFC_StopTagScanning(void);
/**
* @brief Read Amiibo NFC data and load in memory.
*/
Result NFC_LoadAmiiboData(void);
/**
* @brief If the tagstate is valid, it then sets the current tagstate to 3.
*/
Result NFC_ResetTagScanState(void);
/**
* @brief Returns the current NFC tag state.
* @param state Pointer to write NFC tag state.
*
* Tag state values:
* - 0: NFC:Initialize was not used yet.
* - 1: Not currently scanning for NFC tags. Set by NFC:StopTagScanning and NFC:Initialize, when successful.
* - 2: Currently scanning for NFC tags. Set by NFC:StartTagScanning when successful.
* - 3: NFC tag is in range. The state automatically changes to this when the state was previous value 3, without using any NFC service commands.
* - 4: NFC tag is now out of range, where the NFC tag was previously in range. This occurs automatically without using any NFC service commands. Once this state is entered, it won't automatically change to anything else when the tag is moved in range again. Hence, if you want to keep doing tag scanning after this, you must stop+start scanning.
* - 5: NFC tag data was successfully loaded. This is set by NFC:LoadAmiiboData when successful.
*/
Result NFC_GetTagState(u8 *state);

View File

@ -0,0 +1,169 @@
#include <3ds/types.h>
#include <3ds/result.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/synchronization.h>
#include <3ds/services/nfc.h>
#include <3ds/ipc.h>
static Handle nfcHandle;
static int nfcRefCount;
Result nfcInit(void)
{
Result ret=0;
if (AtomicPostIncrement(&nfcRefCount)) return 0;
ret = srvGetServiceHandle(&nfcHandle, "nfc:u");
if (R_SUCCEEDED(ret))
{
ret = NFC_Initialize(0x02);
if (R_FAILED(ret)) svcCloseHandle(nfcHandle);
}
if (R_FAILED(ret)) AtomicDecrement(&nfcRefCount);
return ret;
}
void nfcExit(void)
{
if (AtomicDecrement(&nfcRefCount)) return;
svcCloseHandle(nfcHandle);
}
Handle nfcGetSessionHandle(void)
{
return nfcHandle;
}
Result NFC_Initialize(u8 type)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x1,1,0); // 0x10040
cmdbuf[1]=type;
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_Shutdown(u8 type)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x2,1,0); // 0x20040
cmdbuf[1]=type;
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_StartCommunication(void)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x3,0,0); // 0x30000
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_StopCommunication(void)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x4,0,0); // 0x40000
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_StartTagScanning(u16 unknown)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x5,1,0); // 0x50040
cmdbuf[1]=unknown;
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_StopTagScanning(void)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x6,0,0); // 0x60000
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_LoadAmiiboData(void)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x7,0,0); // 0x70000
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_ResetTagScanState(void)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x8,0,0); // 0x80000
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
return ret;
}
Result NFC_GetTagState(u8 *state)
{
Result ret=0;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0xD,0,0); // 0xD0000
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
ret = (Result)cmdbuf[1];
*state = cmdbuf[2];
return ret;
}