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.
typedef enum {
AC_OPEN = 0, ///< Open authentication.
AC_WEP_40BIT = 1, ///< WEP 40-bit authentication.
AC_WEP_104BIT = 2, ///< WEP 104-bit authentication.
AC_WEP_128BIT = 3, ///< WEP 128-bit authentication.
AC_WPA_TKIP = 4, ///< WPA TKIP authentication.
AC_WPA2_TKIP = 5, ///< WPA2 TKIP authentication.
AC_WPA_AES = 6, ///< WPA AES authentication.
AC_WPA2_AES = 7, ///< WPA2 AES authentication.
AC_OPEN = 0, ///< Open authentication.
AC_WEP_40BIT = 1, ///< WEP 40-bit authentication.
AC_WEP_104BIT = 2, ///< WEP 104-bit authentication.
AC_WEP_128BIT = 3, ///< WEP 128-bit authentication.
AC_WPA_TKIP = 4, ///< WPA TKIP authentication.
AC_WPA2_TKIP = 5, ///< WPA2 TKIP authentication.
AC_WPA_AES = 6, ///< WPA AES authentication.
AC_WPA2_AES = 7, ///< WPA2 AES authentication.
} acSecurityMode;
/// Struct to contain the data for connecting to a Wifi network from a stored slot.
typedef struct {
u8 reserved[0x200];
} acuConfig;
/// Initializes AC.
Result acInit(void);
@ -90,3 +95,36 @@ Result ACU_GetLastErrorCode(u32* errorCode);
* @param errorCode Pointer to output the error code to.
*/
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;
ret = srvGetServiceHandle(&acHandle, "ac:u");
if(R_FAILED(ret)) ret = srvGetServiceHandle(&acHandle, "ac:i");
// ac:i has the most commands, then ac:u
ret = srvGetServiceHandle(&acHandle, "ac:i");
if(R_FAILED(ret)) ret = srvGetServiceHandle(&acHandle, "ac:u");
if(R_FAILED(ret)) AtomicDecrement(&acRefCount);
return ret;
@ -37,16 +38,62 @@ Result acWaitInternetConnection(void)
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;
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;
*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];
}
@ -65,6 +112,91 @@ Result ACU_GetStatus(u32 *out)
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 ret=0;
@ -86,7 +218,7 @@ Result ACU_GetSSID(char *SSID)
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x34,0,0); // 0x340000
staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0);
staticbufs[1] = (u32)SSID;
@ -144,7 +276,7 @@ Result ACU_GetProxyUserName(char *username)
u32 *staticbufs = getThreadStaticBuffers();
cmdbuf[0] = IPC_MakeHeader(0x3A,0,0); // 0x3A0000
staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0);
staticbufs[1] = (u32)username;
@ -152,47 +284,3 @@ Result ACU_GetProxyUserName(char *username)
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];
}