Add AC commands that allow forcing a wifi connection (#438)

This commit is contained in:
LiquidFenrir 2019-09-21 02:49:41 +02:00 committed by fincs
parent 751dd3b42d
commit 8acc1871bc
2 changed files with 185 additions and 59 deletions

View File

@ -6,16 +6,21 @@
/// Wifi security modes. /// Wifi security modes.
typedef enum { typedef enum {
AC_OPEN = 0, ///< Open authentication. AC_OPEN = 0, ///< Open authentication.
AC_WEP_40BIT = 1, ///< WEP 40-bit authentication. AC_WEP_40BIT = 1, ///< WEP 40-bit authentication.
AC_WEP_104BIT = 2, ///< WEP 104-bit authentication. AC_WEP_104BIT = 2, ///< WEP 104-bit authentication.
AC_WEP_128BIT = 3, ///< WEP 128-bit authentication. AC_WEP_128BIT = 3, ///< WEP 128-bit authentication.
AC_WPA_TKIP = 4, ///< WPA TKIP authentication. AC_WPA_TKIP = 4, ///< WPA TKIP authentication.
AC_WPA2_TKIP = 5, ///< WPA2 TKIP authentication. AC_WPA2_TKIP = 5, ///< WPA2 TKIP authentication.
AC_WPA_AES = 6, ///< WPA AES authentication. AC_WPA_AES = 6, ///< WPA AES authentication.
AC_WPA2_AES = 7, ///< WPA2 AES authentication. AC_WPA2_AES = 7, ///< WPA2 AES authentication.
} acSecurityMode; } acSecurityMode;
/// Struct to contain the data for connecting to a Wifi network from a stored slot.
typedef struct {
u8 reserved[0x200];
} acuConfig;
/// Initializes AC. /// Initializes AC.
Result acInit(void); Result acInit(void);
@ -90,3 +95,36 @@ Result ACU_GetLastErrorCode(u32* errorCode);
* @param errorCode Pointer to output the error code to. * @param errorCode Pointer to output the error code to.
*/ */
Result ACU_GetLastDetailErrorCode(u32* errorCode); Result ACU_GetLastDetailErrorCode(u32* errorCode);
/**
* @brief Prepares a buffer to hold the configuration data to start a connection.
* @param config Pointer to an acuConfig struct to contain the data.
*/
Result ACU_CreateDefaultConfig(acuConfig* config);
/**
* @brief Sets something that makes the connection reliable.
* @param config Pointer to an acuConfig struct used with ACU_CreateDefaultConfig previously.
* @param area Always 2 ?
*/
Result ACU_SetNetworkArea(acuConfig* config, u8 area);
/**
* @brief Sets the slot to use when connecting.
* @param config Pointer to an acuConfig struct used with ACU_CreateDefaultConfig previously.
* @param type Allowed slots flag. BIT(0) for slot 1, BIT(1) for slot 2, BIT(2) for slot 3.
*/
Result ACU_SetAllowApType(acuConfig* config, u8 type);
/**
* @brief Sets something that makes the connection reliable.
* @param config Pointer to an acuConfig struct used with ACU_CreateDefaultConfig previously.
*/
Result ACU_SetRequestEulaVersion(acuConfig* config);
/**
* @brief Starts the connection procedure.
* @param config Pointer to an acuConfig struct used with ACU_CreateDefaultConfig previously.
* @param connectionHandle Handle created with svcCreateEvent to wait on until the connection succeeds or fails.
*/
Result ACU_ConnectAsync(const acuConfig* config, Handle connectionHandle);

View File

@ -16,8 +16,9 @@ Result acInit(void)
if (AtomicPostIncrement(&acRefCount)) return 0; if (AtomicPostIncrement(&acRefCount)) return 0;
ret = srvGetServiceHandle(&acHandle, "ac:u"); // ac:i has the most commands, then ac:u
if(R_FAILED(ret)) ret = srvGetServiceHandle(&acHandle, "ac:i"); ret = srvGetServiceHandle(&acHandle, "ac:i");
if(R_FAILED(ret)) ret = srvGetServiceHandle(&acHandle, "ac:u");
if(R_FAILED(ret)) AtomicDecrement(&acRefCount); if(R_FAILED(ret)) AtomicDecrement(&acRefCount);
return ret; return ret;
@ -37,16 +38,62 @@ Result acWaitInternetConnection(void)
return ret; return ret;
} }
Result ACU_GetWifiStatus(u32 *out) Result ACU_CreateDefaultConfig(acuConfig* config)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x1,0,0); // 0x10000
staticbufs[0] = IPC_Desc_StaticBuffer(0x200, 0);
staticbufs[1] = (u32)config;
if(R_FAILED(ret = svcSendSyncRequest(acHandle))) return ret;
return (Result)cmdbuf[1];
}
Result ACU_ConnectAsync(const acuConfig* config, Handle connectionHandle)
{ {
Result ret=0; Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0xD,0,0); // 0xD0000 cmdbuf[0] = IPC_MakeHeader(0x4,0,6); // 0x40006
cmdbuf[1] = 0x20;
cmdbuf[3] = 0;
cmdbuf[4] = connectionHandle;
cmdbuf[5] = IPC_Desc_StaticBuffer(0x200, 1);
cmdbuf[6] = (u32)config;
if(R_FAILED(ret = svcSendSyncRequest(acHandle))) return ret;
return (Result)cmdbuf[1];
}
Result ACU_GetLastErrorCode(u32* errorCode)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0xA,0,0); // 0xA0000
if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret; if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret;
*out = cmdbuf[2]; if(errorCode) *errorCode = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result ACU_GetLastDetailErrorCode(u32* errorCode)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret;
if(errorCode) *errorCode = cmdbuf[2];
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
@ -65,6 +112,91 @@ Result ACU_GetStatus(u32 *out)
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result ACU_GetWifiStatus(u32 *out)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0xD,0,0); // 0xD0000
if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret;
*out = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result ACU_SetAllowApType(acuConfig* config, u8 type)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x22,1,2); // 0x220042
cmdbuf[1] = type;
cmdbuf[2] = IPC_Desc_StaticBuffer(0x200, 0);
cmdbuf[3] = (u32)config;
staticbufs[0] = IPC_Desc_StaticBuffer(0x200, 0);
staticbufs[1] = (u32)config;
if(R_FAILED(ret = svcSendSyncRequest(acHandle))) return ret;
return (Result)cmdbuf[1];
}
Result ACU_SetNetworkArea(acuConfig* config, u8 area)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x25,1,2); // 0x250042
cmdbuf[1] = area;
cmdbuf[2] = IPC_Desc_StaticBuffer(0x200, 0);
cmdbuf[3] = (u32)config;
staticbufs[0] = IPC_Desc_StaticBuffer(0x200, 0);
staticbufs[1] = (u32)config;
if(R_FAILED(ret = svcSendSyncRequest(acHandle))) return ret;
return (Result)cmdbuf[1];
}
Result ACU_SetRequestEulaVersion(acuConfig* config)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x2D,2,2); // 0x2D0082
cmdbuf[1] = 0;
cmdbuf[2] = 0;
cmdbuf[3] = IPC_Desc_StaticBuffer(0x200, 0);
cmdbuf[4] = (u32)config;
staticbufs[0] = IPC_Desc_StaticBuffer(0x200, 0);
staticbufs[1] = (u32)config;
if(R_FAILED(ret = svcSendSyncRequest(acHandle))) return ret;
return (Result)cmdbuf[1];
}
Result ACU_GetProxyPassword(char *password)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x3B,0,0); // 0x3B0000
staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0);
staticbufs[1] = (u32)password;
if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret;
return (Result)cmdbuf[1];
}
Result ACU_GetSecurityMode(acSecurityMode *mode) Result ACU_GetSecurityMode(acSecurityMode *mode)
{ {
Result ret=0; Result ret=0;
@ -86,7 +218,7 @@ Result ACU_GetSSID(char *SSID)
u32 *staticbufs = getThreadStaticBuffers(); u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x34,0,0); // 0x340000 cmdbuf[0] = IPC_MakeHeader(0x34,0,0); // 0x340000
staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0); staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0);
staticbufs[1] = (u32)SSID; staticbufs[1] = (u32)SSID;
@ -144,7 +276,7 @@ Result ACU_GetProxyUserName(char *username)
u32 *staticbufs = getThreadStaticBuffers(); u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x3A,0,0); // 0x3A0000 cmdbuf[0] = IPC_MakeHeader(0x3A,0,0); // 0x3A0000
staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0); staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0);
staticbufs[1] = (u32)username; staticbufs[1] = (u32)username;
@ -152,47 +284,3 @@ Result ACU_GetProxyUserName(char *username)
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result ACU_GetProxyPassword(char *password)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x3B,0,0); // 0x3B0000
staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0);
staticbufs[1] = (u32)password;
if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret;
return (Result)cmdbuf[1];
}
Result ACU_GetLastErrorCode(u32* errorCode)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0xA,0,0); // 0xA0000
if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret;
if(errorCode) *errorCode = cmdbuf[2];
return (Result)cmdbuf[1];
}
Result ACU_GetLastDetailErrorCode(u32* errorCode)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret;
if(errorCode) *errorCode = cmdbuf[2];
return (Result)cmdbuf[1];
}