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