libctru  v2.3.1
nfc/source/main.c
#include <stdio.h>
#include <string.h>
#include <3ds.h>
Result nfc_test()
{
Result ret=0;
u32 pos;
FILE *f;
size_t tmpsize;
NFC_TagState prevstate, curstate;
NFC_TagInfo taginfo;
NFC_AmiiboSettings amiibosettings;
NFC_AmiiboConfig amiiboconfig;
u32 amiibo_appid = 0x10110E00;//Hard-coded for Super Smash Bros. See also: https://www.3dbrew.org/wiki/Amiibo
u32 appdata_initialized;
u8 appdata[0xd8];
char uidstr[16];
char tmpstr[64];
printf("NFC initialized successfully, starting scanning...\n");
if(R_FAILED(ret))
{
printf("nfcStartScanning() failed.\n");
return ret;
}
ret = nfcGetTagState(&curstate);
if(R_FAILED(ret))
{
printf("nfcGetTagState() failed.\n");
return ret;
}
prevstate = curstate;
printf("Press B to stop scanning or Y to restart scanning.\n");
printf("Press X after an amiibo was successfully\nprocessed while still in range, to reprocess it.\n");
printf("Hold down A while processing an amiibo to write\nappdata from SD to it. The amiibo appdata will be\ninitialized if it wasn't initialized already.\n");
printf("Scanning must be restarted after a NFC tag goes\nout-of-range, if you want to scan more tag(s).\n");
while(1)
{
u32 kDown = hidKeysDown();
if(kDown & KEY_B)break;
if(kDown & KEY_Y)//If you want this to be done automatically, you could run this when the TagState changes to NFC_TagState_OutOfRange.
{
printf("Restarting scanning...\n");
if(R_FAILED(ret))
{
printf("nfcStartScanning() failed.\n");
return ret;
}
printf("Scanning restarted.\n");
continue;
}
if(kDown & KEY_X)
{
if(R_FAILED(ret))
{
printf("nfcResetTagScanState() failed.\n");
break;
}
printf("nfcResetTagScanState() was successful.\n");
}
ret = nfcGetTagState(&curstate);
if(R_FAILED(ret))
{
printf("nfcGetTagState() failed.\n");
break;
}
if(curstate!=prevstate)//See nfc.h for the TagState values.
{
printf("TagState changed from %d to %d.\n", prevstate, curstate);
prevstate = curstate;
if(curstate==NFC_TagState_InRange)
{
memset(&taginfo, 0, sizeof(NFC_TagInfo));
memset(&amiibosettings, 0, sizeof(NFC_AmiiboSettings));
ret = nfcGetTagInfo(&taginfo);
if(R_FAILED(ret))
{
printf("nfcGetTagInfo() failed.\n");
break;
}
printf("taginfo id_offset_size: 0x%x.\n", (unsigned int)taginfo.id_offset_size);
printf("NFC tag UID:\n");
memset(uidstr, 0, sizeof(uidstr));
for(pos=0; pos<7; pos++)snprintf(&uidstr[pos*2], 3, "%02x", taginfo.id[pos]);
printf("%s\n", uidstr);
if(R_FAILED(ret))
{
printf("nfcLoadAmiiboData() failed.\n");
break;
}
memset(&amiibosettings, 0, sizeof(NFC_AmiiboSettings));
memset(&amiiboconfig, 0, sizeof(NFC_AmiiboConfig));
ret = nfcGetAmiiboSettings(&amiibosettings);
if(R_FAILED(ret))
{
printf("nfcGetAmiiboSettings() failed.\n");
if(ret==NFC_ERR_AMIIBO_NOTSETUP)printf("This amiibo wasn't setup by the amiibo Settings applet.\n");
break;
}
ret = nfcGetAmiiboConfig(&amiiboconfig);
if(R_FAILED(ret))
{
printf("nfcGetAmiiboConfig() failed.\n");
break;
}
printf("amiibo data successfully loaded.\n");
printf("amiiboconfig: lastwritedate year=%u month=%u day=%u.\n", amiiboconfig.lastwritedate_year, amiiboconfig.lastwritedate_month, amiiboconfig.lastwritedate_day);
printf("amiiboconfig.write_counter=%u\n", amiiboconfig.write_counter);
printf("Opening appdata...\n");
appdata_initialized = 1;
ret = nfcOpenAppData(amiibo_appid);
if(R_FAILED(ret))
{
printf("nfcOpenAppData() failed.\n");
{
printf("This appdata isn't initialized.\n");
appdata_initialized = 0;
}
if(ret==NFC_ERR_APPID_MISMATCH)printf("This appdata is for a different appid(non-Super-Smash-Bros).\n");
if(appdata_initialized)break;
}
memset(appdata, 0, sizeof(appdata));
if(!appdata_initialized)
{
printf("Skipping appdata reading since it's uninitialized.\n");
}
else
{
printf("Reading appdata...\n");
ret = nfcReadAppData(appdata, sizeof(appdata));
if(R_FAILED(ret))
{
printf("nfcReadAppData() failed.\n");
break;
}
printf("Appdata:\n");
for(pos=0; pos<sizeof(appdata); pos++)printf("%02x", appdata[pos]);
printf("\n");
memset(tmpstr, 0, sizeof(tmpstr));
snprintf(tmpstr, sizeof(tmpstr)-1, "amiibo_appdata_out_%s.bin", uidstr);
printf("Writing appdata to file '%s'...\n", tmpstr);
f = fopen(tmpstr, "w");
if(f)
{
tmpsize = fwrite(appdata, 1, sizeof(appdata), f);
fclose(f);
if(tmpsize!=sizeof(appdata))
{
printf("Failed to write to the file, only 0x%x of 0x%x bytes were written.\n", tmpsize, sizeof(appdata));
}
else
{
printf("Writing finished.\n");
}
}
else
{
printf("Failed to open the file.\n");
}
}
{
memset(tmpstr, 0, sizeof(tmpstr));
snprintf(tmpstr, sizeof(tmpstr)-1, "amiibo_appdata_in_%s.bin", uidstr);
printf("Loading appdata from file '%s', which will be written to the amiibo...\n", tmpstr);
ret = 1;
f = fopen(tmpstr, "r");
if(f)
{
memset(appdata, 0, sizeof(appdata));
tmpsize = fread(appdata, 1, sizeof(appdata), f);
fclose(f);
if(tmpsize!=sizeof(appdata))
{
printf("Failed to read to the file, only 0x%x of 0x%x bytes were written.\n", tmpsize, sizeof(appdata));
}
else
{
printf("File reading finished.\n");
ret = 0;
}
}
else
{
printf("Failed to open the file.\n");
}
if(ret==0)
{
if(appdata_initialized)
{
printf("Writing the appdata...\n");
ret = nfcWriteAppData(appdata, sizeof(appdata), &taginfo);
if(R_FAILED(ret))
{
printf("nfcWriteAppData() failed.\n");
break;
}
printf("Writing to the amiibo NFC tag...\n");
if(R_FAILED(ret))
{
printf("nfcUpdateStoredAmiiboData() failed.\n");
break;
}
}
else
{
printf("Initializing the appdata...\n");
ret = nfcInitializeWriteAppData(amiibo_appid, appdata, sizeof(appdata));
if(R_FAILED(ret))
{
printf("nfcInitializeWriteAppData() failed.\n");
break;
}
}
printf("Writing finished.\n");
}
}
printf("amiibo NFC tag processing has finished, you can\nremove the tag from NFC-range now.\n");
}
}
}
return ret;
}
int main()
{
Result ret=0;
printf("libctru nfc example.\n");
if(R_FAILED(ret))
{
printf("nfcInit() failed: 0x%08x.\n", (unsigned int)ret);
}
else
{
ret = nfc_test();
printf("nfc_test() returned: 0x%08x.\n", (unsigned int)ret);
}
printf("Press START to exit.\n");
// Main loop
while (aptMainLoop())
{
u32 kDown = hidKeysDown();
if (kDown & KEY_START)
break; // break in order to return to hbmenu
}
return 0;
}
Central 3DS header.
bool aptMainLoop(void)
Main function which handles sleep mode and HOME/power buttons - call this at the beginning of every f...
PrintConsole * consoleInit(gfxScreen_t screen, PrintConsole *console)
Initialise the console.
void gfxInitDefault(void)
Initializes the LCD framebuffers with default parameters This is equivalent to calling:
@ GFX_TOP
Top screen.
Definition: gfx.h:26
void gfxExit(void)
Deinitializes and frees the LCD framebuffers.
#define gspWaitForVBlank()
Waits for VBlank.
Definition: gspgpu.h:151
@ KEY_B
B.
Definition: hid.h:13
@ KEY_X
X.
Definition: hid.h:22
@ KEY_Y
Y.
Definition: hid.h:23
@ KEY_START
Start.
Definition: hid.h:15
@ KEY_A
A.
Definition: hid.h:12
u32 hidKeysHeld(void)
Returns a bitmask of held buttons.
u32 hidKeysDown(void)
Returns a bitmask of newly pressed buttons, this frame.
void hidScanInput(void)
Scans HID for input data.
Result nfcGetTagInfo(NFC_TagInfo *out)
Returns the current TagInfo.
#define NFC_ERR_AMIIBO_NOTSETUP
This is returned by nfcGetAmiiboSettings() when the amiibo wasn't setup by the amiibo Settings applet...
Definition: nfc.h:14
Result nfcUpdateStoredAmiiboData(void)
This writes the amiibo data stored in memory to the actual amiibo data storage(which is normally the ...
Result nfcGetAmiiboConfig(NFC_AmiiboConfig *out)
Returns the current AmiiboConfig.
void nfcExit(void)
Shuts down NFC.
Result nfcLoadAmiiboData(void)
Read amiibo NFC data and load in memory.
NFC_TagState
Definition: nfc.h:35
@ NFC_TagState_InRange
Currently scanning for NFC tags. Set by nfcStartScanning() when successful.
Definition: nfc.h:39
#define NFC_STARTSCAN_DEFAULTINPUT
This can be used for nfcStartScanning().
Definition: nfc.h:26
Result nfcInit(NFC_OpType type)
Initializes NFC.
Result nfcGetTagState(NFC_TagState *state)
Returns the current NFC tag state.
#define NFC_ERR_APPDATA_UNINITIALIZED
This is returned by nfcOpenAppData() when the appdata is uninitialized since nfcInitializeWriteAppDat...
Definition: nfc.h:11
Result nfcReadAppData(void *buf, size_t size)
Reads the appdata.
Result nfcOpenAppData(u32 amiibo_appid)
Opens the appdata, when the amiibo appdata was previously initialized.
Result nfcResetTagScanState(void)
If the tagstate is valid(NFC_TagState_DataReady or 6), it then sets the current tagstate to NFC_TagSt...
@ NFC_OpType_NFCTag
Unknown.
Definition: nfc.h:31
Result nfcGetAmiiboSettings(NFC_AmiiboSettings *out)
Returns the current AmiiboSettings.
Result nfcStartScanning(u16 inval)
Starts scanning for NFC tags.
Result nfcInitializeWriteAppData(u32 amiibo_appid, const void *buf, size_t size)
This initializes the appdata using the specified input, when the appdata previously wasn't initialize...
Result nfcWriteAppData(const void *buf, size_t size, NFC_TagInfo *taginfo)
Writes the appdata, after nfcOpenAppData() was used successfully.
void nfcStopScanning(void)
Stops scanning for NFC tags.
#define NFC_ERR_APPID_MISMATCH
This is returned by nfcOpenAppData() when the input AppID doesn't match the actual amiibo AppID.
Definition: nfc.h:17
#define R_FAILED(res)
Checks whether a result code indicates failure.
Definition: result.h:11
AmiiboConfig structure, see also here: https://3dbrew.org/wiki/NFC:GetAmiiboConfig.
Definition: nfc.h:70
AmiiboSettings structure, see also here: https://3dbrew.org/wiki/NFC:GetAmiiboSettings.
Definition: nfc.h:58
Definition: nfc.h:50
uint8_t u8
would be nice if newlib had this already
Definition: types.h:21
s32 Result
Function result.
Definition: types.h:42
uint32_t u32
32-bit unsigned integer
Definition: types.h:23