Added support for libapplet nfpLa (amiibo).

This commit is contained in:
yellows8 2020-06-06 22:40:28 -04:00
parent ac468913e4
commit 9dc185ba3c
No known key found for this signature in database
GPG Key ID: 0AF90DA3F1E60E43
3 changed files with 160 additions and 0 deletions

View File

@ -135,6 +135,7 @@ extern "C" {
#include "switch/applets/album_la.h"
#include "switch/applets/friends_la.h"
#include "switch/applets/hid_la.h"
#include "switch/applets/nfp_la.h"
#include "switch/applets/pctlauth.h"
#include "switch/applets/psel.h"
#include "switch/applets/error.h"

View File

@ -0,0 +1,89 @@
/**
* @file nfp_la.h
* @brief Wrapper for using the cabinet (amiibo) LibraryApplet.
* @author yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../services/nfc.h"
/// Values for NfpLaStartParamForAmiiboSettings::type.
typedef enum {
NfpLaStartParamTypeForAmiiboSettings_NicknameAndOwnerSettings = 0, ///< NicknameAndOwnerSettings
NfpLaStartParamTypeForAmiiboSettings_GameDataEraser = 1, ///< GameDataEraser
NfpLaStartParamTypeForAmiiboSettings_Restorer = 2, ///< Restorer
NfpLaStartParamTypeForAmiiboSettings_Formatter = 3, ///< Formatter
} NfpLaStartParamTypeForAmiiboSettings;
/// AmiiboSettingsStartParam
typedef struct {
u8 unk_x0[0x8]; ///< Unknown
u8 unk_x8[0x20]; ///< Unknown
u8 unk_x28; ///< Unknown
} NfpLaAmiiboSettingsStartParam;
/// StartParamForAmiiboSettings
typedef struct {
u8 unk_x0; ///< Unknown
u8 type; ///< \ref NfpLaStartParamTypeForAmiiboSettings
u8 flags; ///< Flags
u8 unk_x3; ///< NfpLaAmiiboSettingsStartParam::unk_x28
u8 unk_x4[0x8]; ///< NfpLaAmiiboSettingsStartParam::unk_x0
NfpTagInfo tag_info; ///< \ref NfpTagInfo, only enabled when flags bit1 is set.
NfpRegisterInfo register_info; ///< \ref NfpRegisterInfo, only enabled when flags bit2 is set.
u8 unk_x164[0x20]; ///< NfpLaAmiiboSettingsStartParam::unk_x8
u8 unk_x184[0x24]; ///< Unknown
} NfpLaStartParamForAmiiboSettings;
/// ReturnValueForAmiiboSettings
typedef struct {
u8 flags; ///< 0 = error, non-zero = success.
u8 pad[3]; ///< Padding
NfcDeviceHandle handle; ///< \ref NfcDeviceHandle
NfpTagInfo tag_info; ///< \ref NfpTagInfo
NfpRegisterInfo register_info; ///< \ref NfpRegisterInfo, only available when flags bit2 is set.
u8 unk_x164[0x24]; ///< Unknown
} NfpLaReturnValueForAmiiboSettings;
/**
* @brief Launches the applet for NicknameAndOwnerSettings.
* @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time.
* @param[in] in_param \ref NfpLaAmiiboSettingsStartParam
* @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo.
* @param[in] in_reg_info \ref NfpRegisterInfo. Optional, can be NULL. If specified, this sets the \ref NfpRegisterInfo which will be used for writing, with an option for the user to change it.
* @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL.
* @param[out] handle \ref NfcDeviceHandle
* @param[out] reg_info_flag Flag indicating whether the data for out_reg_info is set. Optional, can be NULL.
* @param[out] out_reg_info \ref NfpRegisterInfo, see reg_info_flag. Optional, can be NULL.
*/
Result nfpLaStartNicknameAndOwnerSettings(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, const NfpRegisterInfo *in_reg_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle, bool *reg_info_flag, NfpRegisterInfo *out_reg_info);
/**
* @brief Launches the applet for GameDataEraser.
* @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time.
* @param[in] in_param \ref NfpLaAmiiboSettingsStartParam
* @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo.
* @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL.
* @param[out] handle \ref NfcDeviceHandle
*/
Result nfpLaStartGameDataEraser(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle);
/**
* @brief Launches the applet for Restorer.
* @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time.
* @param[in] in_param \ref NfpLaAmiiboSettingsStartParam
* @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo.
* @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL.
* @param[out] handle \ref NfcDeviceHandle
*/
Result nfpLaStartRestorer(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle);
/**
* @brief Launches the applet for Formatter.
* @param[in] in_param \ref NfpLaAmiiboSettingsStartParam
* @param[out] out_tag_info \ref NfpTagInfo
* @param[out] handle \ref NfcDeviceHandle
*/
Result nfpLaStartFormatter(const NfpLaAmiiboSettingsStartParam *in_param, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle);

View File

@ -0,0 +1,70 @@
#include <string.h>
#include "libapplet_internal.h"
#include "applets/nfp_la.h"
static Result _nfpLaShow(const NfpLaStartParamForAmiiboSettings *param, NfpLaReturnValueForAmiiboSettings *reply) {
Result rc=0;
size_t out_reply_size=0;
u32 ver=1;
LibAppletArgs commonargs;
libappletArgsCreate(&commonargs, ver);
rc = libappletLaunch(AppletId_cabinet, &commonargs, param, sizeof(*param), reply, sizeof(*reply), &out_reply_size);
if (R_SUCCEEDED(rc)) { // sdknso doesn't validate out_reply_size.
if (!reply->flags) rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
}
else
reply->flags = 0;
return rc;
}
static Result _nfpLaStartSettings(NfpLaStartParamTypeForAmiiboSettings type, const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, const NfpRegisterInfo *in_reg_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle, bool *reg_info_flag, NfpRegisterInfo *out_reg_info) {
Result rc=0;
NfpLaStartParamForAmiiboSettings param={0};
NfpLaReturnValueForAmiiboSettings reply={0};
param.type = type;
param.flags = 0x1;
if (in_tag_info) param.flags |= BIT(1);
if (in_reg_info) param.flags |= BIT(2);
param.unk_x3 = in_param->unk_x28;
memcpy(param.unk_x4, in_param->unk_x0, sizeof(in_param->unk_x0));
if (in_tag_info) memcpy(&param.tag_info, in_tag_info, sizeof(NfpTagInfo));
if (in_reg_info) memcpy(&param.register_info, in_reg_info, sizeof(NfpRegisterInfo));
memcpy(param.unk_x164, in_param->unk_x8, sizeof(in_param->unk_x8));
rc = _nfpLaShow(&param, &reply);
if (R_SUCCEEDED(rc)) {
if (out_tag_info) memcpy(out_tag_info, &reply.tag_info, sizeof(NfpTagInfo));
*handle = reply.handle;
if (reg_info_flag || out_reg_info) {
bool tmpflag = (reply.flags & BIT(2)) != 0;
if (reg_info_flag) *reg_info_flag = tmpflag;
if (tmpflag && out_reg_info) memcpy(out_reg_info, &reply.register_info, sizeof(NfpRegisterInfo));
}
}
return rc;
}
Result nfpLaStartNicknameAndOwnerSettings(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, const NfpRegisterInfo *in_reg_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle, bool *reg_info_flag, NfpRegisterInfo *out_reg_info) {
return _nfpLaStartSettings(NfpLaStartParamTypeForAmiiboSettings_NicknameAndOwnerSettings, in_param, in_tag_info, in_reg_info, out_tag_info, handle, reg_info_flag, out_reg_info);
}
Result nfpLaStartGameDataEraser(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle) {
return _nfpLaStartSettings(NfpLaStartParamTypeForAmiiboSettings_GameDataEraser, in_param, in_tag_info, NULL, out_tag_info, handle, NULL, NULL);
}
Result nfpLaStartRestorer(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle) {
return _nfpLaStartSettings(NfpLaStartParamTypeForAmiiboSettings_Restorer, in_param, in_tag_info, NULL, out_tag_info, handle, NULL, NULL);
}
Result nfpLaStartFormatter(const NfpLaAmiiboSettingsStartParam *in_param, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle) {
return _nfpLaStartSettings(NfpLaStartParamTypeForAmiiboSettings_Formatter, in_param, NULL, NULL, out_tag_info, handle, NULL, NULL);
}