summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/ac_u.cpp203
-rw-r--r--src/core/hle/service/ac_u.h1
2 files changed, 190 insertions, 14 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 @@
11 11
12namespace AC_U { 12namespace AC_U {
13 13
14static struct AcConfig { u8 data[0x200]; } default_config = {};
15
16static bool ac_connected;
17
18static Kernel::SharedPtr<Kernel::Event> close_event;
19static Kernel::SharedPtr<Kernel::Event> connect_event;
20static Kernel::SharedPtr<Kernel::Event> disconnect_event;
21
22/**
23 * AC_U::CreateDefaultConfig service function
24 * Inputs:
25 * 64 : AcConfig size << 14 | 2
26 * 65 : pointer to AcConfig struct
27 * Outputs:
28 * 1 : Result of function, 0 on success, otherwise error code
29 */
30static void CreateDefaultConfig(Service::Interface* self) {
31 u32* cmd_buff = Kernel::GetCommandBuffer();
32
33 u32 ac_config_addr = cmd_buff[65];
34
35 ASSERT_MSG(cmd_buff[64] == (sizeof(AcConfig) << 14 | 2),
36 "Output buffer size not equal AcConfig size");
37
38 Memory::WriteBlock(ac_config_addr, &default_config, sizeof(AcConfig));
39 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
40
41 LOG_WARNING(Service_AC, "(STUBBED) called");
42}
43
44/**
45 * AC_U::ConnectAsync service function
46 * Inputs:
47 * 1 : ProcessId Header
48 * 3 : Copy Handle Header
49 * 4 : Connection Event handle
50 * 5 : AcConfig size << 14 | 2
51 * 6 : pointer to AcConfig struct
52 * Outputs:
53 * 1 : Result of function, 0 on success, otherwise error code
54 */
55static void ConnectAsync(Service::Interface* self) {
56 u32* cmd_buff = Kernel::GetCommandBuffer();
57
58 connect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
59 if (connect_event) {
60 connect_event->name = "AC_U:connect_event";
61 connect_event->Signal();
62 ac_connected = true;
63 }
64 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
65
66 LOG_WARNING(Service_AC, "(STUBBED) called");
67}
68
69/**
70 * AC_U::GetConnectResult service function
71 * Inputs:
72 * 1 : ProcessId Header
73 * Outputs:
74 * 1 : Result of function, 0 on success, otherwise error code
75 */
76static void GetConnectResult(Service::Interface* self) {
77 u32* cmd_buff = Kernel::GetCommandBuffer();
78
79 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
80
81 LOG_WARNING(Service_AC, "(STUBBED) called");
82}
83
14/** 84/**
15 * AC_U::CloseAsync service function 85 * AC_U::CloseAsync service function
16 * Inputs: 86 * Inputs:
17 * 1 : Always 0x20 87 * 1 : ProcessId Header
18 * 3 : Always 0 88 * 3 : Copy Handle Header
19 * 4 : Event handle, should be signaled when AC connection is closed 89 * 4 : Event handle, should be signaled when AC connection is closed
20 * Outputs: 90 * Outputs:
21 * 1 : Result of function, 0 on success, otherwise error code 91 * 1 : Result of function, 0 on success, otherwise error code
@@ -23,16 +93,37 @@ namespace AC_U {
23static void CloseAsync(Service::Interface* self) { 93static void CloseAsync(Service::Interface* self) {
24 u32* cmd_buff = Kernel::GetCommandBuffer(); 94 u32* cmd_buff = Kernel::GetCommandBuffer();
25 95
26 auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); 96 if (ac_connected && disconnect_event) {
97 disconnect_event->Signal();
98 }
27 99
28 if (evt) { 100 close_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
29 evt->name = "AC_U:close_event"; 101 if (close_event) {
30 evt->Signal(); 102 close_event->name = "AC_U:close_event";
103 close_event->Signal();
31 } 104 }
105
106 ac_connected = false;
107
108 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
109 LOG_WARNING(Service_AC, "(STUBBED) called");
110}
111
112/**
113 * AC_U::GetCloseResult service function
114 * Inputs:
115 * 1 : ProcessId Header
116 * Outputs:
117 * 1 : Result of function, 0 on success, otherwise error code
118 */
119static void GetCloseResult(Service::Interface* self) {
120 u32* cmd_buff = Kernel::GetCommandBuffer();
121
32 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 122 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
33 123
34 LOG_WARNING(Service_AC, "(STUBBED) called"); 124 LOG_WARNING(Service_AC, "(STUBBED) called");
35} 125}
126
36/** 127/**
37 * AC_U::GetWifiStatus service function 128 * AC_U::GetWifiStatus service function
38 * Outputs: 129 * Outputs:
@@ -52,6 +143,75 @@ static void GetWifiStatus(Service::Interface* self) {
52} 143}
53 144
54/** 145/**
146 * AC_U::GetInfraPriority service function
147 * Inputs:
148 * 1 : AcConfig size << 14 | 2
149 * 2 : pointer to AcConfig struct
150 * Outputs:
151 * 1 : Result of function, 0 on success, otherwise error code
152 * 2 : Infra Priority
153 */
154static void GetInfraPriority(Service::Interface* self) {
155 u32* cmd_buff = Kernel::GetCommandBuffer();
156
157 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
158 cmd_buff[2] = 0; // Infra Priority, default 0
159
160 LOG_WARNING(Service_AC, "(STUBBED) called");
161}
162
163/**
164 * AC_U::SetRequestEulaVersion service function
165 * Inputs:
166 * 1 : Eula Version major
167 * 2 : Eula Version minor
168 * 3 : AcConfig size << 14 | 2
169 * 4 : Input pointer to AcConfig struct
170 * 64 : AcConfig size << 14 | 2
171 * 65 : Output pointer to AcConfig struct
172 * Outputs:
173 * 1 : Result of function, 0 on success, otherwise error code
174 * 2 : Infra Priority
175 */
176static void SetRequestEulaVersion(Service::Interface* self) {
177 u32* cmd_buff = Kernel::GetCommandBuffer();
178
179 u8 major = cmd_buff[1] & 0xFF;
180 u8 minor = cmd_buff[2] & 0xFF;
181
182 ASSERT_MSG(cmd_buff[3] == (sizeof(AcConfig) << 14 | 2),
183 "Input buffer size not equal AcConfig size");
184 ASSERT_MSG(cmd_buff[64] == (sizeof(AcConfig) << 14 | 2),
185 "Output buffer size not equal AcConfig size");
186
187 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
188 cmd_buff[2] = 0; // Infra Priority
189
190 LOG_WARNING(Service_AC, "(STUBBED) called, major=%d, minor=%d", major, minor);
191}
192
193/**
194 * AC_U::RegisterDisconnectEvent service function
195 * Inputs:
196 * 1 : ProcessId Header
197 * 3 : Copy Handle Header
198 * 4 : Event handle, should be signaled when AC connection is closed
199 * Outputs:
200 * 1 : Result of function, 0 on success, otherwise error code
201 */
202static void RegisterDisconnectEvent(Service::Interface* self) {
203 u32* cmd_buff = Kernel::GetCommandBuffer();
204
205 disconnect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
206 if (disconnect_event) {
207 disconnect_event->name = "AC_U:disconnect_event";
208 }
209 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
210
211 LOG_WARNING(Service_AC, "(STUBBED) called");
212}
213
214/**
55 * AC_U::IsConnected service function 215 * AC_U::IsConnected service function
56 * Outputs: 216 * Outputs:
57 * 1 : Result of function, 0 on success, otherwise error code 217 * 1 : Result of function, 0 on success, otherwise error code
@@ -61,26 +221,29 @@ static void IsConnected(Service::Interface* self) {
61 u32* cmd_buff = Kernel::GetCommandBuffer(); 221 u32* cmd_buff = Kernel::GetCommandBuffer();
62 222
63 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 223 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
64 cmd_buff[2] = false; // Not connected to ac:u service 224 cmd_buff[2] = ac_connected;
65 225
66 LOG_WARNING(Service_AC, "(STUBBED) called"); 226 LOG_WARNING(Service_AC, "(STUBBED) called");
67} 227}
68 228
69const Interface::FunctionInfo FunctionTable[] = { 229const Interface::FunctionInfo FunctionTable[] = {
70 {0x00010000, nullptr, "CreateDefaultConfig"}, 230 {0x00010000, CreateDefaultConfig, "CreateDefaultConfig"},
71 {0x00040006, nullptr, "ConnectAsync"}, 231 {0x00040006, ConnectAsync, "ConnectAsync"},
72 {0x00050002, nullptr, "GetConnectResult"}, 232 {0x00050002, GetConnectResult, "GetConnectResult"},
233 {0x00070002, nullptr, "CancelConnectAsync"},
73 {0x00080004, CloseAsync, "CloseAsync"}, 234 {0x00080004, CloseAsync, "CloseAsync"},
74 {0x00090002, nullptr, "GetCloseResult"}, 235 {0x00090002, GetCloseResult, "GetCloseResult"},
75 {0x000A0000, nullptr, "GetLastErrorCode"}, 236 {0x000A0000, nullptr, "GetLastErrorCode"},
237 {0x000C0000, nullptr, "GetStatus"},
76 {0x000D0000, GetWifiStatus, "GetWifiStatus"}, 238 {0x000D0000, GetWifiStatus, "GetWifiStatus"},
77 {0x000E0042, nullptr, "GetCurrentAPInfo"}, 239 {0x000E0042, nullptr, "GetCurrentAPInfo"},
78 {0x00100042, nullptr, "GetCurrentNZoneInfo"}, 240 {0x00100042, nullptr, "GetCurrentNZoneInfo"},
79 {0x00110042, nullptr, "GetNZoneApNumService"}, 241 {0x00110042, nullptr, "GetNZoneApNumService"},
242 {0x001D0042, nullptr, "ScanAPs"},
80 {0x00240042, nullptr, "AddDenyApType"}, 243 {0x00240042, nullptr, "AddDenyApType"},
81 {0x00270002, nullptr, "GetInfraPriority"}, 244 {0x00270002, GetInfraPriority, "GetInfraPriority"},
82 {0x002D0082, nullptr, "SetRequestEulaVersion"}, 245 {0x002D0082, SetRequestEulaVersion, "SetRequestEulaVersion"},
83 {0x00300004, nullptr, "RegisterDisconnectEvent"}, 246 {0x00300004, RegisterDisconnectEvent, "RegisterDisconnectEvent"},
84 {0x003C0042, nullptr, "GetAPSSIDList"}, 247 {0x003C0042, nullptr, "GetAPSSIDList"},
85 {0x003E0042, IsConnected, "IsConnected"}, 248 {0x003E0042, IsConnected, "IsConnected"},
86 {0x00400042, nullptr, "SetClientVersion"}, 249 {0x00400042, nullptr, "SetClientVersion"},
@@ -91,6 +254,18 @@ const Interface::FunctionInfo FunctionTable[] = {
91 254
92Interface::Interface() { 255Interface::Interface() {
93 Register(FunctionTable); 256 Register(FunctionTable);
257
258 ac_connected = false;
259
260 close_event = nullptr;
261 connect_event = nullptr;
262 disconnect_event = nullptr;
263}
264
265Interface::~Interface() {
266 close_event = nullptr;
267 connect_event = nullptr;
268 disconnect_event = nullptr;
94} 269}
95 270
96} // namespace 271} // 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 {
16class Interface : public Service::Interface { 16class Interface : public Service::Interface {
17public: 17public:
18 Interface(); 18 Interface();
19 ~Interface();
19 20
20 std::string GetPortName() const override { 21 std::string GetPortName() const override {
21 return "ac:u"; 22 return "ac:u";