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