From a62df98686252f959e9a33dce125f08a90e9427f Mon Sep 17 00:00:00 2001 From: mailwl Date: Wed, 26 Oct 2016 15:53:09 +0300 Subject: [PATCH 1/3] AC_U: Stub functions, used if EULA agreed --- src/core/hle/service/ac_u.cpp | 205 +++++++++++++++++++++++++++++++--- src/core/hle/service/ac_u.h | 1 + 2 files changed, 191 insertions(+), 15 deletions(-) diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index 12d94f37a..86a2a1d3e 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -11,11 +11,81 @@ namespace AC_U { +static struct AcConfig { u8 data[0x200]; } default_config = {}; + +static bool ac_connected; + +static Kernel::SharedPtr close_event; +static Kernel::SharedPtr connect_event; +static Kernel::SharedPtr disconnect_event; + +/** + * AC_U::CreateDefaultConfig service function + * Inputs: + * 64 : AcConfig size << 14 | 2 + * 65 : pointer to AcConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +static void CreateDefaultConfig(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 ac_config_addr = cmd_buff[65]; + + ASSERT_MSG(cmd_buff[64] == (sizeof(AcConfig) << 14 | 2), + "Output buffer size not equal AcConfig size"); + + Memory::WriteBlock(ac_config_addr, &default_config, sizeof(AcConfig)); + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +/** + * AC_U::ConnectAsync service function + * Inputs: + * 1 : ProcessId Header + * 3 : Copy Handle Header + * 4 : Connection Event handle + * 5 : AcConfig size << 14 | 2 + * 6 : pointer to AcConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +static void ConnectAsync(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + connect_event = Kernel::g_handle_table.Get(cmd_buff[4]); + if (connect_event) { + connect_event->name = "AC_U:connect_event"; + connect_event->Signal(); + ac_connected = true; + } + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +/** + * AC_U::GetConnectResult service function + * Inputs: + * 1 : ProcessId Header + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +static void GetConnectResult(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + /** * AC_U::CloseAsync service function * Inputs: - * 1 : Always 0x20 - * 3 : Always 0 + * 1 : ProcessId Header + * 3 : Copy Handle Header * 4 : Event handle, should be signaled when AC connection is closed * Outputs: * 1 : Result of function, 0 on success, otherwise error code @@ -23,16 +93,37 @@ namespace AC_U { static void CloseAsync(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - auto evt = Kernel::g_handle_table.Get(cmd_buff[4]); - - if (evt) { - evt->name = "AC_U:close_event"; - evt->Signal(); + if (ac_connected && disconnect_event) { + disconnect_event->Signal(); } + + close_event = Kernel::g_handle_table.Get(cmd_buff[4]); + if (close_event) { + close_event->name = "AC_U:close_event"; + close_event->Signal(); + } + + ac_connected = false; + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +/** + * AC_U::GetCloseResult service function + * Inputs: + * 1 : ProcessId Header + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +static void GetCloseResult(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + cmd_buff[1] = RESULT_SUCCESS.raw; // No error LOG_WARNING(Service_AC, "(STUBBED) called"); } + /** * AC_U::GetWifiStatus service function * Outputs: @@ -51,6 +142,75 @@ static void GetWifiStatus(Service::Interface* self) { LOG_WARNING(Service_AC, "(STUBBED) called"); } +/** + * AC_U::GetInfraPriority service function + * Inputs: + * 1 : AcConfig size << 14 | 2 + * 2 : pointer to AcConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Infra Priority + */ +static void GetInfraPriority(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = 0; // Infra Priority, default 0 + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +/** + * AC_U::SetRequestEulaVersion service function + * Inputs: + * 1 : Eula Version major + * 2 : Eula Version minor + * 3 : AcConfig size << 14 | 2 + * 4 : Input pointer to AcConfig struct + * 64 : AcConfig size << 14 | 2 + * 65 : Output pointer to AcConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Infra Priority + */ +static void SetRequestEulaVersion(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u8 major = cmd_buff[1] & 0xFF; + u8 minor = cmd_buff[2] & 0xFF; + + ASSERT_MSG(cmd_buff[3] == (sizeof(AcConfig) << 14 | 2), + "Input buffer size not equal AcConfig size"); + ASSERT_MSG(cmd_buff[64] == (sizeof(AcConfig) << 14 | 2), + "Output buffer size not equal AcConfig size"); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = 0; // Infra Priority + + LOG_WARNING(Service_AC, "(STUBBED) called, major=%d, minor=%d", major, minor); +} + +/** + * AC_U::RegisterDisconnectEvent service function + * Inputs: + * 1 : ProcessId Header + * 3 : Copy Handle Header + * 4 : Event handle, should be signaled when AC connection is closed + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +static void RegisterDisconnectEvent(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + disconnect_event = Kernel::g_handle_table.Get(cmd_buff[4]); + if (disconnect_event) { + disconnect_event->name = "AC_U:disconnect_event"; + } + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + /** * AC_U::IsConnected service function * Outputs: @@ -61,26 +221,29 @@ static void IsConnected(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = false; // Not connected to ac:u service + cmd_buff[2] = ac_connected; LOG_WARNING(Service_AC, "(STUBBED) called"); } const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, nullptr, "CreateDefaultConfig"}, - {0x00040006, nullptr, "ConnectAsync"}, - {0x00050002, nullptr, "GetConnectResult"}, + {0x00010000, CreateDefaultConfig, "CreateDefaultConfig"}, + {0x00040006, ConnectAsync, "ConnectAsync"}, + {0x00050002, GetConnectResult, "GetConnectResult"}, + {0x00070002, nullptr, "CancelConnectAsync"}, {0x00080004, CloseAsync, "CloseAsync"}, - {0x00090002, nullptr, "GetCloseResult"}, + {0x00090002, GetCloseResult, "GetCloseResult"}, {0x000A0000, nullptr, "GetLastErrorCode"}, + {0x000C0000, nullptr, "GetStatus"}, {0x000D0000, GetWifiStatus, "GetWifiStatus"}, {0x000E0042, nullptr, "GetCurrentAPInfo"}, {0x00100042, nullptr, "GetCurrentNZoneInfo"}, {0x00110042, nullptr, "GetNZoneApNumService"}, + {0x001D0042, nullptr, "ScanAPs"}, {0x00240042, nullptr, "AddDenyApType"}, - {0x00270002, nullptr, "GetInfraPriority"}, - {0x002D0082, nullptr, "SetRequestEulaVersion"}, - {0x00300004, nullptr, "RegisterDisconnectEvent"}, + {0x00270002, GetInfraPriority, "GetInfraPriority"}, + {0x002D0082, SetRequestEulaVersion, "SetRequestEulaVersion"}, + {0x00300004, RegisterDisconnectEvent, "RegisterDisconnectEvent"}, {0x003C0042, nullptr, "GetAPSSIDList"}, {0x003E0042, IsConnected, "IsConnected"}, {0x00400042, nullptr, "SetClientVersion"}, @@ -91,6 +254,18 @@ const Interface::FunctionInfo FunctionTable[] = { Interface::Interface() { Register(FunctionTable); + + ac_connected = false; + + close_event = nullptr; + connect_event = nullptr; + disconnect_event = nullptr; +} + +Interface::~Interface() { + close_event = nullptr; + connect_event = nullptr; + disconnect_event = nullptr; } } // namespace diff --git a/src/core/hle/service/ac_u.h b/src/core/hle/service/ac_u.h index f1d26ebe8..6592b21c9 100644 --- a/src/core/hle/service/ac_u.h +++ b/src/core/hle/service/ac_u.h @@ -16,6 +16,7 @@ namespace AC_U { class Interface : public Service::Interface { public: Interface(); + ~Interface(); std::string GetPortName() const override { return "ac:u"; From 5872abeab920257cbbd02c58a19440bc8597a1e9 Mon Sep 17 00:00:00 2001 From: mailwl Date: Thu, 27 Oct 2016 09:29:05 +0300 Subject: [PATCH 2/3] Rename AcConfig, change types u8 to u32 --- src/core/hle/service/ac_u.cpp | 46 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index 86a2a1d3e..bbf743c2e 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -11,7 +11,11 @@ namespace AC_U { -static struct AcConfig { u8 data[0x200]; } default_config = {}; +struct ACConfig { + std::array data; +}; + +static ACConfig default_config = {}; static bool ac_connected; @@ -22,8 +26,8 @@ static Kernel::SharedPtr disconnect_event; /** * AC_U::CreateDefaultConfig service function * Inputs: - * 64 : AcConfig size << 14 | 2 - * 65 : pointer to AcConfig struct + * 64 : ACConfig size << 14 | 2 + * 65 : pointer to ACConfig struct * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ @@ -32,10 +36,10 @@ static void CreateDefaultConfig(Service::Interface* self) { u32 ac_config_addr = cmd_buff[65]; - ASSERT_MSG(cmd_buff[64] == (sizeof(AcConfig) << 14 | 2), - "Output buffer size not equal AcConfig size"); + ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2), + "Output buffer size not equal ACConfig size"); - Memory::WriteBlock(ac_config_addr, &default_config, sizeof(AcConfig)); + Memory::WriteBlock(ac_config_addr, &default_config, sizeof(ACConfig)); cmd_buff[1] = RESULT_SUCCESS.raw; // No error LOG_WARNING(Service_AC, "(STUBBED) called"); @@ -47,8 +51,8 @@ static void CreateDefaultConfig(Service::Interface* self) { * 1 : ProcessId Header * 3 : Copy Handle Header * 4 : Connection Event handle - * 5 : AcConfig size << 14 | 2 - * 6 : pointer to AcConfig struct + * 5 : ACConfig size << 14 | 2 + * 6 : pointer to ACConfig struct * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ @@ -145,8 +149,8 @@ static void GetWifiStatus(Service::Interface* self) { /** * AC_U::GetInfraPriority service function * Inputs: - * 1 : AcConfig size << 14 | 2 - * 2 : pointer to AcConfig struct + * 1 : ACConfig size << 14 | 2 + * 2 : pointer to ACConfig struct * Outputs: * 1 : Result of function, 0 on success, otherwise error code * 2 : Infra Priority @@ -165,10 +169,10 @@ static void GetInfraPriority(Service::Interface* self) { * Inputs: * 1 : Eula Version major * 2 : Eula Version minor - * 3 : AcConfig size << 14 | 2 - * 4 : Input pointer to AcConfig struct - * 64 : AcConfig size << 14 | 2 - * 65 : Output pointer to AcConfig struct + * 3 : ACConfig size << 14 | 2 + * 4 : Input pointer to ACConfig struct + * 64 : ACConfig size << 14 | 2 + * 65 : Output pointer to ACConfig struct * Outputs: * 1 : Result of function, 0 on success, otherwise error code * 2 : Infra Priority @@ -176,18 +180,18 @@ static void GetInfraPriority(Service::Interface* self) { static void SetRequestEulaVersion(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u8 major = cmd_buff[1] & 0xFF; - u8 minor = cmd_buff[2] & 0xFF; + u32 major = cmd_buff[1] & 0xFF; + u32 minor = cmd_buff[2] & 0xFF; - ASSERT_MSG(cmd_buff[3] == (sizeof(AcConfig) << 14 | 2), - "Input buffer size not equal AcConfig size"); - ASSERT_MSG(cmd_buff[64] == (sizeof(AcConfig) << 14 | 2), - "Output buffer size not equal AcConfig size"); + ASSERT_MSG(cmd_buff[3] == (sizeof(ACConfig) << 14 | 2), + "Input buffer size not equal ACConfig size"); + ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2), + "Output buffer size not equal ACConfig size"); cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = 0; // Infra Priority - LOG_WARNING(Service_AC, "(STUBBED) called, major=%d, minor=%d", major, minor); + LOG_WARNING(Service_AC, "(STUBBED) called, major=%u, minor=%u", major, minor); } /** From af7f5bef8d93dec286f6c15c47d29b13d05cfb46 Mon Sep 17 00:00:00 2001 From: mailwl Date: Wed, 2 Nov 2016 09:38:30 +0300 Subject: [PATCH 3/3] Style fix --- src/core/hle/service/ac_u.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index bbf743c2e..18026975f 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -15,9 +15,9 @@ struct ACConfig { std::array data; }; -static ACConfig default_config = {}; +static ACConfig default_config{}; -static bool ac_connected; +static bool ac_connected = false; static Kernel::SharedPtr close_event; static Kernel::SharedPtr connect_event;