service: nfc: Implement all interfaces and function calls

This commit is contained in:
german77 2023-06-11 13:21:33 -06:00 committed by fincs
parent b954aaf35d
commit 6bd6fa8907
3 changed files with 663 additions and 8 deletions

View File

@ -113,6 +113,18 @@ typedef struct {
u8 unk_x57; u8 unk_x57;
} MiiCharInfo; } MiiCharInfo;
// Original Mii colors and types before Ver3StoreData conversion
typedef struct {
u8 faceline_color;
u8 hair_color;
u8 eye_color;
u8 eyebrow_color;
u8 mouth_color;
u8 beard_color;
u8 glass_color;
u8 glass_type;
} MiiNfpStoreDataExtension;
/// Initialize mii. /// Initialize mii.
Result miiInitialize(MiiServiceType service_type); Result miiInitialize(MiiServiceType service_type);

View File

@ -28,6 +28,11 @@ typedef enum {
NfpState_Initialized = 1, NfpState_Initialized = 1,
} NfpState; } NfpState;
typedef enum {
NfcState_NonInitialized = 0,
NfcState_Initialized = 1,
} NfcState;
typedef enum { typedef enum {
NfpDeviceState_Initialized = 0, NfpDeviceState_Initialized = 0,
NfpDeviceState_SearchingForTag = 1, NfpDeviceState_SearchingForTag = 1,
@ -38,6 +43,24 @@ typedef enum {
NfpDeviceState_Finalized = 6, NfpDeviceState_Finalized = 6,
} NfpDeviceState; } NfpDeviceState;
typedef enum {
NfcDeviceState_Initialized = 0,
NfcDeviceState_SearchingForTag = 1,
NfcDeviceState_TagFound = 2,
NfcDeviceState_TagRemoved = 3,
NfcDeviceState_TagMounted = 4,
NfcDeviceState_Unavailable = 5,
NfcDeviceState_Finalized = 6,
} NfcDeviceState;
typedef enum {
NfpApplicationAreaVersion_3DS = 0,
NfpApplicationAreaVersion_WiiU = 1,
NfpApplicationAreaVersion_3DSv2 = 2,
NfpApplicationAreaVersion_Switch = 3,
NfpApplicationAreaVersion_NotSet = 0xFF,
} NfpApplicationAreaVersion;
typedef enum { typedef enum {
NfpDeviceType_Amiibo = 0, NfpDeviceType_Amiibo = 0,
} NfpDeviceType; } NfpDeviceType;
@ -48,6 +71,37 @@ typedef enum {
NfpMountTarget_All = 3, NfpMountTarget_All = 3,
} NfpMountTarget; } NfpMountTarget;
typedef enum {
NfcProtocol_None = 0,
NfcProtocol_TypeA = BIT(0), ///< ISO14443A
NfcProtocol_TypeB = BIT(1), ///< ISO14443B
NfcProtocol_TypeF = BIT(2), ///< Sony FeliCa
NfcProtocol_All = 0xFFFFFFFF,
} NfcProtocol;
typedef enum {
NfcTagType_None = 0,
NfcTagType_Type1 = BIT(0), ///< ISO14443A RW. Topaz
NfcTagType_Type2 = BIT(1), ///< ISO14443A RW. Ultralight, NTAGX, ST25TN
NfcTagType_Type3 = BIT(2), ///< ISO14443A RW/RO. Sony FeliCa
NfcTagType_Type4A = BIT(3), ///< ISO14443A RW/RO. DESFire
NfcTagType_Type4B = BIT(4), ///< ISO14443B RW/RO. DESFire
NfcTagType_Type5 = BIT(5), ///< ISO15693 RW/RO. SLI, SLIX, ST25TV
NfcTagType_Mifare = BIT(6), ///< Mifare clasic. Skylanders
NfcTagType_All = 0xFFFFFFFF,
} NfcTagType;
typedef enum {
NfcMifareCommand_Read = 0x30,
NfcMifareCommand_AuthA = 0x60,
NfcMifareCommand_AuthB = 0x61,
NfcMifareCommand_Write = 0xA0,
NfcMifareCommand_Transfer = 0xB0,
NfcMifareCommand_Decrement = 0xC0,
NfcMifareCommand_Increment = 0xC1,
NfcMifareCommand_Store = 0xC2,
} NfcMifareCommand;
typedef struct { typedef struct {
u8 uuid[10]; u8 uuid[10];
u8 uuid_length; u8 uuid_length;
@ -57,6 +111,15 @@ typedef struct {
u8 reserved2[0x30]; u8 reserved2[0x30];
} PACKED NfpTagInfo; } PACKED NfpTagInfo;
typedef struct {
u8 uuid[10];
u8 uuid_length;
u8 reserved1[0x15];
u32 protocol;
u32 tag_type;
u8 reserved2[0x30];
} PACKED NfcTagInfo;
typedef struct { typedef struct {
u16 last_write_year; u16 last_write_year;
u8 last_write_month; u8 last_write_month;
@ -77,10 +140,94 @@ typedef struct {
u16 first_write_year; u16 first_write_year;
u8 first_write_month; u8 first_write_month;
u8 first_write_day; u8 first_write_day;
char amiibo_name[10+1]; ///< utf-8, null-terminated char amiibo_name[(10*4)+1]; ///< utf-8, null-terminated
u8 reserved[0x99]; u8 font_region;
u8 reserved[0x7A];
} PACKED NfpRegisterInfo; } PACKED NfpRegisterInfo;
typedef struct {
u8 mii_store_data[0x44];
u16 first_write_year;
u8 first_write_month;
u8 first_write_day;
char amiibo_name[(10*4)+1]; ///< utf-8, null-terminated
u8 font_region;
u8 reserved[0x8E];
} PACKED NfpRegisterInfoPrivate;
typedef struct {
u64 application_id;
u32 application_area_id;
u16 crc_change_counter;
u8 flags;
u8 tag_type;
u8 application_area_version;
u8 reserved[0x2F];
} PACKED NfpAdminInfo;
typedef struct {
u8 magic;
u8 reserved1[0x1];
u8 write_counter;
u8 reserved2[0x1];
u32 settings_crc;
u8 reserved3[0x38];
u16 last_write_year;
u8 last_write_month;
u8 last_write_day;
u16 application_write_counter;
u16 version;
u32 application_area_size;
u8 reserved4[0x34];
MiiCharInfo mii;
MiiNfpStoreDataExtension mii_store_data_extension;
u16 first_write_year;
u8 first_write_month;
u8 first_write_day;
u16 amiibo_name[10+1]; ///< utf-16, null-terminated
u8 settings_flag; ///< bit4 = amiibo was initialized in console settings, bit5 = has application area
u8 unknown1; ///< Normally zero
u32 register_info_crc;
u32 unknown2[0x5]; ///< Normally zero
u8 reserved5[0x64];
u64 application_id;
u32 access_id;
u16 settings_crc_counter;
u8 font_region;
u8 tag_type;
u8 console_type;
u8 application_id_byte; ///< (Original Program ID >> 0x24) & 0xF byte (Program ID has this byte swapped with console type)
u8 reserved6[0x2E];
u8 application_area[0xD8];
} PACKED NfpData;
typedef struct {
u8 mifare_command;
u8 unknown; ///< Usually 1
u8 reserved1[0x6];
u8 sector_key[0x6];
u8 reserved2[0x2];
} PACKED NfcSectorKey;
typedef struct {
u8 sector_number;
u8 reserved[0x7];
NfcSectorKey sector_key;
} PACKED NfcMifareReadBlockParameter;
typedef struct {
u8 data[0x10];
u8 sector_number;
u8 reserved[0x7];
} PACKED NfcMifareReadBlockData;
typedef struct {
u8 data[0x10];
u8 sector_number;
u8 reserved[0x7];
NfcSectorKey sector_key;
} NfcMifareWriteBlockParameter;
typedef struct { typedef struct {
u64 version; u64 version;
u64 reserved[3]; u64 reserved[3];
@ -103,6 +250,12 @@ Result nfcInitialize(NfcServiceType service_type);
/// Exit nfc:*. /// Exit nfc:*.
void nfcExit(void); void nfcExit(void);
/// Initialize nfc:mf:u.
Result nfcMfInitialize();
/// Exit nfc:mf:u.
void nfcMfExit(void);
/// Gets the Service object for the actual nfp:* service session. /// Gets the Service object for the actual nfp:* service session.
Service* nfpGetServiceSession(void); Service* nfpGetServiceSession(void);
@ -115,17 +268,34 @@ Service* nfcGetServiceSession(void);
/// Gets the Service object for the interface from nfc:*. /// Gets the Service object for the interface from nfc:*.
Service* nfcGetServiceSession_Interface(void); Service* nfcGetServiceSession_Interface(void);
/// Gets the Service object for the actual nfc:mf:u service session.
Service* nfcMfGetServiceSession(void);
/// Gets the Service object for the interface from nfc:mf:u.
Service* nfcMfGetServiceSession_Interface(void);
Result nfpListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count); Result nfpListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count);
Result nfpStartDetection(const NfcDeviceHandle *handle); Result nfpStartDetection(const NfcDeviceHandle *handle);
Result nfpStopDetection(const NfcDeviceHandle *handle); Result nfpStopDetection(const NfcDeviceHandle *handle);
Result nfpMount(const NfcDeviceHandle *handle, NfpDeviceType device_type, NfpMountTarget mount_target); Result nfpMount(const NfcDeviceHandle *handle, NfpDeviceType device_type, NfpMountTarget mount_target);
Result nfpUnmount(const NfcDeviceHandle *handle); Result nfpUnmount(const NfcDeviceHandle *handle);
/// Only available with [4.0.0+].
Result nfcListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count);
/// Only available with [4.0.0+].
Result nfcStartDetection(const NfcDeviceHandle *handle, NfcProtocol protocol);
/// Only available with [4.0.0+].
Result nfcStopDetection(const NfcDeviceHandle *handle);
Result nfcMfListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count);
Result nfcMfStartDetection(const NfcDeviceHandle *handle);
Result nfcMfStopDetection(const NfcDeviceHandle *handle);
/// Not available with ::NfpServiceType_System. /// Not available with ::NfpServiceType_System.
Result nfpOpenApplicationArea(const NfcDeviceHandle *handle, u32 app_id); Result nfpOpenApplicationArea(const NfcDeviceHandle *handle, u32 app_id);
/// Not available with ::NfpServiceType_System. /// Not available with ::NfpServiceType_System.
Result nfpGetApplicationArea(const NfcDeviceHandle *handle, void* buf, size_t buf_size); Result nfpGetApplicationArea(const NfcDeviceHandle *handle, void* buf, size_t buf_size, u32 *out_size);
/// Not available with ::NfpServiceType_System. /// Not available with ::NfpServiceType_System.
Result nfpSetApplicationArea(const NfcDeviceHandle *handle, const void* buf, size_t buf_size); Result nfpSetApplicationArea(const NfcDeviceHandle *handle, const void* buf, size_t buf_size);
@ -135,27 +305,112 @@ Result nfpRestore(const NfcDeviceHandle *handle);
/// Not available with ::NfpServiceType_System. /// Not available with ::NfpServiceType_System.
Result nfpCreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size); Result nfpCreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size);
/// Not available with ::NfpServiceType_System.
/// Only available with [3.0.0+].
Result nfpRecreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size);
/// Not available with ::NfpServiceType_System.
Result nfpGetApplicationAreaSize(const NfcDeviceHandle *handle, u32 *out_app_area_size);
/// Not available with ::NfpServiceType_User.
Result nfpDeleteApplicationArea(const NfcDeviceHandle *handle);
/// Not available with ::NfpServiceType_User.
Result nfpExistsApplicationArea(const NfcDeviceHandle *handle, bool *out);
Result nfpGetTagInfo(const NfcDeviceHandle *handle, NfpTagInfo *out); Result nfpGetTagInfo(const NfcDeviceHandle *handle, NfpTagInfo *out);
Result nfpGetRegisterInfo(const NfcDeviceHandle *handle, NfpRegisterInfo *out); Result nfpGetRegisterInfo(const NfcDeviceHandle *handle, NfpRegisterInfo *out);
Result nfpGetCommonInfo(const NfcDeviceHandle *handle, NfpCommonInfo *out); Result nfpGetCommonInfo(const NfcDeviceHandle *handle, NfpCommonInfo *out);
Result nfpGetModelInfo(const NfcDeviceHandle *handle, NfpModelInfo *out); Result nfpGetModelInfo(const NfcDeviceHandle *handle, NfpModelInfo *out);
/// Not available with ::NfpServiceType_User.
Result nfpGetAdminInfo(const NfcDeviceHandle *handle, NfpAdminInfo *out);
/// Only available with [4.0.0+].
Result nfcGetTagInfo(const NfcDeviceHandle *handle, NfcTagInfo *out);
Result nfcMfGetTagInfo(const NfcDeviceHandle *handle, NfcTagInfo *out);
/// Returned event will have autoclear off. /// Returned event will have autoclear off.
Result nfpAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event); Result nfpAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event);
/// Returned event will have autoclear off. /// Returned event will have autoclear off.
Result nfpAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event); Result nfpAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event);
/// Returned event will have autoclear off.
/// Only available with [4.0.0+].
Result nfcAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event);
/// Returned event will have autoclear off.
/// Only available with [4.0.0+].
Result nfcAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event);
/// Returned event will have autoclear off.
Result nfcMfAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event);
/// Returned event will have autoclear off.
Result nfcMfAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event);
Result nfpGetState(NfpState *out); Result nfpGetState(NfpState *out);
Result nfpGetDeviceState(const NfcDeviceHandle *handle, NfpDeviceState *out); Result nfpGetDeviceState(const NfcDeviceHandle *handle, NfpDeviceState *out);
Result nfpGetNpadId(const NfcDeviceHandle *handle, u32 *out); Result nfpGetNpadId(const NfcDeviceHandle *handle, u32 *out);
/// Only available with [4.0.0+].
Result nfcGetState(NfcState *out);
/// Only available with [4.0.0+].
Result nfcGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out);
/// Only available with [4.0.0+].
Result nfcGetNpadId(const NfcDeviceHandle *handle, u32 *out);
Result nfcMfGetState(NfcState *out);
Result nfcMfGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out);
Result nfcMfGetNpadId(const NfcDeviceHandle *handle, u32 *out);
/// Returned event will have autoclear on. /// Returned event will have autoclear on.
/// Only available with [3.0.0+]. /// Only available with [3.0.0+].
Result nfpAttachAvailabilityChangeEvent(Event *out_event); Result nfpAttachAvailabilityChangeEvent(Event *out_event);
/// Returned event will have autoclear on.
/// Only available with [4.0.0+].
Result nfcAttachAvailabilityChangeEvent(Event *out_event);
/// Returned event will have autoclear on.
Result nfcMfAttachAvailabilityChangeEvent(Event *out_event);
/// Not available with ::NfpServiceType_User.
Result nfpFormat(const NfcDeviceHandle *handle);
/// Not available with ::NfpServiceType_User.
Result nfpGetRegisterInfoPrivate(const NfcDeviceHandle *handle, NfpRegisterInfoPrivate *out);
/// Not available with ::NfpServiceType_User.
Result nfpSetRegisterInfoPrivate(const NfcDeviceHandle *handle, const NfpRegisterInfoPrivate *register_info_private);
/// Not available with ::NfpServiceType_User.
Result nfpDeleteRegisterInfo(const NfcDeviceHandle *handle);
/// Only available with ::NfpServiceType_Debug.
Result nfpGetAll(const NfcDeviceHandle *handle, NfpData *out);
/// Only available with ::NfpServiceType_Debug.
Result nfpSetAll(const NfcDeviceHandle *handle, const NfpData *nfp_data);
/// Only available with ::NfpServiceType_Debug.
Result nfpFlushDebug(const NfcDeviceHandle *handle);
/// Only available with ::NfpServiceType_Debug.
Result nfpBreakTag(const NfcDeviceHandle *handle, u32 break_type);
/// Only available with ::NfpServiceType_Debug.
Result nfpReadBackupData(const NfcDeviceHandle *handle, void* out_buf, size_t buf_size, u32 *out_size);
/// Only available with ::NfpServiceType_Debug.
Result nfpWriteBackupData(const NfcDeviceHandle *handle, const void* buf, size_t buf_size);
/// Only available with ::NfpServiceType_Debug.
Result nfpWriteNtf(const NfcDeviceHandle *handle, u32 write_type, const void* buf, size_t buf_size);
/// This uses nfc:*. /// This uses nfc:*.
Result nfcIsNfcEnabled(bool *out); Result nfcIsNfcEnabled(bool *out);
/// Only available with [4.0.0+].
Result nfcReadMifare(const NfcDeviceHandle *handle, NfcMifareReadBlockData *out_block_data, const NfcMifareReadBlockParameter *read_block_parameter, s32 count);
/// Only available with [4.0.0+].
Result nfcWriteMifare(const NfcDeviceHandle *handle, const NfcMifareWriteBlockParameter *write_block_parameter, s32 count);
Result nfcMfReadMifare(const NfcDeviceHandle *handle, NfcMifareReadBlockData *out_block_data, const NfcMifareReadBlockParameter *read_block_parameter, s32 count);
Result nfcMfWriteMifare(const NfcDeviceHandle *handle, const NfcMifareWriteBlockParameter *write_block_parameter, s32 count);
/// Only available with [4.0.0+].
Result nfcSendCommandByPassThrough(const NfcDeviceHandle *handle, u64 timeout, const void* cmd_buf, size_t cmd_buf_size, void* reply_buf, size_t reply_buf_size, u64 *out_size); Result nfcSendCommandByPassThrough(const NfcDeviceHandle *handle, u64 timeout, const void* cmd_buf, size_t cmd_buf_size, void* reply_buf, size_t reply_buf_size, u64 *out_size);
/// Only available with [4.0.0+].
Result nfcKeepPassThroughSession(const NfcDeviceHandle *handle); Result nfcKeepPassThroughSession(const NfcDeviceHandle *handle);
/// Only available with [4.0.0+].
Result nfcReleasePassThroughSession(const NfcDeviceHandle *handle); Result nfcReleasePassThroughSession(const NfcDeviceHandle *handle);

View File

@ -10,6 +10,8 @@ static Service g_nfpSrv;
static Service g_nfpInterface; static Service g_nfpInterface;
static Service g_nfcSrv; static Service g_nfcSrv;
static Service g_nfcInterface; static Service g_nfcInterface;
static Service g_nfcMfSrv;
static Service g_nfcMfInterface;
static const NfcRequiredMcuVersionData g_nfcVersionData[2] = { static const NfcRequiredMcuVersionData g_nfcVersionData[2] = {
{ {
@ -29,6 +31,7 @@ static Result _nfcCmdNoIO(Service* srv, u32 cmd_id);
static Result _nfcCmdInDevhandleNoOut(Service* srv, const NfcDeviceHandle *handle, u32 cmd_id); static Result _nfcCmdInDevhandleNoOut(Service* srv, const NfcDeviceHandle *handle, u32 cmd_id);
static Result _nfcCmdInDevhandleOutEvent(Service* srv, const NfcDeviceHandle *handle, Event *out_event, u32 cmd_id); static Result _nfcCmdInDevhandleOutEvent(Service* srv, const NfcDeviceHandle *handle, Event *out_event, u32 cmd_id);
static Result _nfcCmdInDevhandleOutBuffer(Service* srv, const NfcDeviceHandle *handle, void* buf, size_t buf_size, u32 cmd_id); static Result _nfcCmdInDevhandleOutBuffer(Service* srv, const NfcDeviceHandle *handle, void* buf, size_t buf_size, u32 cmd_id);
static Result _nfcCmdInDevhandleInBufferNoOut(Service* srv, const NfcDeviceHandle *handle, const void* buf, size_t buf_size, u32 cmd_id);
NX_GENERATE_SERVICE_GUARD_PARAMS(nfp, (NfpServiceType service_type), (service_type)); NX_GENERATE_SERVICE_GUARD_PARAMS(nfp, (NfpServiceType service_type), (service_type));
@ -99,6 +102,29 @@ void _nfcCleanup(void) {
serviceClose(&g_nfcSrv); serviceClose(&g_nfcSrv);
} }
Result _nfcMfInitialize() {
Result rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
rc = smGetService(&g_nfcMfSrv, "nfc:mf:u");
if (R_SUCCEEDED(rc))
rc = serviceConvertToDomain(&g_nfcMfSrv);
if (R_SUCCEEDED(rc))
rc = _nfcCreateInterface(&g_nfcMfSrv, &g_nfcMfInterface);
if (R_SUCCEEDED(rc))
rc = _nfcInterfaceInitialize(&g_nfcMfInterface, g_nfcVersionData, 2, 0);
return rc;
}
void _nfcMfCleanup(void) {
_nfcCmdNoIO(&g_nfcMfInterface, 1); // Finalize
serviceClose(&g_nfcMfInterface);
serviceClose(&g_nfcMfSrv);
}
Service* nfpGetServiceSession(void) { Service* nfpGetServiceSession(void) {
return &g_nfpSrv; return &g_nfpSrv;
} }
@ -108,11 +134,19 @@ Service* nfpGetServiceSession_Interface(void) {
} }
Service* nfcGetServiceSession(void) { Service* nfcGetServiceSession(void) {
return &g_nfpSrv; return &g_nfcSrv;
} }
Service* nfcGetServiceSession_Interface(void) { Service* nfcGetServiceSession_Interface(void) {
return &g_nfpInterface; return &g_nfcInterface;
}
Service* nfcMfGetServiceSession(void) {
return &g_nfcMfSrv;
}
Service* nfcMfGetServiceSession_Interface(void) {
return &g_nfcMfInterface;
} }
static Result _nfcCreateInterface(Service* srv, Service* srv_out) { static Result _nfcCreateInterface(Service* srv, Service* srv_out) {
@ -191,6 +225,14 @@ static Result _nfcCmdInDevhandleOutBuffer(Service* srv, const NfcDeviceHandle *h
); );
} }
static Result _nfcCmdInDevhandleInBufferNoOut(Service* srv, const NfcDeviceHandle *handle, const void* buf, size_t buf_size, u32 cmd_id) {
serviceAssumeDomain(srv);
return serviceDispatchIn(srv, cmd_id, *handle,
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { buf, buf_size } },
);
}
static Result _nfcInterfaceInitialize(Service* srv, const NfcRequiredMcuVersionData *version, s32 count, u32 cmd_id) { static Result _nfcInterfaceInitialize(Service* srv, const NfcRequiredMcuVersionData *version, s32 count, u32 cmd_id) {
const struct { const struct {
u64 aruid; u64 aruid;
@ -213,14 +255,61 @@ Result nfpListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count) {
); );
} }
Result nfcListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
serviceAssumeDomain(&g_nfcInterface);
return serviceDispatchOut(&g_nfcInterface, 404, *total_out,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
.buffers = { { out, count*sizeof(NfcDeviceHandle) } },
);
}
Result nfcMfListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count) {
serviceAssumeDomain(&g_nfcMfInterface);
return serviceDispatchOut(&g_nfcMfInterface, 2, *total_out,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
.buffers = { { out, count*sizeof(NfcDeviceHandle) } },
);
}
Result nfpStartDetection(const NfcDeviceHandle *handle) { Result nfpStartDetection(const NfcDeviceHandle *handle) {
return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 3); return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 3);
} }
Result nfcStartDetection(const NfcDeviceHandle *handle, NfcProtocol protocol) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
NfcDeviceHandle handle;
NfcProtocol protocol;
} in = { *handle, protocol };
serviceAssumeDomain(&g_nfcInterface);
return serviceDispatchIn(&g_nfcInterface, 408, in);
}
Result nfcMfStartDetection(const NfcDeviceHandle *handle) {
return _nfcCmdInDevhandleNoOut(&g_nfcMfInterface, handle, 3);
}
Result nfpStopDetection(const NfcDeviceHandle *handle) { Result nfpStopDetection(const NfcDeviceHandle *handle) {
return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 4); return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 4);
} }
Result nfcStopDetection(const NfcDeviceHandle *handle) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 409);
}
Result nfcMfStopDetection(const NfcDeviceHandle *handle) {
return _nfcCmdInDevhandleNoOut(&g_nfcMfInterface, handle, 4);
}
Result nfpMount(const NfcDeviceHandle *handle, NfpDeviceType device_type, NfpMountTarget mount_target) { Result nfpMount(const NfcDeviceHandle *handle, NfpDeviceType device_type, NfpMountTarget mount_target) {
const struct { const struct {
NfcDeviceHandle handle; NfcDeviceHandle handle;
@ -249,12 +338,12 @@ Result nfpOpenApplicationArea(const NfcDeviceHandle *handle, u32 app_id) {
return serviceDispatchIn(&g_nfpInterface, 7, in); return serviceDispatchIn(&g_nfpInterface, 7, in);
} }
Result nfpGetApplicationArea(const NfcDeviceHandle *handle, void* buf, size_t buf_size) { Result nfpGetApplicationArea(const NfcDeviceHandle *handle, void* buf, size_t buf_size, u32 *out_size) {
if (g_nfpServiceType == NfpServiceType_System) if (g_nfpServiceType == NfpServiceType_System)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
serviceAssumeDomain(&g_nfpInterface); serviceAssumeDomain(&g_nfpInterface);
return serviceDispatchIn(&g_nfpInterface, 8, *handle, return serviceDispatchInOut(&g_nfpInterface, 8, *handle, *out_size,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { buf, buf_size } }, .buffers = { { buf, buf_size } },
); );
@ -295,10 +384,64 @@ Result nfpCreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const
); );
} }
Result nfpRecreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size) {
if (g_nfpServiceType == NfpServiceType_System)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
NfcDeviceHandle handle;
u32 app_id;
} in = { *handle, app_id };
serviceAssumeDomain(&g_nfpInterface);
return serviceDispatchIn(&g_nfpInterface, 24, in,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = { { buf, buf_size } },
);
}
Result nfpGetApplicationAreaSize(const NfcDeviceHandle *handle, u32 *out_app_area_size) {
if (g_nfpServiceType == NfpServiceType_System)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleOutU32(&g_nfpInterface, handle, out_app_area_size, 22);
}
Result nfpDeleteApplicationArea(const NfcDeviceHandle *handle) {
if (g_nfpServiceType == NfpServiceType_User)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 105);
}
Result nfpExistsApplicationArea(const NfcDeviceHandle *handle, bool *out) {
if (g_nfpServiceType == NfpServiceType_User)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
u32 tmp=0;
Result rc = _nfcCmdInDevhandleOutU32(&g_nfpInterface, handle, &tmp, 106);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result nfpGetTagInfo(const NfcDeviceHandle *handle, NfpTagInfo *out) { Result nfpGetTagInfo(const NfcDeviceHandle *handle, NfpTagInfo *out) {
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpTagInfo), 13); return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpTagInfo), 13);
} }
Result nfcGetTagInfo(const NfcDeviceHandle *handle, NfcTagInfo *out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nfcCmdInDevhandleOutBuffer(&g_nfcInterface, handle, out, sizeof(NfcTagInfo), 410);
}
Result nfcMfGetTagInfo(const NfcDeviceHandle *handle, NfcTagInfo *out) {
return _nfcCmdInDevhandleOutBuffer(&g_nfcMfInterface, handle, out, sizeof(NfcTagInfo), 7);
}
Result nfpGetRegisterInfo(const NfcDeviceHandle *handle, NfpRegisterInfo *out) { Result nfpGetRegisterInfo(const NfcDeviceHandle *handle, NfpRegisterInfo *out) {
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpRegisterInfo), 14); return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpRegisterInfo), 14);
} }
@ -311,14 +454,43 @@ Result nfpGetModelInfo(const NfcDeviceHandle *handle, NfpModelInfo *out) {
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpModelInfo), 16); return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpModelInfo), 16);
} }
Result nfpGetAdminInfo(const NfcDeviceHandle *handle, NfpAdminInfo *out) {
if (g_nfpServiceType == NfpServiceType_User)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpAdminInfo), 101);
}
Result nfpAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event) { Result nfpAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event) {
return _nfcCmdInDevhandleOutEvent(&g_nfpInterface, handle, out_event, 17); return _nfcCmdInDevhandleOutEvent(&g_nfpInterface, handle, out_event, 17);
} }
Result nfcAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nfcCmdInDevhandleOutEvent(&g_nfcInterface, handle, out_event, 411);
}
Result nfcMfAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event) {
return _nfcCmdInDevhandleOutEvent(&g_nfcMfInterface, handle, out_event, 8);
}
Result nfpAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event) { Result nfpAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event) {
return _nfcCmdInDevhandleOutEvent(&g_nfpInterface, handle, out_event, 18); return _nfcCmdInDevhandleOutEvent(&g_nfpInterface, handle, out_event, 18);
} }
Result nfcAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nfcCmdInDevhandleOutEvent(&g_nfcInterface, handle, out_event, 412);
}
Result nfcMfAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event) {
return _nfcCmdInDevhandleOutEvent(&g_nfcMfInterface, handle, out_event, 9);
}
Result nfpGetState(NfpState *out) { Result nfpGetState(NfpState *out) {
u32 tmp=0; u32 tmp=0;
Result rc = _nfcCmdNoInOutU32(&g_nfpInterface, &tmp, 19); Result rc = _nfcCmdNoInOutU32(&g_nfpInterface, &tmp, 19);
@ -326,6 +498,20 @@ Result nfpGetState(NfpState *out) {
return rc; return rc;
} }
Result nfcGetState(NfcState *out) {
u32 tmp=0;
Result rc = _nfcCmdNoInOutU32(&g_nfcInterface, &tmp, hosversionBefore(4,0,0) ? 2 : 402);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result nfcMfGetState(NfcState *out) {
u32 tmp=0;
Result rc = _nfcCmdNoInOutU32(&g_nfcMfInterface, &tmp, 10);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result nfpGetDeviceState(const NfcDeviceHandle *handle, NfpDeviceState *out) { Result nfpGetDeviceState(const NfcDeviceHandle *handle, NfpDeviceState *out) {
u32 tmp=0; u32 tmp=0;
Result rc = _nfcCmdInDevhandleOutU32(&g_nfpInterface, handle, &tmp, 20); Result rc = _nfcCmdInDevhandleOutU32(&g_nfpInterface, handle, &tmp, 20);
@ -333,10 +519,38 @@ Result nfpGetDeviceState(const NfcDeviceHandle *handle, NfpDeviceState *out) {
return rc; return rc;
} }
Result nfcGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 tmp=0;
Result rc = _nfcCmdInDevhandleOutU32(&g_nfcInterface, handle, &tmp, 405);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result nfcMfGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out) {
u32 tmp=0;
Result rc = _nfcCmdInDevhandleOutU32(&g_nfcMfInterface, handle, &tmp, 11);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result nfpGetNpadId(const NfcDeviceHandle *handle, u32 *out) { Result nfpGetNpadId(const NfcDeviceHandle *handle, u32 *out) {
return _nfcCmdInDevhandleOutU32(&g_nfpInterface, handle, out, 21); return _nfcCmdInDevhandleOutU32(&g_nfpInterface, handle, out, 21);
} }
Result nfcGetNpadId(const NfcDeviceHandle *handle, u32 *out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nfcCmdInDevhandleOutU32(&g_nfcInterface, handle, out, 406);
}
Result nfcMfGetNpadId(const NfcDeviceHandle *handle, u32 *out) {
return _nfcCmdInDevhandleOutU32(&g_nfcMfInterface, handle, out, 12);
}
Result nfpAttachAvailabilityChangeEvent(Event *out_event) { Result nfpAttachAvailabilityChangeEvent(Event *out_event) {
if (hosversionBefore(3,0,0)) if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -344,10 +558,185 @@ Result nfpAttachAvailabilityChangeEvent(Event *out_event) {
return _nfcCmdGetEvent(&g_nfpInterface, out_event, true, 23); return _nfcCmdGetEvent(&g_nfpInterface, out_event, true, 23);
} }
Result nfcAttachAvailabilityChangeEvent(Event *out_event) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nfcCmdGetEvent(&g_nfcInterface, out_event, true, 407);
}
Result nfcMfAttachAvailabilityChangeEvent(Event *out_event) {
return _nfcCmdGetEvent(&g_nfcMfInterface, out_event, true, 13);
}
Result nfcFormat(const NfcDeviceHandle *handle) {
if (g_nfpServiceType == NfpServiceType_User)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 100);
}
Result nfpGetRegisterInfoPrivate(const NfcDeviceHandle *handle, NfpRegisterInfoPrivate *out) {
if (g_nfpServiceType == NfpServiceType_User)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpRegisterInfoPrivate), 102);
}
Result nfpSetRegisterInfoPrivate(const NfcDeviceHandle *handle, const NfpRegisterInfoPrivate *register_info_private) {
if (g_nfpServiceType == NfpServiceType_User)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleInBufferNoOut(&g_nfcInterface, handle, register_info_private, sizeof(NfpRegisterInfoPrivate) , 103);
}
Result nfpDeleteRegisterInfo(const NfcDeviceHandle *handle) {
if (g_nfpServiceType == NfpServiceType_User)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 104);
}
Result nfpGetAll(const NfcDeviceHandle *handle, NfpData *out) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpData), 200);
}
Result nfpSetAll(const NfcDeviceHandle *handle, const NfpData *nfp_data) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleInBufferNoOut(&g_nfcInterface, handle, nfp_data, sizeof(NfpData) , 201);
}
Result nfpFlushDebug(const NfcDeviceHandle *handle) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 202);
}
Result nfpBreakTag(const NfcDeviceHandle *handle, u32 break_type) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
const struct {
NfcDeviceHandle handle;
u32 break_type;
} in = { *handle, break_type };
serviceAssumeDomain(&g_nfpInterface);
return serviceDispatchIn(&g_nfpInterface, 203, in);
}
Result nfpReadBackupData(const NfcDeviceHandle *handle, void* out_buf, size_t buf_size, u32 *out_size) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
serviceAssumeDomain(&g_nfpInterface);
return serviceDispatchInOut(&g_nfpInterface, 204, *handle, *out_size,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { out_buf, buf_size } },
);
}
Result nfpWriteBackupData(const NfcDeviceHandle *handle, const void* buf, size_t buf_size) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
serviceAssumeDomain(&g_nfpInterface);
return serviceDispatchIn(&g_nfpInterface, 205, *handle,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = { { buf, buf_size } },
);
}
/// Only available with ::NfpServiceType_Debug.
Result nfpWriteNtf(const NfcDeviceHandle *handle, u32 write_type, const void* buf, size_t buf_size) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
const struct {
NfcDeviceHandle handle;
u32 write_type;
} in = { *handle, write_type };
serviceAssumeDomain(&g_nfpInterface);
return serviceDispatchIn(&g_nfpInterface, 206, in,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = { { buf, buf_size } },
);
}
Result nfcIsNfcEnabled(bool *out) { Result nfcIsNfcEnabled(bool *out) {
return _nfcCmdNoInOutBool(&g_nfcInterface, out, hosversionBefore(4,0,0) ? 3 : 403); return _nfcCmdNoInOutBool(&g_nfcInterface, out, hosversionBefore(4,0,0) ? 3 : 403);
} }
Result nfcReadMifare(const NfcDeviceHandle *handle, NfcMifareReadBlockData *out_block_data, const NfcMifareReadBlockParameter *read_block_parameter, s32 count) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
serviceAssumeDomain(&g_nfcInterface);
Result rc = serviceDispatchIn(&g_nfcInterface, 1000, *handle,
.buffer_attrs = {
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
},
.buffers = {
{ out_block_data, count*sizeof(NfcMifareReadBlockData) },
{ read_block_parameter, count*sizeof(NfcMifareReadBlockParameter) },
},
);
return rc;
}
Result nfcMfReadMifare(const NfcDeviceHandle *handle, NfcMifareReadBlockData *out_block_data, const NfcMifareReadBlockParameter *read_block_parameter, s32 count) {
serviceAssumeDomain(&g_nfcMfInterface);
Result rc = serviceDispatchIn(&g_nfcMfInterface, 5, *handle,
.buffer_attrs = {
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
},
.buffers = {
{ out_block_data, count*sizeof(NfcMifareReadBlockData) },
{ read_block_parameter, count*sizeof(NfcMifareReadBlockParameter) },
},
);
return rc;
}
Result nfcWriteMifare(const NfcDeviceHandle *handle, const NfcMifareWriteBlockParameter *write_block_parameter, s32 count) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
serviceAssumeDomain(&g_nfcInterface);
Result rc = serviceDispatchIn(&g_nfcInterface, 1001, *handle,
.buffer_attrs = {
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
},
.buffers = {
{ write_block_parameter, count*sizeof(NfcMifareWriteBlockParameter) },
},
);
return rc;
}
Result nfcMfWriteMifare(const NfcDeviceHandle *handle, const NfcMifareWriteBlockParameter *write_block_parameter, s32 count) {
serviceAssumeDomain(&g_nfcMfInterface);
Result rc = serviceDispatchIn(&g_nfcMfInterface, 6, *handle,
.buffer_attrs = {
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
},
.buffers = {
{ write_block_parameter, count*sizeof(NfcMifareWriteBlockParameter) },
},
);
return rc;
}
Result nfcSendCommandByPassThrough(const NfcDeviceHandle *handle, u64 timeout, const void* cmd_buf, size_t cmd_buf_size, void* reply_buf, size_t reply_buf_size, u64 *out_size) { Result nfcSendCommandByPassThrough(const NfcDeviceHandle *handle, u64 timeout, const void* cmd_buf, size_t cmd_buf_size, void* reply_buf, size_t reply_buf_size, u64 *out_size) {
if (hosversionBefore(4,0,0)) if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -386,4 +775,3 @@ Result nfcReleasePassThroughSession(const NfcDeviceHandle *handle) {
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 1302); return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 1302);
} }