mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
780 lines
26 KiB
C
780 lines
26 KiB
C
#include "service_guard.h"
|
|
#include <string.h>
|
|
#include "runtime/hosversion.h"
|
|
#include "services/applet.h"
|
|
#include "services/nfc.h"
|
|
|
|
static NfpServiceType g_nfpServiceType;
|
|
static NfcServiceType g_nfcServiceType;
|
|
static Service g_nfpSrv;
|
|
static Service g_nfpInterface;
|
|
static Service g_nfcSrv;
|
|
static Service g_nfcInterface;
|
|
static Service g_nfcMfSrv;
|
|
static Service g_nfcMfInterface;
|
|
|
|
static const NfcRequiredMcuVersionData g_nfcVersionData[2] = {
|
|
{
|
|
.version = 0x00000001000a0003,
|
|
.reserved = {0},
|
|
},
|
|
{
|
|
.version = 0x0000000300040003,
|
|
.reserved = {0},
|
|
},
|
|
};
|
|
|
|
static Result _nfcCreateInterface(Service* srv, Service* srv_out);
|
|
static Result _nfcInterfaceInitialize(Service* srv, const NfcRequiredMcuVersionData *version, s32 count, u32 cmd_id);
|
|
|
|
static Result _nfcCmdNoIO(Service* srv, 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 _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));
|
|
|
|
Result _nfpInitialize(NfpServiceType service_type) {
|
|
Result rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
|
|
|
g_nfpServiceType = service_type;
|
|
switch (g_nfpServiceType) {
|
|
case NfpServiceType_User:
|
|
rc = smGetService(&g_nfpSrv, "nfp:user");
|
|
break;
|
|
case NfpServiceType_Debug:
|
|
rc = smGetService(&g_nfpSrv, "nfp:dbg");
|
|
break;
|
|
case NfpServiceType_System:
|
|
rc = smGetService(&g_nfpSrv, "nfp:sys");
|
|
break;
|
|
}
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
rc = serviceConvertToDomain(&g_nfpSrv);
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
rc = _nfcCreateInterface(&g_nfpSrv, &g_nfpInterface);
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
rc = _nfcInterfaceInitialize(&g_nfpInterface, g_nfcVersionData, 2, 0);
|
|
|
|
return rc;
|
|
}
|
|
|
|
void _nfpCleanup(void) {
|
|
_nfcCmdNoIO(&g_nfpInterface, 1); // Finalize
|
|
serviceClose(&g_nfpInterface);
|
|
serviceClose(&g_nfpSrv);
|
|
}
|
|
|
|
NX_GENERATE_SERVICE_GUARD_PARAMS(nfc, (NfcServiceType service_type), (service_type));
|
|
|
|
Result _nfcInitialize(NfcServiceType service_type) {
|
|
Result rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
|
|
|
g_nfcServiceType = service_type;
|
|
switch (g_nfcServiceType) {
|
|
case NfcServiceType_User:
|
|
rc = smGetService(&g_nfcSrv, "nfc:user");
|
|
break;
|
|
case NfcServiceType_System:
|
|
rc = smGetService(&g_nfcSrv, "nfc:sys");
|
|
break;
|
|
}
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
rc = serviceConvertToDomain(&g_nfcSrv);
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
rc = _nfcCreateInterface(&g_nfcSrv, &g_nfcInterface);
|
|
|
|
if (R_SUCCEEDED(rc))
|
|
rc = _nfcInterfaceInitialize(&g_nfcInterface, g_nfcVersionData, 2, hosversionBefore(4,0,0) ? 0 : 400);
|
|
|
|
return rc;
|
|
}
|
|
|
|
void _nfcCleanup(void) {
|
|
_nfcCmdNoIO(&g_nfcInterface, hosversionBefore(4,0,0) ? 1 : 401); // Finalize
|
|
serviceClose(&g_nfcInterface);
|
|
serviceClose(&g_nfcSrv);
|
|
}
|
|
|
|
NX_GENERATE_SERVICE_GUARD(nfcMf);
|
|
|
|
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) {
|
|
return &g_nfpSrv;
|
|
}
|
|
|
|
Service* nfpGetServiceSession_Interface(void) {
|
|
return &g_nfpInterface;
|
|
}
|
|
|
|
Service* nfcGetServiceSession(void) {
|
|
return &g_nfcSrv;
|
|
}
|
|
|
|
Service* nfcGetServiceSession_Interface(void) {
|
|
return &g_nfcInterface;
|
|
}
|
|
|
|
Service* nfcMfGetServiceSession(void) {
|
|
return &g_nfcMfSrv;
|
|
}
|
|
|
|
Service* nfcMfGetServiceSession_Interface(void) {
|
|
return &g_nfcMfInterface;
|
|
}
|
|
|
|
static Result _nfcCreateInterface(Service* srv, Service* srv_out) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatch(srv, 0,
|
|
.out_num_objects = 1,
|
|
.out_objects = srv_out,
|
|
);
|
|
}
|
|
|
|
static Result _nfcCmdGetHandle(Service* srv, Handle* handle_out, u32 cmd_id) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatch(srv, cmd_id,
|
|
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
|
|
.out_handles = handle_out,
|
|
);
|
|
}
|
|
|
|
static Result _nfcCmdGetEvent(Service* srv, Event* out_event, bool autoclear, u32 cmd_id) {
|
|
Handle tmp_handle = INVALID_HANDLE;
|
|
Result rc = 0;
|
|
|
|
rc = _nfcCmdGetHandle(srv, &tmp_handle, cmd_id);
|
|
if (R_SUCCEEDED(rc)) eventLoadRemote(out_event, tmp_handle, autoclear);
|
|
return rc;
|
|
}
|
|
|
|
static Result _nfcCmdNoIO(Service* srv, u32 cmd_id) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatch(srv, cmd_id);
|
|
}
|
|
|
|
static Result _nfcCmdInDevhandleNoOut(Service* srv, const NfcDeviceHandle *handle, u32 cmd_id) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatchIn(srv, cmd_id, *handle);
|
|
}
|
|
|
|
static Result _nfcCmdInDevhandleOutU32(Service* srv, const NfcDeviceHandle *handle, u32 *out, u32 cmd_id) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatchInOut(srv, cmd_id, *handle, *out);
|
|
}
|
|
|
|
static Result _nfcCmdNoInOutU32(Service* srv, u32 *out, u32 cmd_id) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatchOut(srv, cmd_id, *out);
|
|
}
|
|
|
|
static Result _nfcCmdNoInOutU8(Service* srv, u8 *out, u32 cmd_id) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatchOut(srv, cmd_id, *out);
|
|
}
|
|
|
|
static Result _nfcCmdNoInOutBool(Service* srv, bool *out, u32 cmd_id) {
|
|
u8 tmp=0;
|
|
Result rc = _nfcCmdNoInOutU8(srv, &tmp, cmd_id);
|
|
if (R_SUCCEEDED(rc) && out) *out = tmp & 1;
|
|
return rc;
|
|
}
|
|
|
|
static Result _nfcCmdInDevhandleOutEvent(Service* srv, const NfcDeviceHandle *handle, Event *out_event, u32 cmd_id) {
|
|
Handle tmp_handle = INVALID_HANDLE;
|
|
serviceAssumeDomain(srv);
|
|
Result rc = serviceDispatchIn(srv, cmd_id, *handle,
|
|
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
|
|
.out_handles = &tmp_handle,
|
|
);
|
|
if (R_SUCCEEDED(rc)) eventLoadRemote(out_event, tmp_handle, false);
|
|
return rc;
|
|
}
|
|
|
|
static Result _nfcCmdInDevhandleOutBuffer(Service* srv, const NfcDeviceHandle *handle, void* buf, size_t buf_size, u32 cmd_id) {
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatchIn(srv, cmd_id, *handle,
|
|
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
|
.buffers = { { buf, buf_size } },
|
|
);
|
|
}
|
|
|
|
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) {
|
|
const struct {
|
|
u64 aruid;
|
|
u64 zero;
|
|
} in = { appletGetAppletResourceUserId(), 0 };
|
|
|
|
serviceAssumeDomain(srv);
|
|
return serviceDispatchIn(srv, cmd_id, in,
|
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
|
.buffers = { { version, count*sizeof(NfcRequiredMcuVersionData) } },
|
|
.in_send_pid = true,
|
|
);
|
|
}
|
|
|
|
Result nfpListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count) {
|
|
serviceAssumeDomain(&g_nfpInterface);
|
|
return serviceDispatchOut(&g_nfpInterface, 2, *total_out,
|
|
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
|
.buffers = { { out, count*sizeof(NfcDeviceHandle) } },
|
|
);
|
|
}
|
|
|
|
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) {
|
|
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) {
|
|
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) {
|
|
const struct {
|
|
NfcDeviceHandle handle;
|
|
u32 device_type;
|
|
u32 mount_target;
|
|
} in = { *handle, device_type, mount_target };
|
|
|
|
serviceAssumeDomain(&g_nfpInterface);
|
|
return serviceDispatchIn(&g_nfpInterface, 5, in);
|
|
}
|
|
|
|
Result nfpUnmount(const NfcDeviceHandle *handle) {
|
|
return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 6);
|
|
}
|
|
|
|
Result nfpOpenApplicationArea(const NfcDeviceHandle *handle, u32 app_id) {
|
|
if (g_nfpServiceType == NfpServiceType_System)
|
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
|
|
|
const struct {
|
|
NfcDeviceHandle handle;
|
|
u32 app_id;
|
|
} in = { *handle, app_id };
|
|
|
|
serviceAssumeDomain(&g_nfpInterface);
|
|
return serviceDispatchIn(&g_nfpInterface, 7, in);
|
|
}
|
|
|
|
Result nfpGetApplicationArea(const NfcDeviceHandle *handle, void* buf, size_t buf_size, u32 *out_size) {
|
|
if (g_nfpServiceType == NfpServiceType_System)
|
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
|
|
|
serviceAssumeDomain(&g_nfpInterface);
|
|
return serviceDispatchInOut(&g_nfpInterface, 8, *handle, *out_size,
|
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
|
.buffers = { { buf, buf_size } },
|
|
);
|
|
}
|
|
|
|
Result nfpSetApplicationArea(const NfcDeviceHandle *handle, const void* buf, size_t buf_size) {
|
|
if (g_nfpServiceType == NfpServiceType_System)
|
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
|
|
|
serviceAssumeDomain(&g_nfpInterface);
|
|
return serviceDispatchIn(&g_nfpInterface, 9, *handle,
|
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
|
.buffers = { { buf, buf_size } },
|
|
);
|
|
}
|
|
|
|
Result nfpFlush(const NfcDeviceHandle *handle) {
|
|
return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 10);
|
|
}
|
|
|
|
Result nfpRestore(const NfcDeviceHandle *handle) {
|
|
return _nfcCmdInDevhandleNoOut(&g_nfpInterface, handle, 11);
|
|
}
|
|
|
|
Result nfpCreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size) {
|
|
if (g_nfpServiceType == NfpServiceType_System)
|
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
|
|
|
const struct {
|
|
NfcDeviceHandle handle;
|
|
u32 app_id;
|
|
} in = { *handle, app_id };
|
|
|
|
serviceAssumeDomain(&g_nfpInterface);
|
|
return serviceDispatchIn(&g_nfpInterface, 12, in,
|
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
|
.buffers = { { buf, buf_size } },
|
|
);
|
|
}
|
|
|
|
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) {
|
|
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) {
|
|
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpRegisterInfo), 14);
|
|
}
|
|
|
|
Result nfpGetCommonInfo(const NfcDeviceHandle *handle, NfpCommonInfo *out) {
|
|
return _nfcCmdInDevhandleOutBuffer(&g_nfpInterface, handle, out, sizeof(NfpCommonInfo), 15);
|
|
}
|
|
|
|
Result nfpGetModelInfo(const NfcDeviceHandle *handle, NfpModelInfo *out) {
|
|
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) {
|
|
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) {
|
|
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) {
|
|
u32 tmp=0;
|
|
Result rc = _nfcCmdNoInOutU32(&g_nfpInterface, &tmp, 19);
|
|
if (R_SUCCEEDED(rc) && out) *out = tmp;
|
|
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) {
|
|
u32 tmp=0;
|
|
Result rc = _nfcCmdInDevhandleOutU32(&g_nfpInterface, handle, &tmp, 20);
|
|
if (R_SUCCEEDED(rc) && out) *out = tmp;
|
|
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) {
|
|
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) {
|
|
if (hosversionBefore(3,0,0))
|
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
|
|
|
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) {
|
|
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) {
|
|
if (hosversionBefore(4,0,0))
|
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
|
|
|
const struct {
|
|
NfcDeviceHandle handle;
|
|
u64 timeout;
|
|
} in = { *handle, timeout };
|
|
|
|
serviceAssumeDomain(&g_nfcInterface);
|
|
u32 tmp_out=0;
|
|
Result rc = serviceDispatchInOut(&g_nfcInterface, 1300, in, tmp_out,
|
|
.buffer_attrs = {
|
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
|
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
|
|
},
|
|
.buffers = {
|
|
{ reply_buf, reply_buf_size },
|
|
{ cmd_buf, cmd_buf_size },
|
|
},
|
|
);
|
|
if (R_SUCCEEDED(rc) && out_size) *out_size = tmp_out;
|
|
return rc;
|
|
}
|
|
|
|
Result nfcKeepPassThroughSession(const NfcDeviceHandle *handle) {
|
|
if (hosversionBefore(4,0,0))
|
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
|
|
|
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 1301);
|
|
}
|
|
|
|
Result nfcReleasePassThroughSession(const NfcDeviceHandle *handle) {
|
|
if (hosversionBefore(4,0,0))
|
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
|
|
|
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 1302);
|
|
}
|