Add more ndm:u functions. (#386)

This commit is contained in:
Joel 2018-01-12 06:34:56 -06:00 committed by fincs
parent fdf31f7556
commit 52be537b48
3 changed files with 338 additions and 20 deletions

View File

@ -4,13 +4,54 @@
*/
#pragma once
/// Exclusive states.
typedef enum {
EXCLUSIVE_STATE_NONE = 0,
EXCLUSIVE_STATE_INFRASTRUCTURE = 1,
EXCLUSIVE_STATE_LOCAL_COMMUNICATIONS = 2,
EXCLUSIVE_STATE_STREETPASS = 3,
EXCLUSIVE_STATE_STREETPASS_DATA = 4,
} NDM_ExclusiveState;
} ndmExclusiveState;
/// Current states.
typedef enum {
STATE_INITIAL = 0,
STATE_SUSPENDED = 1,
STATE_INFRASTRUCTURE_CONNECTING = 2,
STATE_INFRASTRUCTURE_CONNECTED = 3,
STATE_INFRASTRUCTURE_WORKING = 4,
STATE_INFRASTRUCTURE_SUSPENDING = 5,
STATE_INFRASTRUCTURE_FORCE_SUSPENDING = 6,
STATE_INFRASTRUCTURE_DISCONNECTING = 7,
STATE_INFRASTRUCTURE_FORCE_DISCONNECTING = 8,
STATE_CEC_WORKING = 9,
STATE_CEC_FORCE_SUSPENDING = 10,
STATE_CEC_SUSPENDING = 11,
} ndmState;
// Daemons.
typedef enum {
DAEMON_CEC = 0,
DAEMON_BOSS = 1,
DAEMON_NIM = 2,
DAEMON_FRIENDS = 3,
} ndmDaemon;
/// Used to specify multiple daemons.
typedef enum {
DAEMON_MASK_CEC = BIT(DAEMON_CEC),
DAEMON_MASK_BOSS = BIT(DAEMON_BOSS),
DAEMON_MASK_NIM = BIT(DAEMON_NIM),
DAEMON_MASK_FRIENDS = BIT(DAEMON_FRIENDS),
} ndmDaemonMask;
// Daemon status.
typedef enum {
DAEMON_STATUS_BUSY = 0,
DAEMON_STATUS_IDLE = 1,
DAEMON_STATUS_SUSPENDING = 2,
DAEMON_STATUS_SUSPENDED = 3,
} ndmDaemonStatus;
/// Initializes ndmu.
Result ndmuInit(void);
@ -18,7 +59,87 @@ Result ndmuInit(void);
/// Exits ndmu.
void ndmuExit(void);
Result ndmuEnterExclusiveState(NDM_ExclusiveState state);
/**
* @brief Sets the network daemon to an exclusive state.
* @param state State specified in the ndmExclusiveState enumerator.
*/
Result NDMU_EnterExclusiveState(ndmExclusiveState state);
Result ndmuLeaveExclusiveState(void);
/// Cancels an exclusive state for the network daemon.
Result NDMU_LeaveExclusiveState(void);
/**
* @brief Returns the exclusive state for the network daemon.
* @param state Pointer to write the exclsuive state to.
*/
Result NDMU_GetExclusiveState(ndmExclusiveState *state);
/// Locks the exclusive state.
Result NDMU_LockState(void);
/// Unlocks the exclusive state.
Result NDMU_UnlockState(void);
/**
* @brief Suspends network daemon.
* @param mask The specified daemon.
*/
Result NDMU_SuspendDaemons(ndmDaemonMask mask);
/**
* @brief Resumes network daemon.
* @param mask The specified daemon.
*/
Result NDMU_ResumeDaemons(ndmDaemonMask mask);
/**
* @brief Suspends scheduling for all network daemons.
* @param flag 0 = Wait for completion, 1 = Perform in background.
*/
Result NDMU_SuspendScheduler(u32 flag);
/// Resumes daemon scheduling.
Result NDMU_ResumeScheduler(void);
/**
* @brief Returns the current state for the network daemon.
* @param state Pointer to write the current state to.
*/
Result NDMU_GetCurrentState(ndmState *state);
/**
* @brief Returns the daemon state.
* @param state Pointer to write the daemons state to.
*/
Result NDMU_QueryStatus(ndmDaemonStatus *status);
/**
* @brief Sets the scan interval.
* @param interval Value to set the scan interval to.
*/
Result NDMU_SetScanInterval(u32 interval);
/**
* @brief Returns the scan interval.
* @param interval Pointer to write the interval value to.
*/
Result NDMU_GetScanInterval(u32 *interval);
/**
* @brief Returns the retry interval.
* @param interval Pointer to write the interval value to.
*/
Result NDMU_GetRetryInterval(u32 *interval);
/// Reverts network daemon to defaults.
Result NDMU_ResetDaemons(void);
/**
* @brief Gets the current default daemon bit mask.
* @param interval Pointer to write the default daemon mask value to. The default value is (DAEMONMASK_CEC | DAEMONMASK_FRIENDS)
*/
Result NDMU_GetDefaultDaemons(ndmDaemonMask *mask);
/// Clears half awake mac filter.
Result NDMU_ClearMacFilter(void);

View File

@ -10,30 +10,30 @@
#include <3ds/services/ndm.h>
#include <3ds/ipc.h>
Handle __ndmu_servhandle;
static int __ndmu_refcount;
Handle ndmuHandle;
static int ndmuRefCount;
Result ndmuInit(void)
{
Result ret=0;
if (AtomicPostIncrement(&__ndmu_refcount)) return 0;
if (AtomicPostIncrement(&ndmuRefCount)) return 0;
ret = srvGetServiceHandle(&__ndmu_servhandle, "ndm:u");
if (R_FAILED(ret)) AtomicDecrement(&__ndmu_refcount);
ret = srvGetServiceHandle(&ndmuHandle, "ndm:u");
if (R_FAILED(ret)) AtomicDecrement(&ndmuRefCount);
return ret;
}
void ndmuExit(void)
{
if (AtomicDecrement(&__ndmu_refcount)) return;
if (AtomicDecrement(&ndmuRefCount)) return;
svcCloseHandle(__ndmu_servhandle);
__ndmu_servhandle = 0;
svcCloseHandle(ndmuHandle);
ndmuHandle = 0;
}
Result ndmuEnterExclusiveState(NDM_ExclusiveState state)
Result NDMU_EnterExclusiveState(ndmExclusiveState state)
{
u32* cmdbuf=getThreadCommandBuffer();
@ -42,12 +42,12 @@ Result ndmuEnterExclusiveState(NDM_ExclusiveState state)
cmdbuf[2]=IPC_Desc_CurProcessHandle();
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(__ndmu_servhandle)))return ret;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return cmdbuf[1];
return (Result)cmdbuf[1];
}
Result ndmuLeaveExclusiveState(void)
Result NDMU_LeaveExclusiveState(void)
{
u32* cmdbuf=getThreadCommandBuffer();
@ -55,8 +55,205 @@ Result ndmuLeaveExclusiveState(void)
cmdbuf[1]=IPC_Desc_CurProcessHandle();
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(__ndmu_servhandle)))return ret;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return cmdbuf[1];
return (Result)cmdbuf[1];
}
Result NDMU_GetExclusiveState(ndmExclusiveState *state)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x3,0,0); // 0x30000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
*state = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result NDMU_LockState(void)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x4,0,2); // 0x40002
cmdbuf[1]=IPC_Desc_CurProcessHandle();
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_UnlockState(void)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x5,0,2); // 0x50002
cmdbuf[1]=IPC_Desc_CurProcessHandle();
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_SuspendDaemons(ndmDaemonMask mask)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x6,1,0); // 0x60040
cmdbuf[1]=mask;
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_ResumeDaemons(ndmDaemonMask mask)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x7,1,0); // 0x70040
cmdbuf[1]=mask;
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_SuspendScheduler(u32 flag)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x8,1,0); // 0x80040
cmdbuf[1]=flag;
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_ResumeScheduler(void)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x9,0,0); // 0x90000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_GetCurrentState(ndmState *state)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0xA,0,0); // 0xA0000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
*state = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result NDMU_QueryStatus(ndmDaemonStatus *status)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0xD,1,0); // 0xD0000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
*status = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result NDMU_SetScanInterval(u32 interval)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x10,1,0); // 0x10040
cmdbuf[1]=interval;
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_GetScanInterval(u32 *interval)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x11,0,0); // 0x110000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
*interval = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result NDMU_GetRetryInterval(u32 *interval)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x13,0,0); // 0x130000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
*interval = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result NDMU_ResetDaemons(void)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x15,0,0); // 0x150000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}
Result NDMU_GetDefaultDaemons(ndmDaemonMask *mask)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x16,0,0); // 0x160000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
*mask = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result NDMU_ClearMacFilter(void)
{
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=IPC_MakeHeader(0x17,0,0); // 0x170000
Result ret=0;
if(R_FAILED(ret=svcSendSyncRequest(ndmuHandle)))return ret;
return (Result)cmdbuf[1];
}

View File

@ -55,7 +55,7 @@ Result udsInit(size_t sharedmem_size, const char *username)
if(R_SUCCEEDED(ret))
{
ndm_state = 1;
ret = ndmuEnterExclusiveState(EXCLUSIVE_STATE_LOCAL_COMMUNICATIONS);
ret = NDMU_EnterExclusiveState(EXCLUSIVE_STATE_LOCAL_COMMUNICATIONS);
if(R_SUCCEEDED(ret))
{
ndm_state = 2;
@ -80,7 +80,7 @@ Result udsInit(size_t sharedmem_size, const char *username)
{
if(ndm_state)
{
if(ndm_state==2)ndmuLeaveExclusiveState();
if(ndm_state==2)NDMU_LeaveExclusiveState();
ndmuExit();
}
@ -111,7 +111,7 @@ void udsExit(void)
svcCloseHandle(__uds_connectionstatus_event);
__uds_connectionstatus_event = 0;
ndmuLeaveExclusiveState();
NDMU_LeaveExclusiveState();
ndmuExit();
}