From ca6d017be9740197102e4ce2bccc4882caa47e0e Mon Sep 17 00:00:00 2001 From: yellows8 Date: Mon, 29 Jan 2018 23:16:06 -0500 Subject: [PATCH] Started irs IR-sensor support. --- nx/include/switch.h | 1 + nx/include/switch/services/irs.h | 22 ++++ nx/source/services/irs.c | 187 +++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 nx/include/switch/services/irs.h create mode 100644 nx/source/services/irs.c diff --git a/nx/include/switch.h b/nx/include/switch.h index 1b641209..45503abb 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -35,6 +35,7 @@ extern "C" { #include "switch/services/fatal.h" #include "switch/services/usb.h" #include "switch/services/hid.h" +#include "switch/services/irs.h" #include "switch/services/vi.h" #include "switch/services/nv.h" #include "switch/services/pm.h" diff --git a/nx/include/switch/services/irs.h b/nx/include/switch/services/irs.h new file mode 100644 index 00000000..c63b0b9b --- /dev/null +++ b/nx/include/switch/services/irs.h @@ -0,0 +1,22 @@ +/** + * @file irs.h + * @brief HID IR sensor service. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../services/sm.h" +#include "../services/hid.h" + +Result irsInitialize(void); +void irsExit(void); + +Service* irsGetSessionService(void); +void* irsGetSharedmemAddr(void); + +/// (De)activate the IR sensor, this is automatically used by irsExit(). Must be called after irsInitialize() to activate the IR sensor. +Result irsActivateIrsensor(bool activate); + +Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id); diff --git a/nx/source/services/irs.c b/nx/source/services/irs.c new file mode 100644 index 00000000..0508ff21 --- /dev/null +++ b/nx/source/services/irs.c @@ -0,0 +1,187 @@ +#include +#include "types.h" +#include "result.h" +#include "ipc.h" +#include "services/applet.h" +#include "services/irs.h" +#include "services/hid.h" +#include "services/sm.h" +#include "kernel/shmem.h" + +static Service g_irsSrv; +static SharedMemory g_irsSharedmem; +bool g_irsSensorActivated; + +static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletResourceUserId); + +Result irsInitialize(void) +{ + if (serviceIsActive(&g_irsSrv)) + return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); + + Result rc; + Handle sharedmem_handle; + u64 AppletResourceUserId=0; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + rc = smGetService(&g_irsSrv, "irs"); + if (R_FAILED(rc)) + return rc; + + rc = _irsGetIrsensorSharedMemoryHandle(&sharedmem_handle, AppletResourceUserId); + + if (R_SUCCEEDED(rc)) + { + shmemLoadRemote(&g_irsSharedmem, sharedmem_handle, 0x8000, PERM_R); + + rc = shmemMap(&g_irsSharedmem); + } + + if (R_FAILED(rc)) + irsExit(); + + return rc; +} + +void irsExit(void) +{ + irsActivateIrsensor(0); + + serviceClose(&g_irsSrv); + shmemClose(&g_irsSharedmem); +} + +Service* irsGetSessionService(void) { + return &g_irsSrv; +} + +void* irsGetSharedmemAddr(void) { + return shmemGetAddr(&g_irsSharedmem); +} + +Result irsActivateIrsensor(bool activate) { + if (g_irsSensorActivated==activate) return 0; + + Result rc=0; + u64 AppletResourceUserId=0; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = activate ? 302 : 303; + raw->AppletResourceUserId = AppletResourceUserId; + + rc = serviceIpcDispatch(&g_irsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) g_irsSensorActivated = activate; + } + + return rc; +} + +static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletResourceUserId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 304; + raw->AppletResourceUserId = AppletResourceUserId; + + Result rc = serviceIpcDispatch(&g_irsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + *handle_out = r.Handles[0]; + } + } + + return rc; +} + +Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 311; + raw->id = id; + + Result rc = serviceIpcDispatch(&g_irsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 IrCameraHandle; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && IrCameraHandle) { + *IrCameraHandle = resp->IrCameraHandle; + } + } + + return rc; +} +