blob: 1589dd258c35e7cf743ccaf3d7107c04ed485b26 [file] [log] [blame]
Gabriel Biren57ededa2021-09-03 16:08:50 +00001/*
2 * WPA Supplicant - Supplicant Aidl interface
3 * Copyright (c) 2021, Google Inc. All rights reserved.
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "aidl_manager.h"
10#include "aidl_return_util.h"
11#include "misc_utils.h"
12#include "supplicant.h"
13#include "p2p_iface.h"
14
15#include <android-base/file.h>
16#include <fcntl.h>
17#include <sys/stat.h>
18
19namespace {
20
21// Pre-populated interface params for interfaces controlled by wpa_supplicant.
22// Note: This may differ for other OEM's. So, modify this accordingly.
Jooyung Hanbd916f82024-02-22 14:17:39 +090023// When wpa_supplicant is in its APEX, overlay/template configurations should be
24// loaded from the same APEX.
Gabriel Biren57ededa2021-09-03 16:08:50 +000025constexpr char kIfaceDriverName[] = "nl80211";
Jooyung Han40d8f1a2024-02-22 13:30:57 +090026
Gabriel Biren57ededa2021-09-03 16:08:50 +000027constexpr char kStaIfaceConfPath[] =
28 "/data/vendor/wifi/wpa/wpa_supplicant.conf";
Jooyung Han40d8f1a2024-02-22 13:30:57 +090029constexpr char kStaIfaceConfOverlayPath[] =
Jooyung Hanbd916f82024-02-22 14:17:39 +090030 "/etc/wifi/wpa_supplicant_overlay.conf";
Jooyung Han40d8f1a2024-02-22 13:30:57 +090031
Gabriel Biren57ededa2021-09-03 16:08:50 +000032constexpr char kP2pIfaceConfPath[] =
33 "/data/vendor/wifi/wpa/p2p_supplicant.conf";
Jooyung Han40d8f1a2024-02-22 13:30:57 +090034constexpr char kP2pIfaceConfOverlayPath[] =
Jooyung Hanbd916f82024-02-22 14:17:39 +090035 "/etc/wifi/p2p_supplicant_overlay.conf";
Jooyung Han40d8f1a2024-02-22 13:30:57 +090036
Gabriel Biren57ededa2021-09-03 16:08:50 +000037// Migrate conf files for existing devices.
Jooyung Han40d8f1a2024-02-22 13:30:57 +090038constexpr char kSystemTemplateConfPath[] =
39 "/system/etc/wifi/wpa_supplicant.conf";
40constexpr char kVendorTemplateConfPath[] =
Jooyung Hanbd916f82024-02-22 14:17:39 +090041 "/etc/wifi/wpa_supplicant.conf";
Jooyung Han40d8f1a2024-02-22 13:30:57 +090042
Gabriel Biren57ededa2021-09-03 16:08:50 +000043constexpr char kOldStaIfaceConfPath[] = "/data/misc/wifi/wpa_supplicant.conf";
44constexpr char kOldP2pIfaceConfPath[] = "/data/misc/wifi/p2p_supplicant.conf";
45constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
46
Jooyung Hanbd916f82024-02-22 14:17:39 +090047std::string resolveVendorConfPath(const std::string& conf_path)
48{
49#if defined(__ANDROID_APEX__)
50 // returns "/apex/<apexname>" + conf_path
51 std::string path = android::base::GetExecutablePath();
52 return path.substr(0, path.find_first_of('/', strlen("/apex/"))) + conf_path;
53#else
54 return std::string("/vendor") + conf_path;
55#endif
56}
57
Gabriel Biren57ededa2021-09-03 16:08:50 +000058int copyFile(
59 const std::string& src_file_path, const std::string& dest_file_path)
60{
61 std::string file_contents;
62 if (!android::base::ReadFileToString(src_file_path, &file_contents)) {
63 wpa_printf(
64 MSG_ERROR, "Failed to read from %s. Errno: %s",
65 src_file_path.c_str(), strerror(errno));
66 return -1;
67 }
68 if (!android::base::WriteStringToFile(
69 file_contents, dest_file_path, kConfigFileMode, getuid(),
70 getgid())) {
71 wpa_printf(
72 MSG_ERROR, "Failed to write to %s. Errno: %s",
73 dest_file_path.c_str(), strerror(errno));
74 return -1;
75 }
76 return 0;
77}
78
79/**
80 * Copy |src_file_path| to |dest_file_path| if it exists.
81 *
82 * Returns 1 if |src_file_path| does not exist or not accessible,
83 * Returns -1 if the copy fails.
84 * Returns 0 if the copy succeeds.
85 */
86int copyFileIfItExists(
87 const std::string& src_file_path, const std::string& dest_file_path)
88{
89 int ret = access(src_file_path.c_str(), R_OK);
90 // Sepolicy denial (2018+ device) will return EACCESS instead of ENOENT.
91 if ((ret != 0) && ((errno == ENOENT) || (errno == EACCES))) {
92 return 1;
93 }
94 ret = copyFile(src_file_path, dest_file_path);
95 if (ret != 0) {
96 wpa_printf(
97 MSG_ERROR, "Failed copying %s to %s.",
98 src_file_path.c_str(), dest_file_path.c_str());
99 return -1;
100 }
101 return 0;
102}
103
104/**
105 * Ensure that the specified config file pointed by |config_file_path| exists.
106 * a) If the |config_file_path| exists with the correct permissions, return.
107 * b) If the |config_file_path| does not exist, but |old_config_file_path|
108 * exists, copy over the contents of the |old_config_file_path| to
109 * |config_file_path|.
110 * c) If the |config_file_path| & |old_config_file_path|
111 * does not exists, copy over the contents of |template_config_file_path|.
112 */
113int ensureConfigFileExists(
114 const std::string& config_file_path,
115 const std::string& old_config_file_path)
116{
117 int ret = access(config_file_path.c_str(), R_OK | W_OK);
118 if (ret == 0) {
119 return 0;
120 }
121 if (errno == EACCES) {
122 ret = chmod(config_file_path.c_str(), kConfigFileMode);
123 if (ret == 0) {
124 return 0;
125 } else {
126 wpa_printf(
127 MSG_ERROR, "Cannot set RW to %s. Errno: %s",
128 config_file_path.c_str(), strerror(errno));
129 return -1;
130 }
131 } else if (errno != ENOENT) {
132 wpa_printf(
133 MSG_ERROR, "Cannot acces %s. Errno: %s",
134 config_file_path.c_str(), strerror(errno));
135 return -1;
136 }
137 ret = copyFileIfItExists(old_config_file_path, config_file_path);
138 if (ret == 0) {
139 wpa_printf(
140 MSG_INFO, "Migrated conf file from %s to %s",
141 old_config_file_path.c_str(), config_file_path.c_str());
142 unlink(old_config_file_path.c_str());
143 return 0;
144 } else if (ret == -1) {
145 unlink(config_file_path.c_str());
146 return -1;
147 }
Jooyung Hanbd916f82024-02-22 14:17:39 +0900148 std::string vendor_template_conf_path = resolveVendorConfPath(kVendorTemplateConfPath);
149 ret = copyFileIfItExists(vendor_template_conf_path, config_file_path);
Jooyung Han40d8f1a2024-02-22 13:30:57 +0900150 if (ret == 0) {
151 wpa_printf(
152 MSG_INFO, "Copied template conf file from %s to %s",
Jooyung Hanbd916f82024-02-22 14:17:39 +0900153 vendor_template_conf_path.c_str(), config_file_path.c_str());
Jooyung Han40d8f1a2024-02-22 13:30:57 +0900154 return 0;
155 } else if (ret == -1) {
156 unlink(config_file_path.c_str());
157 return -1;
158 }
159 ret = copyFileIfItExists(kSystemTemplateConfPath, config_file_path);
160 if (ret == 0) {
161 wpa_printf(
162 MSG_INFO, "Copied template conf file from %s to %s",
163 kSystemTemplateConfPath, config_file_path.c_str());
164 return 0;
165 } else if (ret == -1) {
166 unlink(config_file_path.c_str());
167 return -1;
Gabriel Biren57ededa2021-09-03 16:08:50 +0000168 }
169 // Did not create the conf file.
170 return -1;
171}
172} // namespace
173
174namespace aidl {
175namespace android {
176namespace hardware {
177namespace wifi {
178namespace supplicant {
179using aidl_return_util::validateAndCall;
180using misc_utils::createStatus;
181using misc_utils::createStatusWithMsg;
182
183Supplicant::Supplicant(struct wpa_global* global) : wpa_global_(global) {}
184bool Supplicant::isValid()
185{
186 // This top level object cannot be invalidated.
187 return true;
188}
189
190::ndk::ScopedAStatus Supplicant::addP2pInterface(
191 const std::string& in_name,
192 std::shared_ptr<ISupplicantP2pIface>* _aidl_return)
193{
194 return validateAndCall(
195 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
196 &Supplicant::addP2pInterfaceInternal, _aidl_return, in_name);
197}
198
199::ndk::ScopedAStatus Supplicant::addStaInterface(
200 const std::string& in_name,
201 std::shared_ptr<ISupplicantStaIface>* _aidl_return)
202{
203 return validateAndCall(
204 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
205 &Supplicant::addStaInterfaceInternal, _aidl_return, in_name);
206}
207
208::ndk::ScopedAStatus Supplicant::removeInterface(
209 const IfaceInfo& in_ifaceInfo)
210{
211 return validateAndCall(
212 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
213 &Supplicant::removeInterfaceInternal, in_ifaceInfo);
214}
215
216::ndk::ScopedAStatus Supplicant::getP2pInterface(
217 const std::string& in_name,
218 std::shared_ptr<ISupplicantP2pIface>* _aidl_return)
219{
220 return validateAndCall(
221 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
222 &Supplicant::getP2pInterfaceInternal, _aidl_return, in_name);
223}
224
225::ndk::ScopedAStatus Supplicant::getStaInterface(
226 const std::string& in_name,
227 std::shared_ptr<ISupplicantStaIface>* _aidl_return)
228{
229 return validateAndCall(
230 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
231 &Supplicant::getStaInterfaceInternal, _aidl_return, in_name);
232}
233
234::ndk::ScopedAStatus Supplicant::listInterfaces(
235 std::vector<IfaceInfo>* _aidl_return)
236{
237 return validateAndCall(
238 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
239 &Supplicant::listInterfacesInternal, _aidl_return);
240}
241
242::ndk::ScopedAStatus Supplicant::registerCallback(
243 const std::shared_ptr<ISupplicantCallback>& in_callback)
244{
245 return validateAndCall(
246 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
247 &Supplicant::registerCallbackInternal, in_callback);
248}
249
Gabriel Birence222d72022-12-09 01:03:10 +0000250::ndk::ScopedAStatus Supplicant::registerNonStandardCertCallback(
251 const std::shared_ptr<INonStandardCertCallback>& in_callback)
252{
253 return validateAndCall(
254 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
255 &Supplicant::registerNonStandardCertCallbackInternal, in_callback);
256}
257
Gabriel Biren57ededa2021-09-03 16:08:50 +0000258::ndk::ScopedAStatus Supplicant::setDebugParams(
259 DebugLevel in_level, bool in_showTimestamp,
260 bool in_showKeys)
261{
262 return validateAndCall(
263 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
264 &Supplicant::setDebugParamsInternal, in_level,
265 in_showTimestamp, in_showKeys);
266}
267
268::ndk::ScopedAStatus Supplicant::setConcurrencyPriority(
269 IfaceType in_type)
270{
271 return validateAndCall(
272 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
273 &Supplicant::setConcurrencyPriorityInternal, in_type);
274}
275
276::ndk::ScopedAStatus Supplicant::getDebugLevel(DebugLevel* _aidl_return)
277{
278 *_aidl_return = static_cast<DebugLevel>(wpa_debug_level);
279 return ndk::ScopedAStatus::ok();
280}
281
282::ndk::ScopedAStatus Supplicant::isDebugShowTimestampEnabled(bool* _aidl_return)
283{
284 *_aidl_return = ((wpa_debug_timestamp != 0) ? true : false);
285 return ndk::ScopedAStatus::ok();
286}
287
288::ndk::ScopedAStatus Supplicant::isDebugShowKeysEnabled(bool* _aidl_return)
289{
290 *_aidl_return = ((wpa_debug_show_keys != 0) ? true : false);
291 return ndk::ScopedAStatus::ok();
292}
293
294::ndk::ScopedAStatus Supplicant::terminate()
295{
296 wpa_printf(MSG_INFO, "Terminating...");
297 wpa_supplicant_terminate_proc(wpa_global_);
298 return ndk::ScopedAStatus::ok();
299}
300
301ndk::ScopedAStatus Supplicant::addP2pDevInterface(struct wpa_interface iface_params)
302{
303 char primary_ifname[IFNAMSIZ];
304 u32 primary_ifname_len =
305 strlen(iface_params.ifname) - strlen(P2P_MGMT_DEVICE_PREFIX);
306
307 if(primary_ifname_len > IFNAMSIZ) {
308 wpa_printf(MSG_DEBUG, "%s, Invalid primary iface name ", __FUNCTION__);
309 return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
310 }
311
312 strncpy(primary_ifname, iface_params.ifname +
313 strlen(P2P_MGMT_DEVICE_PREFIX), primary_ifname_len);
314 wpa_printf(MSG_DEBUG, "%s, Initialize p2p-dev-wlan0 iface with"
315 "primary_iface = %s", __FUNCTION__, primary_ifname);
316 struct wpa_supplicant* wpa_s =
317 wpa_supplicant_get_iface(wpa_global_, primary_ifname);
318 if (!wpa_s) {
319 wpa_printf(MSG_DEBUG, "%s,NULL wpa_s for wlan0", __FUNCTION__);
320 return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
321 }
Jimmy Chen44a0f2c2022-07-11 23:49:12 +0800322
323 const u8 *if_addr = NULL;
324 char force_name[100] = {'\0'};
325 wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
326 if (wpa_s->conf->p2p_device_random_mac_addr == 2 &&
327 !is_zero_ether_addr(wpa_s->conf->p2p_device_persistent_mac_addr))
328 if_addr = wpa_s->conf->p2p_device_persistent_mac_addr;
329
330 int ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, iface_params.ifname, if_addr, NULL,
331 force_name, wpa_s->pending_interface_addr, NULL);
332 if (ret < 0) {
333 wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
334 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
335 }
336
337 os_strlcpy(wpa_s->pending_interface_name, iface_params.ifname,
338 sizeof(wpa_s->pending_interface_name));
339 iface_params.p2p_mgmt = 1;
340 iface_params.driver_param = wpa_s->conf->driver_param;
341 iface_params.ctrl_interface = NULL;
342
343 struct wpa_supplicant *p2pdev_wpa_s = wpa_supplicant_add_iface(
344 wpa_s->global, &iface_params, wpa_s);
345
346 if (!p2pdev_wpa_s) {
Gabriel Biren57ededa2021-09-03 16:08:50 +0000347 wpa_printf(MSG_INFO,
348 "Failed to enable P2P Device");
349 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
350 }
Jimmy Chen44a0f2c2022-07-11 23:49:12 +0800351 p2pdev_wpa_s->p2pdev = p2pdev_wpa_s;
352 wpa_s->pending_interface_name[0] = '\0';
353
Gabriel Biren57ededa2021-09-03 16:08:50 +0000354 return ndk::ScopedAStatus::ok();
355}
356
357std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
358Supplicant::addP2pInterfaceInternal(const std::string& name)
359{
360 std::shared_ptr<ISupplicantP2pIface> iface;
361
362 // Check if required |ifname| argument is empty.
363 if (name.empty()) {
364 return {nullptr, createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
365 }
Jimmy Chen44a0f2c2022-07-11 23:49:12 +0800366 if (strncmp(name.c_str(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
367 struct wpa_supplicant* wpa_s = wpa_supplicant_get_iface(wpa_global_, name.c_str());
368 if (wpa_s) {
369 wpa_printf(MSG_DEBUG, "Remove existing p2p dev interface");
370 wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0);
371 }
372 }
Gabriel Biren57ededa2021-09-03 16:08:50 +0000373 // Try to get the wpa_supplicant record for this iface, return
374 // the iface object with the appropriate status code if it exists.
375 ndk::ScopedAStatus status;
376 std::tie(iface, status) = getP2pInterfaceInternal(name);
377 if (status.isOk()) {
378 wpa_printf(MSG_INFO, "Iface already exists, return existing");
379 return {iface, ndk::ScopedAStatus::ok()};
380 }
381
382 struct wpa_interface iface_params = {};
383 iface_params.driver = kIfaceDriverName;
384 if (ensureConfigFileExists(
385 kP2pIfaceConfPath, kOldP2pIfaceConfPath) != 0) {
386 wpa_printf(
387 MSG_ERROR, "Conf file does not exists: %s",
388 kP2pIfaceConfPath);
389 return {nullptr, createStatusWithMsg(
390 SupplicantStatusCode::FAILURE_UNKNOWN, "Conf file does not exist")};
391 }
392 iface_params.confname = kP2pIfaceConfPath;
Jooyung Hanbd916f82024-02-22 14:17:39 +0900393 std::string overlay_path = resolveVendorConfPath(kP2pIfaceConfOverlayPath);
394 int ret = access(overlay_path.c_str(), R_OK);
Jooyung Han40d8f1a2024-02-22 13:30:57 +0900395 if (ret == 0) {
Jooyung Hanbd916f82024-02-22 14:17:39 +0900396 iface_params.confanother = overlay_path.c_str();
Gabriel Biren57ededa2021-09-03 16:08:50 +0000397 }
398
399 iface_params.ifname = name.c_str();
400 if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
401 strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
402 status = addP2pDevInterface(iface_params);
403 if (!status.isOk()) {
404 return {iface, createStatus(static_cast<SupplicantStatusCode>(
405 status.getServiceSpecificError()))};
406 }
407 } else {
408 struct wpa_supplicant* wpa_s =
409 wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
410 if (!wpa_s) {
411 return {nullptr, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
412 }
413 // Request the current scan results from the driver and update
414 // the local BSS list wpa_s->bss. This is to avoid a full scan
415 // while processing the connect request on newly created interface.
416 wpa_supplicant_update_scan_results(wpa_s);
417 }
418 // The supplicant core creates a corresponding aidl object via
419 // AidlManager when |wpa_supplicant_add_iface| is called.
420 return getP2pInterfaceInternal(name);
421}
422
423std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
424Supplicant::addStaInterfaceInternal(const std::string& name)
425{
426 std::shared_ptr<ISupplicantStaIface> iface;
427
428 // Check if required |ifname| argument is empty.
429 if (name.empty()) {
430 return {nullptr, createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
431 }
432 // Try to get the wpa_supplicant record for this iface, return
433 // the iface object with the appropriate status code if it exists.
434 ndk::ScopedAStatus status;
435 std::tie(iface, status) = getStaInterfaceInternal(name);
436 if (status.isOk()) {
437 wpa_printf(MSG_INFO, "Iface already exists, return existing");
438 return {iface, ndk::ScopedAStatus::ok()};
439 }
440
441 struct wpa_interface iface_params = {};
442 iface_params.driver = kIfaceDriverName;
443 if (ensureConfigFileExists(
444 kStaIfaceConfPath, kOldStaIfaceConfPath) != 0) {
445 wpa_printf(
446 MSG_ERROR, "Conf file does not exists: %s",
447 kStaIfaceConfPath);
448 return {nullptr, createStatusWithMsg(
449 SupplicantStatusCode::FAILURE_UNKNOWN, "Conf file does not exist")};
450 }
451 iface_params.confname = kStaIfaceConfPath;
Jooyung Hanbd916f82024-02-22 14:17:39 +0900452 std::string overlay_path = resolveVendorConfPath(kStaIfaceConfOverlayPath);
453 int ret = access(overlay_path.c_str(), R_OK);
Jooyung Han40d8f1a2024-02-22 13:30:57 +0900454 if (ret == 0) {
Jooyung Hanbd916f82024-02-22 14:17:39 +0900455 iface_params.confanother = overlay_path.c_str();
Gabriel Biren57ededa2021-09-03 16:08:50 +0000456 }
457
458 iface_params.ifname = name.c_str();
459 if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
460 strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
461 status = addP2pDevInterface(iface_params);
462 if (!status.isOk()) {
463 return {iface, createStatus(static_cast<SupplicantStatusCode>(
464 status.getServiceSpecificError()))};
465 }
466 } else {
467 struct wpa_supplicant* wpa_s =
468 wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
469 if (!wpa_s) {
470 return {nullptr, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
471 }
472 // Request the current scan results from the driver and update
473 // the local BSS list wpa_s->bss. This is to avoid a full scan
474 // while processing the connect request on newly created interface.
475 wpa_supplicant_update_scan_results(wpa_s);
476 }
477 // The supplicant core creates a corresponding aidl object via
478 // AidlManager when |wpa_supplicant_add_iface| is called.
479 return getStaInterfaceInternal(name);
480}
481
482ndk::ScopedAStatus Supplicant::removeInterfaceInternal(
483 const IfaceInfo& iface_info)
484{
485 struct wpa_supplicant* wpa_s =
486 wpa_supplicant_get_iface(wpa_global_, iface_info.name.c_str());
487 if (!wpa_s) {
488 return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
489 }
490 if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
491 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
492 }
493 return ndk::ScopedAStatus::ok();
494}
495
496std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
497Supplicant::getP2pInterfaceInternal(const std::string& name)
498{
499 struct wpa_supplicant* wpa_s =
500 wpa_supplicant_get_iface(wpa_global_, name.c_str());
501 if (!wpa_s) {
502 return {nullptr, createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
503 }
504 AidlManager* aidl_manager = AidlManager::getInstance();
505 std::shared_ptr<ISupplicantP2pIface> iface;
506 if (!aidl_manager ||
507 aidl_manager->getP2pIfaceAidlObjectByIfname(
508 wpa_s->ifname, &iface)) {
509 return {iface, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
510 }
511 // Set this flag true here, since there is no AIDL initialize
512 // method for the p2p config, and the supplicant interface is
513 // not ready when the p2p iface is created.
514 wpa_s->conf->persistent_reconnect = true;
515 return {iface, ndk::ScopedAStatus::ok()};
516}
517
518std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
519Supplicant::getStaInterfaceInternal(const std::string& name)
520{
521 struct wpa_supplicant* wpa_s =
522 wpa_supplicant_get_iface(wpa_global_, name.c_str());
523 if (!wpa_s) {
524 return {nullptr, createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
525 }
526 AidlManager* aidl_manager = AidlManager::getInstance();
527 std::shared_ptr<ISupplicantStaIface> iface;
528 if (!aidl_manager ||
529 aidl_manager->getStaIfaceAidlObjectByIfname(
530 wpa_s->ifname, &iface)) {
531 return {iface, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
532 }
533 return {iface, ndk::ScopedAStatus::ok()};
534}
535
536std::pair<std::vector<IfaceInfo>, ndk::ScopedAStatus>
537Supplicant::listInterfacesInternal()
538{
539 std::vector<IfaceInfo> ifaces;
540 for (struct wpa_supplicant* wpa_s = wpa_global_->ifaces; wpa_s;
541 wpa_s = wpa_s->next) {
542 if (wpa_s->global->p2p_init_wpa_s == wpa_s) {
543 ifaces.emplace_back(IfaceInfo{
544 IfaceType::P2P, wpa_s->ifname});
545 } else {
546 ifaces.emplace_back(IfaceInfo{
547 IfaceType::STA, wpa_s->ifname});
548 }
549 }
550 return {std::move(ifaces), ndk::ScopedAStatus::ok()};
551}
552
553ndk::ScopedAStatus Supplicant::registerCallbackInternal(
554 const std::shared_ptr<ISupplicantCallback>& callback)
555{
556 AidlManager* aidl_manager = AidlManager::getInstance();
557 if (!aidl_manager ||
558 aidl_manager->addSupplicantCallbackAidlObject(callback)) {
559 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
560 }
561 return ndk::ScopedAStatus::ok();
562}
563
Gabriel Birence222d72022-12-09 01:03:10 +0000564ndk::ScopedAStatus Supplicant::registerNonStandardCertCallbackInternal(
565 const std::shared_ptr<INonStandardCertCallback>& callback)
566{
567 AidlManager* aidl_manager = AidlManager::getInstance();
568 if (!aidl_manager ||
569 aidl_manager->registerNonStandardCertCallbackAidlObject(callback)) {
570 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
571 }
572 return ndk::ScopedAStatus::ok();
573}
574
Gabriel Biren57ededa2021-09-03 16:08:50 +0000575ndk::ScopedAStatus Supplicant::setDebugParamsInternal(
576 DebugLevel level, bool show_timestamp, bool show_keys)
577{
578 if (wpa_supplicant_set_debug_params(
579 wpa_global_, static_cast<uint32_t>(level), show_timestamp,
580 show_keys)) {
581 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
582 }
583 return ndk::ScopedAStatus::ok();
584}
585
586ndk::ScopedAStatus Supplicant::setConcurrencyPriorityInternal(IfaceType type)
587{
588 if (type == IfaceType::STA) {
589 wpa_global_->conc_pref =
590 wpa_global::wpa_conc_pref::WPA_CONC_PREF_STA;
591 } else if (type == IfaceType::P2P) {
592 wpa_global_->conc_pref =
593 wpa_global::wpa_conc_pref::WPA_CONC_PREF_P2P;
594 } else {
595 return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
596 }
597 return ndk::ScopedAStatus::ok();
598}
599} // namespace supplicant
600} // namespace wifi
601} // namespace hardware
602} // namespace android
603} // namespace aidl