• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant - Sta Iface 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 "iface_config_utils.h"
12 #include "misc_utils.h"
13 #include "sta_iface.h"
14 
15 extern "C"
16 {
17 #include "utils/eloop.h"
18 #include "gas_query.h"
19 #include "interworking.h"
20 #include "hs20_supplicant.h"
21 #include "wps_supplicant.h"
22 #include "dpp.h"
23 #include "dpp_supplicant.h"
24 #include "rsn_supp/wpa.h"
25 #include "rsn_supp/pmksa_cache.h"
26 }
27 
28 namespace {
29 using aidl::android::hardware::wifi::supplicant::AidlManager;
30 using aidl::android::hardware::wifi::supplicant::BtCoexistenceMode;
31 using aidl::android::hardware::wifi::supplicant::ConnectionCapabilities;
32 using aidl::android::hardware::wifi::supplicant::DppCurve;
33 using aidl::android::hardware::wifi::supplicant::DppResponderBootstrapInfo;
34 using aidl::android::hardware::wifi::supplicant::ISupplicant;
35 using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
36 using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
37 using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
38 using aidl::android::hardware::wifi::supplicant::LegacyMode;
39 using aidl::android::hardware::wifi::supplicant::RxFilterType;
40 using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
41 using aidl::android::hardware::wifi::supplicant::WifiTechnology;
42 using aidl::android::hardware::wifi::supplicant::misc_utils::createStatus;
43 
44 // TODO (b/204810426): Import from wifi vendor AIDL interface when it exists
45 enum WifiChannelWidthInMhz {
46   WIDTH_20	= 0,
47   WIDTH_40	= 1,
48   WIDTH_80	= 2,
49   WIDTH_160   = 3,
50   WIDTH_80P80 = 4,
51   WIDTH_5	 = 5,
52   WIDTH_10	= 6,
53   WIDTH_INVALID = -1
54 };
55 
56 constexpr uint32_t kMaxAnqpElems = 100;
57 constexpr char kGetMacAddress[] = "MACADDR";
58 constexpr char kStartRxFilter[] = "RXFILTER-START";
59 constexpr char kStopRxFilter[] = "RXFILTER-STOP";
60 constexpr char kAddRxFilter[] = "RXFILTER-ADD";
61 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
62 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
63 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
64 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
65 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
66 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
67 constexpr char kSetCountryCode[] = "COUNTRY";
68 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec =
69 	static_cast<uint32_t>(ISupplicant::EXT_RADIO_WORK_TIMEOUT_IN_SECS);
70 constexpr char kExtRadioWorkNamePrefix[] = "ext:";
71 
convertAidlRxFilterTypeToInternal(RxFilterType type)72 uint8_t convertAidlRxFilterTypeToInternal(
73 	RxFilterType type)
74 {
75 	switch (type) {
76 	case RxFilterType::V4_MULTICAST:
77 		return 2;
78 	case RxFilterType::V6_MULTICAST:
79 		return 3;
80 	};
81 	WPA_ASSERT(false);
82 }
83 
convertAidlBtCoexModeToInternal(BtCoexistenceMode mode)84 uint8_t convertAidlBtCoexModeToInternal(
85 	BtCoexistenceMode mode)
86 {
87 	switch (mode) {
88 	case BtCoexistenceMode::ENABLED:
89 		return 0;
90 	case BtCoexistenceMode::DISABLED:
91 		return 1;
92 	case BtCoexistenceMode::SENSE:
93 		return 2;
94 	};
95 	WPA_ASSERT(false);
96 }
97 
doZeroArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd)98 ndk::ScopedAStatus doZeroArgDriverCommand(
99 	struct wpa_supplicant *wpa_s, const char *cmd)
100 {
101 	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
102 	char driver_cmd_reply_buf[4096] = {};
103 	if (wpa_drv_driver_cmd(
104 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
105 		sizeof(driver_cmd_reply_buf))) {
106 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
107 	}
108 	return ndk::ScopedAStatus::ok();
109 }
110 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,uint8_t arg)111 ndk::ScopedAStatus doOneArgDriverCommand(
112 	struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
113 {
114 	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
115 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
116 }
117 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,const std::string & arg)118 ndk::ScopedAStatus doOneArgDriverCommand(
119 	struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
120 {
121 	std::string cmd_str = std::string(cmd) + " " + arg;
122 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
123 }
124 
endExtRadioWork(struct wpa_radio_work * work)125 void endExtRadioWork(struct wpa_radio_work *work)
126 {
127 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
128 	work->wpa_s->ext_work_in_progress = 0;
129 	radio_work_done(work);
130 	os_free(ework);
131 }
132 
extRadioWorkTimeoutCb(void * eloop_ctx,void * timeout_ctx)133 void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
134 {
135 	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
136 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
137 	wpa_dbg(
138 		work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
139 		ework->id, work->type);
140 
141 	AidlManager *aidl_manager = AidlManager::getInstance();
142 	WPA_ASSERT(aidl_manager);
143 	aidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
144 
145 	endExtRadioWork(work);
146 }
147 
startExtRadioWork(struct wpa_radio_work * work)148 void startExtRadioWork(struct wpa_radio_work *work)
149 {
150 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
151 	work->wpa_s->ext_work_in_progress = 1;
152 	if (!ework->timeout) {
153 		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
154 	}
155 	eloop_register_timeout(
156 		ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
157 }
158 
extRadioWorkStartCb(struct wpa_radio_work * work,int deinit)159 void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
160 {
161 	// deinit==1 is invoked during interface removal. Since the AIDL
162 	// interface does not support interface addition/removal, we don't
163 	// need to handle this scenario.
164 	WPA_ASSERT(!deinit);
165 
166 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
167 	wpa_dbg(
168 		work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
169 		ework->id, ework->type);
170 
171 	AidlManager *aidl_manager = AidlManager::getInstance();
172 	WPA_ASSERT(aidl_manager);
173 	aidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
174 
175 	startExtRadioWork(work);
176 }
177 
convertWpaKeyMgmtCapabilitiesToAidl(struct wpa_supplicant * wpa_s,struct wpa_driver_capa * capa)178 KeyMgmtMask convertWpaKeyMgmtCapabilitiesToAidl (
179 	struct wpa_supplicant *wpa_s, struct wpa_driver_capa *capa) {
180 
181 	uint32_t mask = 0;
182 	/* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability
183 	 * flags and always enabled.
184 	 */
185 	mask |=
186 		(static_cast<uint32_t>(KeyMgmtMask::NONE) |
187 		 static_cast<uint32_t>(KeyMgmtMask::IEEE8021X));
188 
189 	if (capa->key_mgmt &
190 		(WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
191 		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_EAP);
192 	}
193 
194 	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
195 				 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
196 		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_PSK);
197 	}
198 #ifdef CONFIG_SUITEB192
199 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
200 		mask |= static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192);
201 	}
202 #endif /* CONFIG_SUITEB192 */
203 #ifdef CONFIG_OWE
204 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
205 		mask |= static_cast<uint32_t>(KeyMgmtMask::OWE);
206 	}
207 #endif /* CONFIG_OWE */
208 #ifdef CONFIG_SAE
209 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
210 		mask |= static_cast<uint32_t>(KeyMgmtMask::SAE);
211 	}
212 #endif /* CONFIG_SAE */
213 #ifdef CONFIG_DPP
214 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
215 		mask |= static_cast<uint32_t>(KeyMgmtMask::DPP);
216 	}
217 #endif
218 #ifdef CONFIG_WAPI_INTERFACE
219 	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK);
220 	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT);
221 #endif /* CONFIG_WAPI_INTERFACE */
222 #ifdef CONFIG_FILS
223 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
224 		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256);
225 	}
226 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
227 		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384);
228 	}
229 #endif /* CONFIG_FILS */
230 	return static_cast<KeyMgmtMask>(mask);
231 }
232 
getDppListenChannel(struct wpa_supplicant * wpa_s,int32_t * listen_channel)233 const std::string getDppListenChannel(struct wpa_supplicant *wpa_s, int32_t *listen_channel)
234 {
235 	struct hostapd_hw_modes *mode;
236 	int chan44 = 0, chan149 = 0;
237 	*listen_channel = 0;
238 
239 	/* Check if device support 2.4GHz band*/
240 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
241 			HOSTAPD_MODE_IEEE80211G, 0);
242 	if (mode) {
243 		*listen_channel = 6;
244 		return "81/6";
245 	}
246 	/* Check if device support 5GHz band */
247 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
248 			HOSTAPD_MODE_IEEE80211A, 0);
249 	if (mode) {
250 		for (int i = 0; i < mode->num_channels; i++) {
251 			struct hostapd_channel_data *chan = &mode->channels[i];
252 
253 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
254 					  HOSTAPD_CHAN_RADAR))
255 				continue;
256 			if (chan->freq == 5220)
257 				chan44 = 1;
258 			if (chan->freq == 5745)
259 				chan149 = 1;
260 		}
261 		if (chan149) {
262 			*listen_channel = 149;
263 			return "124/149";
264 		} else if (chan44) {
265 			*listen_channel = 44;
266 			return "115/44";
267 		}
268 	}
269 
270 	return "";
271 }
272 
convertCurveTypeToName(DppCurve curve)273 const std::string convertCurveTypeToName(DppCurve curve)
274 {
275 	switch (curve) {
276 	case DppCurve::PRIME256V1:
277 		return "prime256v1";
278 	case DppCurve::SECP384R1:
279 		return "secp384r1";
280 	case DppCurve::SECP521R1:
281 		return "secp521r1";
282 	case DppCurve::BRAINPOOLP256R1:
283 		return "brainpoolP256r1";
284 	case DppCurve::BRAINPOOLP384R1:
285 		return "brainpoolP384r1";
286 	case DppCurve::BRAINPOOLP512R1:
287 		return "brainpoolP512r1";
288 	}
289 	WPA_ASSERT(false);
290 }
291 
292 }  // namespace
293 
294 namespace aidl {
295 namespace android {
296 namespace hardware {
297 namespace wifi {
298 namespace supplicant {
299 using aidl_return_util::validateAndCall;
300 using misc_utils::createStatus;
301 
StaIface(struct wpa_global * wpa_global,const char ifname[])302 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
303 	: wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
304 {}
305 
invalidate()306 void StaIface::invalidate() { is_valid_ = false; }
isValid()307 bool StaIface::isValid()
308 {
309 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
310 }
311 
getName(std::string * _aidl_return)312 ::ndk::ScopedAStatus StaIface::getName(
313 	std::string* _aidl_return)
314 {
315 	return validateAndCall(
316 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
317 		&StaIface::getNameInternal, _aidl_return);
318 }
319 
getType(IfaceType * _aidl_return)320 ::ndk::ScopedAStatus StaIface::getType(
321 	IfaceType* _aidl_return)
322 {
323 	return validateAndCall(
324 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
325 		&StaIface::getTypeInternal, _aidl_return);
326 }
327 
addNetwork(std::shared_ptr<ISupplicantStaNetwork> * _aidl_return)328 ::ndk::ScopedAStatus StaIface::addNetwork(
329 	std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
330 {
331 	return validateAndCall(
332 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
333 		&StaIface::addNetworkInternal, _aidl_return);
334 }
335 
removeNetwork(int32_t in_id)336 ::ndk::ScopedAStatus StaIface::removeNetwork(
337 	int32_t in_id)
338 {
339 	return validateAndCall(
340 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
341 		&StaIface::removeNetworkInternal, in_id);
342 }
343 
filsHlpFlushRequest()344 ::ndk::ScopedAStatus StaIface::filsHlpFlushRequest()
345 {
346 	return validateAndCall(
347 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
348 		&StaIface::filsHlpFlushRequestInternal);
349 }
350 
filsHlpAddRequest(const std::vector<uint8_t> & in_dst_mac,const std::vector<uint8_t> & in_pkt)351 ::ndk::ScopedAStatus StaIface::filsHlpAddRequest(
352 	const std::vector<uint8_t>& in_dst_mac,
353 	const std::vector<uint8_t>& in_pkt)
354 {
355 	return validateAndCall(
356 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
357 		&StaIface::filsHlpAddRequestInternal, in_dst_mac, in_pkt);
358 }
359 
getNetwork(int32_t in_id,std::shared_ptr<ISupplicantStaNetwork> * _aidl_return)360 ::ndk::ScopedAStatus StaIface::getNetwork(
361 	int32_t in_id, std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
362 {
363 	return validateAndCall(
364 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
365 		&StaIface::getNetworkInternal, _aidl_return, in_id);
366 }
367 
listNetworks(std::vector<int32_t> * _aidl_return)368 ::ndk::ScopedAStatus StaIface::listNetworks(
369 	std::vector<int32_t>* _aidl_return)
370 {
371 	return validateAndCall(
372 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
373 		&StaIface::listNetworksInternal, _aidl_return);
374 }
375 
registerCallback(const std::shared_ptr<ISupplicantStaIfaceCallback> & in_callback)376 ::ndk::ScopedAStatus StaIface::registerCallback(
377 	const std::shared_ptr<ISupplicantStaIfaceCallback>& in_callback)
378 {
379 	return validateAndCall(
380 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
381 		&StaIface::registerCallbackInternal, in_callback);
382 }
383 
reassociate()384 ::ndk::ScopedAStatus StaIface::reassociate()
385 {
386 	return validateAndCall(
387 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
388 		&StaIface::reassociateInternal);
389 }
390 
reconnect()391 ::ndk::ScopedAStatus StaIface::reconnect()
392 {
393 	return validateAndCall(
394 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
395 		&StaIface::reconnectInternal);
396 }
397 
disconnect()398 ::ndk::ScopedAStatus StaIface::disconnect()
399 {
400 	return validateAndCall(
401 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
402 		&StaIface::disconnectInternal);
403 }
404 
setPowerSave(bool in_enable)405 ::ndk::ScopedAStatus StaIface::setPowerSave(
406 	bool in_enable)
407 {
408 	return validateAndCall(
409 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
410 		&StaIface::setPowerSaveInternal, in_enable);
411 }
412 
initiateTdlsDiscover(const std::vector<uint8_t> & in_macAddress)413 ::ndk::ScopedAStatus StaIface::initiateTdlsDiscover(
414 	const std::vector<uint8_t>& in_macAddress)
415 {
416 	return validateAndCall(
417 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
418 		&StaIface::initiateTdlsDiscoverInternal, in_macAddress);
419 }
420 
initiateTdlsSetup(const std::vector<uint8_t> & in_macAddress)421 ::ndk::ScopedAStatus StaIface::initiateTdlsSetup(
422 	const std::vector<uint8_t>& in_macAddress)
423 {
424 	return validateAndCall(
425 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
426 		&StaIface::initiateTdlsSetupInternal, in_macAddress);
427 }
428 
initiateTdlsTeardown(const std::vector<uint8_t> & in_macAddress)429 ::ndk::ScopedAStatus StaIface::initiateTdlsTeardown(
430 	const std::vector<uint8_t>& in_macAddress)
431 {
432 	return validateAndCall(
433 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
434 		&StaIface::initiateTdlsTeardownInternal, in_macAddress);
435 }
436 
initiateAnqpQuery(const std::vector<uint8_t> & in_macAddress,const std::vector<AnqpInfoId> & in_infoElements,const std::vector<Hs20AnqpSubtypes> & in_subTypes)437 ::ndk::ScopedAStatus StaIface::initiateAnqpQuery(
438 	const std::vector<uint8_t>& in_macAddress,
439 	const std::vector<AnqpInfoId>& in_infoElements,
440 	const std::vector<Hs20AnqpSubtypes>& in_subTypes)
441 {
442 	return validateAndCall(
443 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
444 		&StaIface::initiateAnqpQueryInternal, in_macAddress,
445 		in_infoElements, in_subTypes);
446 }
447 
initiateVenueUrlAnqpQuery(const std::vector<uint8_t> & in_macAddress)448 ::ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQuery(
449 	const std::vector<uint8_t>& in_macAddress)
450 {
451 	return validateAndCall(
452 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
453 		&StaIface::initiateVenueUrlAnqpQueryInternal, in_macAddress);
454 }
455 
initiateHs20IconQuery(const std::vector<uint8_t> & in_macAddress,const std::string & in_fileName)456 ::ndk::ScopedAStatus StaIface::initiateHs20IconQuery(
457 	const std::vector<uint8_t>& in_macAddress,
458 	const std::string& in_fileName)
459 {
460 	return validateAndCall(
461 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
462 		&StaIface::initiateHs20IconQueryInternal, in_macAddress,
463 		in_fileName);
464 }
465 
getMacAddress(std::vector<uint8_t> * _aidl_return)466 ::ndk::ScopedAStatus StaIface::getMacAddress(
467 	std::vector<uint8_t>* _aidl_return)
468 {
469 	return validateAndCall(
470 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
471 		&StaIface::getMacAddressInternal, _aidl_return);
472 }
473 
startRxFilter()474 ::ndk::ScopedAStatus StaIface::startRxFilter()
475 {
476 	return validateAndCall(
477 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
478 		&StaIface::startRxFilterInternal);
479 }
480 
stopRxFilter()481 ::ndk::ScopedAStatus StaIface::stopRxFilter()
482 {
483 	return validateAndCall(
484 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
485 		&StaIface::stopRxFilterInternal);
486 }
487 
addRxFilter(RxFilterType in_type)488 ::ndk::ScopedAStatus StaIface::addRxFilter(
489 	RxFilterType in_type)
490 {
491 	return validateAndCall(
492 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
493 		&StaIface::addRxFilterInternal, in_type);
494 }
495 
removeRxFilter(RxFilterType in_type)496 ::ndk::ScopedAStatus StaIface::removeRxFilter(
497 	RxFilterType in_type)
498 {
499 	return validateAndCall(
500 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
501 		&StaIface::removeRxFilterInternal, in_type);
502 }
503 
setBtCoexistenceMode(BtCoexistenceMode in_mode)504 ::ndk::ScopedAStatus StaIface::setBtCoexistenceMode(
505 	BtCoexistenceMode in_mode)
506 {
507 	return validateAndCall(
508 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
509 		&StaIface::setBtCoexistenceModeInternal, in_mode);
510 }
511 
setBtCoexistenceScanModeEnabled(bool in_enable)512 ::ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabled(
513 	bool in_enable)
514 {
515 	return validateAndCall(
516 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
517 		&StaIface::setBtCoexistenceScanModeEnabledInternal,
518 		in_enable);
519 }
520 
setSuspendModeEnabled(bool in_enable)521 ::ndk::ScopedAStatus StaIface::setSuspendModeEnabled(
522 	bool in_enable)
523 {
524 	return validateAndCall(
525 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
526 		&StaIface::setSuspendModeEnabledInternal, in_enable);
527 }
528 
setCountryCode(const std::vector<uint8_t> & in_code)529 ::ndk::ScopedAStatus StaIface::setCountryCode(
530 	const std::vector<uint8_t>& in_code)
531 {
532 	return validateAndCall(
533 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
534 		&StaIface::setCountryCodeInternal, in_code);
535 }
536 
startWpsRegistrar(const std::vector<uint8_t> & in_bssid,const std::string & in_pin)537 ::ndk::ScopedAStatus StaIface::startWpsRegistrar(
538 	const std::vector<uint8_t>& in_bssid,
539 	const std::string& in_pin)
540 {
541 	return validateAndCall(
542 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
543 		&StaIface::startWpsRegistrarInternal, in_bssid, in_pin);
544 }
545 
startWpsPbc(const std::vector<uint8_t> & in_bssid)546 ::ndk::ScopedAStatus StaIface::startWpsPbc(
547 	const std::vector<uint8_t>& in_bssid)
548 {
549 	return validateAndCall(
550 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
551 		&StaIface::startWpsPbcInternal, in_bssid);
552 }
553 
startWpsPinKeypad(const std::string & in_pin)554 ::ndk::ScopedAStatus StaIface::startWpsPinKeypad(
555 	const std::string& in_pin)
556 {
557 	return validateAndCall(
558 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
559 		&StaIface::startWpsPinKeypadInternal, in_pin);
560 }
561 
startWpsPinDisplay(const std::vector<uint8_t> & in_bssid,std::string * _aidl_return)562 ::ndk::ScopedAStatus StaIface::startWpsPinDisplay(
563 	const std::vector<uint8_t>& in_bssid,
564 	std::string* _aidl_return)
565 {
566 	return validateAndCall(
567 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
568 		&StaIface::startWpsPinDisplayInternal, _aidl_return, in_bssid);
569 }
570 
cancelWps()571 ::ndk::ScopedAStatus StaIface::cancelWps()
572 {
573 	return validateAndCall(
574 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
575 		&StaIface::cancelWpsInternal);
576 }
577 
setWpsDeviceName(const std::string & in_name)578 ::ndk::ScopedAStatus StaIface::setWpsDeviceName(
579 	const std::string& in_name)
580 {
581 	return validateAndCall(
582 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
583 		&StaIface::setWpsDeviceNameInternal, in_name);
584 }
585 
setWpsDeviceType(const std::vector<uint8_t> & in_type)586 ::ndk::ScopedAStatus StaIface::setWpsDeviceType(
587 	const std::vector<uint8_t>& in_type)
588 {
589 	return validateAndCall(
590 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
591 		&StaIface::setWpsDeviceTypeInternal, in_type);
592 }
593 
setWpsManufacturer(const std::string & in_manufacturer)594 ::ndk::ScopedAStatus StaIface::setWpsManufacturer(
595 	const std::string& in_manufacturer)
596 {
597 	return validateAndCall(
598 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
599 		&StaIface::setWpsManufacturerInternal, in_manufacturer);
600 }
601 
setWpsModelName(const std::string & in_modelName)602 ::ndk::ScopedAStatus StaIface::setWpsModelName(
603 	const std::string& in_modelName)
604 {
605 	return validateAndCall(
606 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
607 		&StaIface::setWpsModelNameInternal, in_modelName);
608 }
609 
setWpsModelNumber(const std::string & in_modelNumber)610 ::ndk::ScopedAStatus StaIface::setWpsModelNumber(
611 	const std::string& in_modelNumber)
612 {
613 	return validateAndCall(
614 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
615 		&StaIface::setWpsModelNumberInternal, in_modelNumber);
616 }
617 
setWpsSerialNumber(const std::string & in_serialNumber)618 ::ndk::ScopedAStatus StaIface::setWpsSerialNumber(
619 	const std::string& in_serialNumber)
620 {
621 	return validateAndCall(
622 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
623 		&StaIface::setWpsSerialNumberInternal, in_serialNumber);
624 }
625 
setWpsConfigMethods(WpsConfigMethods in_configMethods)626 ::ndk::ScopedAStatus StaIface::setWpsConfigMethods(
627 	WpsConfigMethods in_configMethods)
628 {
629 	return validateAndCall(
630 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
631 		&StaIface::setWpsConfigMethodsInternal, in_configMethods);
632 }
633 
setExternalSim(bool in_useExternalSim)634 ::ndk::ScopedAStatus StaIface::setExternalSim(
635 	bool in_useExternalSim)
636 {
637 	return validateAndCall(
638 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
639 		&StaIface::setExternalSimInternal, in_useExternalSim);
640 }
641 
addExtRadioWork(const std::string & in_name,int32_t in_freqInMhz,int32_t in_timeoutInSec,int32_t * _aidl_return)642 ::ndk::ScopedAStatus StaIface::addExtRadioWork(
643 	const std::string& in_name, int32_t in_freqInMhz,
644 	int32_t in_timeoutInSec,
645 	int32_t* _aidl_return)
646 {
647 	return validateAndCall(
648 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
649 		&StaIface::addExtRadioWorkInternal, _aidl_return, in_name, in_freqInMhz,
650 		in_timeoutInSec);
651 }
652 
removeExtRadioWork(int32_t in_id)653 ::ndk::ScopedAStatus StaIface::removeExtRadioWork(
654 	int32_t in_id)
655 {
656 	return validateAndCall(
657 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
658 		&StaIface::removeExtRadioWorkInternal, in_id);
659 }
660 
enableAutoReconnect(bool in_enable)661 ::ndk::ScopedAStatus StaIface::enableAutoReconnect(
662 	bool in_enable)
663 {
664 	return validateAndCall(
665 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
666 		&StaIface::enableAutoReconnectInternal, in_enable);
667 }
668 
getKeyMgmtCapabilities(KeyMgmtMask * _aidl_return)669 ::ndk::ScopedAStatus StaIface::getKeyMgmtCapabilities(
670 	KeyMgmtMask* _aidl_return)
671 {
672 	return validateAndCall(
673 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
674 		&StaIface::getKeyMgmtCapabilitiesInternal, _aidl_return);
675 }
676 
addDppPeerUri(const std::string & in_uri,int32_t * _aidl_return)677 ::ndk::ScopedAStatus StaIface::addDppPeerUri(
678 	const std::string& in_uri, int32_t* _aidl_return)
679 {
680 	return validateAndCall(
681 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
682 		&StaIface::addDppPeerUriInternal, _aidl_return, in_uri);
683 }
684 
removeDppUri(int32_t in_id)685 ::ndk::ScopedAStatus StaIface::removeDppUri(
686 	int32_t in_id)
687 {
688 	return validateAndCall(
689 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
690 		&StaIface::removeDppUriInternal, in_id);
691 }
692 
startDppConfiguratorInitiator(int32_t in_peerBootstrapId,int32_t in_ownBootstrapId,const std::string & in_ssid,const std::string & in_password,const std::string & in_psk,DppNetRole in_netRole,DppAkm in_securityAkm,const std::vector<uint8_t> & in_privEcKey,std::vector<uint8_t> * _aidl_return)693 ::ndk::ScopedAStatus StaIface::startDppConfiguratorInitiator(
694 	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId,
695 	const std::string& in_ssid, const std::string& in_password,
696 	const std::string& in_psk, DppNetRole in_netRole,
697 	DppAkm in_securityAkm, const std::vector<uint8_t>& in_privEcKey,
698 	std::vector<uint8_t>* _aidl_return)
699 {
700 	return validateAndCall(
701 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
702 		&StaIface::startDppConfiguratorInitiatorInternal, _aidl_return,
703 		in_peerBootstrapId,in_ownBootstrapId, in_ssid, in_password,
704 		in_psk, in_netRole, in_securityAkm, in_privEcKey);
705 }
706 
startDppEnrolleeInitiator(int32_t in_peerBootstrapId,int32_t in_ownBootstrapId)707 ::ndk::ScopedAStatus StaIface::startDppEnrolleeInitiator(
708 	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId)
709 {
710 	return validateAndCall(
711 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
712 		&StaIface::startDppEnrolleeInitiatorInternal, in_peerBootstrapId,
713 		in_ownBootstrapId);
714 }
715 
stopDppInitiator()716 ::ndk::ScopedAStatus StaIface::stopDppInitiator()
717 {
718 	return validateAndCall(
719 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
720 		&StaIface::stopDppInitiatorInternal);
721 }
722 
getConnectionCapabilities(ConnectionCapabilities * _aidl_return)723 ::ndk::ScopedAStatus StaIface::getConnectionCapabilities(
724 	ConnectionCapabilities* _aidl_return)
725 {
726 	return validateAndCall(
727 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
728 		&StaIface::getConnectionCapabilitiesInternal,
729 		_aidl_return);
730 }
731 
generateDppBootstrapInfoForResponder(const std::vector<uint8_t> & in_macAddress,const std::string & in_deviceInfo,DppCurve in_curve,DppResponderBootstrapInfo * _aidl_return)732 ::ndk::ScopedAStatus StaIface::generateDppBootstrapInfoForResponder(
733 	const std::vector<uint8_t>& in_macAddress, const std::string& in_deviceInfo,
734 	DppCurve in_curve, DppResponderBootstrapInfo* _aidl_return)
735 {
736 	return validateAndCall(
737 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
738 		&StaIface::generateDppBootstrapInfoForResponderInternal, _aidl_return,
739 		in_macAddress, in_deviceInfo, in_curve);
740 }
741 
startDppEnrolleeResponder(int32_t in_listenChannel)742 ::ndk::ScopedAStatus StaIface::startDppEnrolleeResponder(
743 	int32_t in_listenChannel)
744 {
745 	return validateAndCall(
746 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
747 		&StaIface::startDppEnrolleeResponderInternal, in_listenChannel);
748 }
749 
stopDppResponder(int32_t in_ownBootstrapId)750 ::ndk::ScopedAStatus StaIface::stopDppResponder(
751 	int32_t in_ownBootstrapId)
752 {
753 	return validateAndCall(
754 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
755 		&StaIface::stopDppResponderInternal, in_ownBootstrapId);
756 }
757 
generateSelfDppConfiguration(const std::string & in_ssid,const std::vector<uint8_t> & in_privEcKey)758 ::ndk::ScopedAStatus StaIface::generateSelfDppConfiguration(
759 	const std::string& in_ssid, const std::vector<uint8_t>& in_privEcKey)
760 {
761 	return validateAndCall(
762 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
763 		&StaIface::generateSelfDppConfigurationInternal, in_ssid, in_privEcKey);
764 }
765 
getWpaDriverCapabilities(WpaDriverCapabilitiesMask * _aidl_return)766 ::ndk::ScopedAStatus StaIface::getWpaDriverCapabilities(
767 	WpaDriverCapabilitiesMask* _aidl_return)
768 {
769 	return validateAndCall(
770 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
771 		&StaIface::getWpaDriverCapabilitiesInternal, _aidl_return);
772 }
773 
setMboCellularDataStatus(bool in_available)774 ::ndk::ScopedAStatus StaIface::setMboCellularDataStatus(
775 	bool in_available)
776 {
777 	return validateAndCall(
778 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
779 		&StaIface::setMboCellularDataStatusInternal, in_available);
780 }
781 
setQosPolicyFeatureEnabled(bool in_enable)782 ::ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabled(
783 	bool in_enable)
784 {
785 	return validateAndCall(
786 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
787 		&StaIface::setQosPolicyFeatureEnabledInternal, in_enable);
788 }
789 
sendQosPolicyResponse(int32_t in_qosPolicyRequestId,bool in_morePolicies,const std::vector<QosPolicyStatus> & in_qosPolicyStatusList)790 ::ndk::ScopedAStatus StaIface::sendQosPolicyResponse(
791 	int32_t in_qosPolicyRequestId, bool in_morePolicies,
792 	const std::vector<QosPolicyStatus>& in_qosPolicyStatusList)
793 {
794 	return validateAndCall(
795 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
796 		&StaIface::sendQosPolicyResponseInternal, in_qosPolicyRequestId,
797 		in_morePolicies, in_qosPolicyStatusList);
798 }
799 
removeAllQosPolicies()800 ::ndk::ScopedAStatus StaIface::removeAllQosPolicies()
801 {
802 	return validateAndCall(
803 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
804 		&StaIface::removeAllQosPoliciesInternal);
805 }
806 
getConnectionMloLinksInfo(MloLinksInfo * _aidl_return)807 ::ndk::ScopedAStatus StaIface::getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) {
808 	return validateAndCall(
809 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
810 		&StaIface::getConnectionMloLinksInfoInternal, _aidl_return);
811 }
812 
getNameInternal()813 std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
814 {
815 	return {ifname_, ndk::ScopedAStatus::ok()};
816 }
817 
getTypeInternal()818 std::pair<IfaceType, ndk::ScopedAStatus> StaIface::getTypeInternal()
819 {
820 	return {IfaceType::STA, ndk::ScopedAStatus::ok()};
821 }
822 
filsHlpFlushRequestInternal()823 ndk::ScopedAStatus StaIface::filsHlpFlushRequestInternal()
824 {
825 #ifdef CONFIG_FILS
826 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
827 
828 	wpas_flush_fils_hlp_req(wpa_s);
829 	return ndk::ScopedAStatus::ok();
830 #else /* CONFIG_FILS */
831 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN, "");
832 #endif /* CONFIG_FILS */
833 }
834 
filsHlpAddRequestInternal(const std::vector<uint8_t> & dst_mac,const std::vector<uint8_t> & pkt)835 ndk::ScopedAStatus StaIface::filsHlpAddRequestInternal(
836 	const std::vector<uint8_t> &dst_mac, const std::vector<uint8_t> &pkt)
837 {
838 #ifdef CONFIG_FILS
839 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
840 	struct fils_hlp_req *req;
841 
842 	if (!pkt.size())
843 		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
844 	if (dst_mac.size() != ETH_ALEN)
845 		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
846 
847 
848 	req = (struct fils_hlp_req *)os_zalloc(sizeof(*req));
849 	if (!req)
850 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
851 
852 	os_memcpy(req->dst, dst_mac.data(), ETH_ALEN);
853 
854 	req->pkt = wpabuf_alloc_copy(pkt.data(), pkt.size());
855 	if (!req->pkt) {
856 		os_free(req);
857 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
858 	}
859 
860 	dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
861 	return ndk::ScopedAStatus::ok();
862 #else /* CONFIG_FILS */
863 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
864 #endif /* CONFIG_FILS */
865 }
866 
867 std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
addNetworkInternal()868 StaIface::addNetworkInternal()
869 {
870 	std::shared_ptr<ISupplicantStaNetwork> network;
871 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
872 	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
873 	if (!ssid) {
874 		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
875 	}
876 	AidlManager *aidl_manager = AidlManager::getInstance();
877 	if (!aidl_manager ||
878 		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
879 		wpa_s->ifname, ssid->id, &network)) {
880 		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
881 	}
882 	return {network, ndk::ScopedAStatus::ok()};
883 }
884 
removeNetworkInternal(int32_t id)885 ndk::ScopedAStatus StaIface::removeNetworkInternal(int32_t id)
886 {
887 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
888 	int result = wpa_supplicant_remove_network(wpa_s, id);
889 	if (result == -1) {
890 		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
891 	}
892 	if (result != 0) {
893 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
894 	}
895 	return ndk::ScopedAStatus::ok();
896 }
897 
898 std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
getNetworkInternal(int32_t id)899 StaIface::getNetworkInternal(int32_t id)
900 {
901 	std::shared_ptr<ISupplicantStaNetwork> network;
902 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
903 	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
904 	if (!ssid) {
905 		return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
906 	}
907 	AidlManager *aidl_manager = AidlManager::getInstance();
908 	if (!aidl_manager ||
909 		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
910 		wpa_s->ifname, ssid->id, &network)) {
911 		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
912 	}
913 	return {network, ndk::ScopedAStatus::ok()};
914 }
915 
916 std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
listNetworksInternal()917 StaIface::listNetworksInternal()
918 {
919 	std::vector<int32_t> network_ids;
920 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
921 	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
922 		 wpa_ssid = wpa_ssid->next) {
923 		network_ids.emplace_back(wpa_ssid->id);
924 	}
925 	return {std::move(network_ids), ndk::ScopedAStatus::ok()};
926 }
927 
registerCallbackInternal(const std::shared_ptr<ISupplicantStaIfaceCallback> & callback)928 ndk::ScopedAStatus StaIface::registerCallbackInternal(
929 	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
930 {
931 	AidlManager *aidl_manager = AidlManager::getInstance();
932 	if (!aidl_manager ||
933 		aidl_manager->addStaIfaceCallbackAidlObject(ifname_, callback)) {
934 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
935 	}
936 	return ndk::ScopedAStatus::ok();
937 }
938 
reassociateInternal()939 ndk::ScopedAStatus StaIface::reassociateInternal()
940 {
941 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
942 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
943 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
944 	}
945 	wpas_request_connection(wpa_s);
946 	return ndk::ScopedAStatus::ok();
947 }
948 
reconnectInternal()949 ndk::ScopedAStatus StaIface::reconnectInternal()
950 {
951 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
952 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
953 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
954 	}
955 	if (!wpa_s->disconnected) {
956 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
957 	}
958 	wpas_request_connection(wpa_s);
959 	return ndk::ScopedAStatus::ok();
960 }
961 
disconnectInternal()962 ndk::ScopedAStatus StaIface::disconnectInternal()
963 {
964 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
965 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
966 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
967 	}
968 	wpas_request_disconnection(wpa_s);
969 	return ndk::ScopedAStatus::ok();
970 }
971 
setPowerSaveInternal(bool enable)972 ndk::ScopedAStatus StaIface::setPowerSaveInternal(bool enable)
973 {
974 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
975 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
976 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
977 	}
978 	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
979 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
980 	}
981 	return ndk::ScopedAStatus::ok();
982 }
983 
initiateTdlsDiscoverInternal(const std::vector<uint8_t> & mac_address)984 ndk::ScopedAStatus StaIface::initiateTdlsDiscoverInternal(
985 	const std::vector<uint8_t> &mac_address)
986 {
987 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
988 	int ret;
989 	if (mac_address.size() != ETH_ALEN) {
990 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
991 	}
992 	const u8 *peer = mac_address.data();
993 	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
994 		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
995 	} else {
996 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
997 	}
998 	if (ret) {
999 		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
1000 	}
1001 	return ndk::ScopedAStatus::ok();
1002 }
1003 
initiateTdlsSetupInternal(const std::vector<uint8_t> & mac_address)1004 ndk::ScopedAStatus StaIface::initiateTdlsSetupInternal(
1005 	const std::vector<uint8_t> &mac_address)
1006 {
1007 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1008 	int ret;
1009 	if (mac_address.size() != ETH_ALEN) {
1010 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1011 	}
1012 	const u8 *peer = mac_address.data();
1013 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
1014 		!(wpa_s->conf->tdls_external_control)) {
1015 		wpa_tdls_remove(wpa_s->wpa, peer);
1016 		ret = wpa_tdls_start(wpa_s->wpa, peer);
1017 	} else {
1018 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
1019 	}
1020 	if (ret) {
1021 		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
1022 	}
1023 	return ndk::ScopedAStatus::ok();
1024 }
1025 
initiateTdlsTeardownInternal(const std::vector<uint8_t> & mac_address)1026 ndk::ScopedAStatus StaIface::initiateTdlsTeardownInternal(
1027 	const std::vector<uint8_t> &mac_address)
1028 {
1029 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1030 	int ret;
1031 	if (mac_address.size() != ETH_ALEN) {
1032 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1033 	}
1034 	const u8 *peer = mac_address.data();
1035 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
1036 		!(wpa_s->conf->tdls_external_control)) {
1037 		ret = wpa_tdls_teardown_link(
1038 			wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
1039 	} else {
1040 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
1041 	}
1042 	if (ret) {
1043 		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
1044 	}
1045 	return ndk::ScopedAStatus::ok();
1046 }
1047 
initiateAnqpQueryInternal(const std::vector<uint8_t> & mac_address,const std::vector<AnqpInfoId> & info_elements,const std::vector<Hs20AnqpSubtypes> & sub_types)1048 ndk::ScopedAStatus StaIface::initiateAnqpQueryInternal(
1049 	const std::vector<uint8_t> &mac_address,
1050 	const std::vector<AnqpInfoId> &info_elements,
1051 	const std::vector<Hs20AnqpSubtypes> &sub_types)
1052 {
1053 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1054 	if (info_elements.size() > kMaxAnqpElems) {
1055 		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
1056 	}
1057 	uint16_t info_elems_buf[kMaxAnqpElems];
1058 	uint32_t num_info_elems = 0;
1059 	for (const auto &info_element : info_elements) {
1060 		info_elems_buf[num_info_elems++] =
1061 			static_cast<std::underlying_type<
1062 			AnqpInfoId>::type>(info_element);
1063 	}
1064 	uint32_t sub_types_bitmask = 0;
1065 	for (const auto &type : sub_types) {
1066 		sub_types_bitmask |= BIT(
1067 			static_cast<std::underlying_type<
1068 			Hs20AnqpSubtypes>::type>(type));
1069 	}
1070 	if (mac_address.size() != ETH_ALEN) {
1071 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1072 	}
1073 
1074 	if (anqp_send_req(
1075 		wpa_s, mac_address.data(), 0, info_elems_buf, num_info_elems,
1076 		sub_types_bitmask, 0)) {
1077 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1078 	}
1079 	return ndk::ScopedAStatus::ok();
1080 }
1081 
initiateVenueUrlAnqpQueryInternal(const std::vector<uint8_t> & mac_address)1082 ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQueryInternal(
1083 	const std::vector<uint8_t> &mac_address)
1084 {
1085 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1086 	uint16_t info_elems_buf[1] = {ANQP_VENUE_URL};
1087 	if (mac_address.size() != ETH_ALEN) {
1088 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1089 	}
1090 
1091 	if (anqp_send_req(
1092 		wpa_s, mac_address.data(), 0, info_elems_buf, 1, 0, 0)) {
1093 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1094 	}
1095 	return ndk::ScopedAStatus::ok();
1096 }
1097 
initiateHs20IconQueryInternal(const std::vector<uint8_t> & mac_address,const std::string & file_name)1098 ndk::ScopedAStatus StaIface::initiateHs20IconQueryInternal(
1099 	const std::vector<uint8_t> &mac_address, const std::string &file_name)
1100 {
1101 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1102 	if (mac_address.size() != ETH_ALEN) {
1103 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1104 	}
1105 	wpa_s->fetch_osu_icon_in_progress = 0;
1106 	if (hs20_anqp_send_req(
1107 		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
1108 		reinterpret_cast<const uint8_t *>(file_name.c_str()),
1109 		file_name.size(), true)) {
1110 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1111 	}
1112 	return ndk::ScopedAStatus::ok();
1113 }
1114 
1115 std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
getMacAddressInternal()1116 StaIface::getMacAddressInternal()
1117 {
1118 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1119 	std::vector<char> cmd(
1120 		kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
1121 	char driver_cmd_reply_buf[4096] = {};
1122 	int ret = wpa_drv_driver_cmd(
1123 		wpa_s, cmd.data(), driver_cmd_reply_buf,
1124 		sizeof(driver_cmd_reply_buf));
1125 	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
1126 	std::string reply_str = driver_cmd_reply_buf;
1127 	if (ret < 0 || reply_str.empty() ||
1128 		reply_str.find("=") == std::string::npos) {
1129 		return {std::vector<uint8_t>(),
1130 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1131 	}
1132 	// Remove all whitespace first and then split using the delimiter "=".
1133 	reply_str.erase(
1134 		remove_if(reply_str.begin(), reply_str.end(), isspace),
1135 		reply_str.end());
1136 	std::string mac_addr_str =
1137 		reply_str.substr(reply_str.find("=") + 1, reply_str.size());
1138 	std::vector<uint8_t> mac_addr(6);
1139 	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
1140 		return {std::vector<uint8_t>(),
1141 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1142 	}
1143 	return {mac_addr, ndk::ScopedAStatus::ok()};
1144 }
1145 
startRxFilterInternal()1146 ndk::ScopedAStatus StaIface::startRxFilterInternal()
1147 {
1148 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
1149 }
1150 
stopRxFilterInternal()1151 ndk::ScopedAStatus StaIface::stopRxFilterInternal()
1152 {
1153 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
1154 }
1155 
addRxFilterInternal(RxFilterType type)1156 ndk::ScopedAStatus StaIface::addRxFilterInternal(
1157 	RxFilterType type)
1158 {
1159 	return doOneArgDriverCommand(
1160 		retrieveIfacePtr(), kAddRxFilter,
1161 		convertAidlRxFilterTypeToInternal(type));
1162 }
1163 
removeRxFilterInternal(RxFilterType type)1164 ndk::ScopedAStatus StaIface::removeRxFilterInternal(
1165 	RxFilterType type)
1166 {
1167 	return doOneArgDriverCommand(
1168 		retrieveIfacePtr(), kRemoveRxFilter,
1169 		convertAidlRxFilterTypeToInternal(type));
1170 }
1171 
setBtCoexistenceModeInternal(BtCoexistenceMode mode)1172 ndk::ScopedAStatus StaIface::setBtCoexistenceModeInternal(
1173 	BtCoexistenceMode mode)
1174 {
1175 	return doOneArgDriverCommand(
1176 		retrieveIfacePtr(), kSetBtCoexistenceMode,
1177 		convertAidlBtCoexModeToInternal(mode));
1178 }
1179 
setBtCoexistenceScanModeEnabledInternal(bool enable)1180 ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
1181 {
1182 	const char *cmd;
1183 	if (enable) {
1184 		cmd = kSetBtCoexistenceScanStart;
1185 	} else {
1186 		cmd = kSetBtCoexistenceScanStop;
1187 	}
1188 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
1189 }
1190 
setSuspendModeEnabledInternal(bool enable)1191 ndk::ScopedAStatus StaIface::setSuspendModeEnabledInternal(bool enable)
1192 {
1193 	const char *cmd;
1194 	if (enable) {
1195 		cmd = kSetSupendModeEnabled;
1196 	} else {
1197 		cmd = kSetSupendModeDisabled;
1198 	}
1199 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
1200 }
1201 
setCountryCodeInternal(const std::vector<uint8_t> & code)1202 ndk::ScopedAStatus StaIface::setCountryCodeInternal(
1203 	const std::vector<uint8_t> &code)
1204 {
1205 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1206 	//2-Character alphanumeric country code
1207 	if (code.size() != 2) {
1208 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1209 	}
1210 	ndk::ScopedAStatus status = doOneArgDriverCommand(
1211 		wpa_s, kSetCountryCode,
1212 		std::string(std::begin(code), std::end(code)));
1213 	if (!status.isOk()) {
1214 		return status;
1215 	}
1216 	struct p2p_data *p2p = wpa_s->global->p2p;
1217 	if (p2p) {
1218 		char country[3];
1219 		country[0] = code[0];
1220 		country[1] = code[1];
1221 		country[2] = 0x04;
1222 		p2p_set_country(p2p, country);
1223 	}
1224 	return ndk::ScopedAStatus::ok();
1225 }
1226 
startWpsRegistrarInternal(const std::vector<uint8_t> & bssid,const std::string & pin)1227 ndk::ScopedAStatus StaIface::startWpsRegistrarInternal(
1228 	const std::vector<uint8_t> &bssid, const std::string &pin)
1229 {
1230 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1231 	if (bssid.size() != ETH_ALEN) {
1232 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1233 	}
1234 	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
1235 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1236 	}
1237 	return ndk::ScopedAStatus::ok();
1238 }
1239 
startWpsPbcInternal(const std::vector<uint8_t> & bssid)1240 ndk::ScopedAStatus StaIface::startWpsPbcInternal(
1241 	const std::vector<uint8_t> &bssid)
1242 {
1243 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1244 	if (bssid.size() != ETH_ALEN) {
1245 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1246 	}
1247 	const uint8_t *bssid_addr =
1248 		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1249 	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
1250 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1251 	}
1252 	return ndk::ScopedAStatus::ok();
1253 }
1254 
startWpsPinKeypadInternal(const std::string & pin)1255 ndk::ScopedAStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
1256 {
1257 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1258 	if (wpas_wps_start_pin(
1259 		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
1260 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1261 	}
1262 	return ndk::ScopedAStatus::ok();
1263 }
1264 
startWpsPinDisplayInternal(const std::vector<uint8_t> & bssid)1265 std::pair<std::string, ndk::ScopedAStatus> StaIface::startWpsPinDisplayInternal(
1266 	const std::vector<uint8_t> &bssid)
1267 {
1268 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1269 	if (bssid.size() != ETH_ALEN) {
1270 		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1271 	}
1272 	const uint8_t *bssid_addr =
1273 		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1274 	int pin =
1275 		wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
1276 	if (pin < 0) {
1277 		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1278 	}
1279 	return {misc_utils::convertWpsPinToString(pin),
1280 		ndk::ScopedAStatus::ok()};
1281 }
1282 
cancelWpsInternal()1283 ndk::ScopedAStatus StaIface::cancelWpsInternal()
1284 {
1285 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1286 	if (wpas_wps_cancel(wpa_s)) {
1287 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1288 	}
1289 	return ndk::ScopedAStatus::ok();
1290 }
1291 
setWpsDeviceNameInternal(const std::string & name)1292 ndk::ScopedAStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
1293 {
1294 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
1295 }
1296 
setWpsDeviceTypeInternal(const std::vector<uint8_t> & type)1297 ndk::ScopedAStatus StaIface::setWpsDeviceTypeInternal(
1298 	const std::vector<uint8_t> &type)
1299 {
1300 	std::array<uint8_t, 8> type_arr;
1301 	std::copy_n(type.begin(), 8, type_arr.begin());
1302 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
1303 }
1304 
setWpsManufacturerInternal(const std::string & manufacturer)1305 ndk::ScopedAStatus StaIface::setWpsManufacturerInternal(
1306 	const std::string &manufacturer)
1307 {
1308 	return iface_config_utils::setWpsManufacturer(
1309 		retrieveIfacePtr(), manufacturer);
1310 }
1311 
setWpsModelNameInternal(const std::string & model_name)1312 ndk::ScopedAStatus StaIface::setWpsModelNameInternal(
1313 	const std::string &model_name)
1314 {
1315 	return iface_config_utils::setWpsModelName(
1316 		retrieveIfacePtr(), model_name);
1317 }
1318 
setWpsModelNumberInternal(const std::string & model_number)1319 ndk::ScopedAStatus StaIface::setWpsModelNumberInternal(
1320 	const std::string &model_number)
1321 {
1322 	return iface_config_utils::setWpsModelNumber(
1323 		retrieveIfacePtr(), model_number);
1324 }
1325 
setWpsSerialNumberInternal(const std::string & serial_number)1326 ndk::ScopedAStatus StaIface::setWpsSerialNumberInternal(
1327 	const std::string &serial_number)
1328 {
1329 	return iface_config_utils::setWpsSerialNumber(
1330 		retrieveIfacePtr(), serial_number);
1331 }
1332 
setWpsConfigMethodsInternal(WpsConfigMethods config_methods)1333 ndk::ScopedAStatus StaIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
1334 {
1335 	return iface_config_utils::setWpsConfigMethods(
1336 		retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
1337 }
1338 
setExternalSimInternal(bool useExternalSim)1339 ndk::ScopedAStatus StaIface::setExternalSimInternal(bool useExternalSim)
1340 {
1341 	return iface_config_utils::setExternalSim(
1342 		retrieveIfacePtr(), useExternalSim);
1343 }
1344 
addExtRadioWorkInternal(const std::string & name,uint32_t freq_in_mhz,uint32_t timeout_in_sec)1345 std::pair<uint32_t, ndk::ScopedAStatus> StaIface::addExtRadioWorkInternal(
1346 	const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
1347 {
1348 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1349 	auto *ework = static_cast<struct wpa_external_work *>(
1350 		os_zalloc(sizeof(struct wpa_external_work)));
1351 	if (!ework) {
1352 		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1353 	}
1354 
1355 	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
1356 	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
1357 	ework->timeout = timeout_in_sec;
1358 	wpa_s->ext_work_id++;
1359 	if (wpa_s->ext_work_id == 0) {
1360 		wpa_s->ext_work_id++;
1361 	}
1362 	ework->id = wpa_s->ext_work_id;
1363 
1364 	if (radio_add_work(
1365 		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
1366 		ework)) {
1367 		os_free(ework);
1368 		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1369 	}
1370 	return {ework->id, ndk::ScopedAStatus::ok()};
1371 }
1372 
removeExtRadioWorkInternal(uint32_t id)1373 ndk::ScopedAStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
1374 {
1375 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1376 	struct wpa_radio_work *work;
1377 	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
1378 	{
1379 		if (os_strncmp(
1380 			work->type, kExtRadioWorkNamePrefix,
1381 			sizeof(kExtRadioWorkNamePrefix)) != 0)
1382 			continue;
1383 
1384 		auto *ework =
1385 			static_cast<struct wpa_external_work *>(work->ctx);
1386 		if (ework->id != id)
1387 			continue;
1388 
1389 		wpa_dbg(
1390 			wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
1391 			ework->id, ework->type);
1392 		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
1393 		endExtRadioWork(work);
1394 
1395 		return ndk::ScopedAStatus::ok();
1396 	}
1397 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1398 }
1399 
enableAutoReconnectInternal(bool enable)1400 ndk::ScopedAStatus StaIface::enableAutoReconnectInternal(bool enable)
1401 {
1402 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1403 	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
1404 	return ndk::ScopedAStatus::ok();
1405 }
1406 
1407 std::pair<uint32_t, ndk::ScopedAStatus>
addDppPeerUriInternal(const std::string & uri)1408 StaIface::addDppPeerUriInternal(const std::string& uri)
1409 {
1410 #ifdef CONFIG_DPP
1411 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1412 	int32_t id;
1413 
1414 	id = wpas_dpp_qr_code(wpa_s, uri.c_str());
1415 
1416 	if (id > 0) {
1417 		return {id, ndk::ScopedAStatus::ok()};
1418 	}
1419 #endif
1420 	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1421 }
1422 
removeDppUriInternal(uint32_t bootstrap_id)1423 ndk::ScopedAStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id)
1424 {
1425 #ifdef CONFIG_DPP
1426 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1427 	std::string bootstrap_id_str;
1428 
1429 	if (bootstrap_id == 0) {
1430 		bootstrap_id_str = "*";
1431 	}
1432 	else {
1433 		bootstrap_id_str = std::to_string(bootstrap_id);
1434 	}
1435 
1436 	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
1437 		return ndk::ScopedAStatus::ok();
1438 	}
1439 #endif
1440 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1441 }
1442 
1443 std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
startDppConfiguratorInitiatorInternal(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id,const std::string & ssid,const std::string & password,const std::string & psk,DppNetRole net_role,DppAkm security_akm,const std::vector<uint8_t> & privEcKey)1444 StaIface::startDppConfiguratorInitiatorInternal(
1445 		uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id,
1446 		const std::string& ssid, const std::string& password,
1447 		const std::string& psk, DppNetRole net_role, DppAkm security_akm,
1448 		const std::vector<uint8_t> &privEcKey)
1449 {
1450 #ifdef CONFIG_DPP
1451 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1452 	std::string cmd = "";
1453 	std::string cmd2 = "";
1454 	int32_t id;
1455 	char key[1024];
1456 
1457 	if (net_role != DppNetRole::AP &&
1458 			net_role != DppNetRole::STA) {
1459 		wpa_printf(MSG_ERROR,
1460 			   "DPP: Error: Invalid network role specified: %d", net_role);
1461 		return {std::vector<uint8_t>(),
1462 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1463 	}
1464 
1465 	cmd += " peer=" + std::to_string(peer_bootstrap_id);
1466 	cmd += (own_bootstrap_id > 0) ?
1467 			" own=" + std::to_string(own_bootstrap_id) : "";
1468 
1469 	/* Check for supported AKMs */
1470 	if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
1471 			security_akm != DppAkm::PSK_SAE && security_akm != DppAkm::DPP) {
1472 		wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
1473 				security_akm);
1474 		return {std::vector<uint8_t>(),
1475 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1476 	}
1477 
1478 	/* SAE AKM requires SSID and password to be initialized */
1479 	if ((security_akm == DppAkm::SAE ||
1480 			security_akm == DppAkm::PSK_SAE) &&
1481 			(ssid.empty() || password.empty())) {
1482 		wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified");
1483 		return {std::vector<uint8_t>(),
1484 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1485 	} else if (security_akm == DppAkm::PSK ||
1486 			security_akm == DppAkm::PSK_SAE) {
1487 		/* PSK AKM requires SSID and password/psk to be initialized */
1488 		if (ssid.empty()) {
1489 			wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified");
1490 			return {std::vector<uint8_t>(),
1491 				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1492 		}
1493 		if (password.empty() && psk.empty()) {
1494 			wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
1495 			return {std::vector<uint8_t>(),
1496 				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1497 		}
1498 	}
1499 
1500 	cmd += " role=configurator";
1501 	cmd += (ssid.empty()) ? "" : " ssid=" + ssid;
1502 
1503 	if (!psk.empty()) {
1504 		cmd += " psk=" + psk;
1505 	} else {
1506 		cmd += (password.empty()) ? "" : " pass=" + password;
1507 	}
1508 
1509 	std::string role = "";
1510 	if (net_role == DppNetRole::AP) {
1511 		role = "ap-";
1512 	}
1513 	else {
1514 		role = "sta-";
1515 	}
1516 
1517 	switch (security_akm) {
1518 	case DppAkm::PSK:
1519 		role += "psk";
1520 		break;
1521 
1522 	case DppAkm::SAE:
1523 		role += "sae";
1524 		break;
1525 
1526 	case DppAkm::PSK_SAE:
1527 		role += "psk-sae";
1528 		break;
1529 
1530 	case DppAkm::DPP:
1531 		role += "dpp";
1532 		break;
1533 
1534 	default:
1535 		wpa_printf(MSG_ERROR,
1536 			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
1537 		return {std::vector<uint8_t>(),
1538 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1539 	}
1540 
1541 	cmd += " conf=";
1542 	cmd += role;
1543 
1544 	if (net_role == DppNetRole::STA) {
1545 		/* DPP R2 connection status request */
1546 		cmd += " conn_status=1";
1547 	}
1548 
1549 	if (security_akm == DppAkm::DPP) {
1550 		if (!privEcKey.empty()) {
1551 			cmd2 += " key=" + std::string(privEcKey.begin(), privEcKey.end());
1552 		}
1553 		id = dpp_configurator_add(wpa_s->dpp, cmd2.c_str());
1554 		if (id < 0 || (privEcKey.empty() &&
1555 			       (dpp_configurator_get_key_id(wpa_s->dpp, id, key, sizeof(key)) < 0)))
1556 		{
1557 			wpa_printf(MSG_ERROR, "DPP configurator add failed. "
1558 			           "Input key might be incorrect");
1559 			return {std::vector<uint8_t>(),
1560 				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1561 		}
1562 
1563 		cmd += " configurator=" + std::to_string(id);
1564 	}
1565 
1566 	wpa_printf(MSG_DEBUG,
1567 		   "DPP initiator command: %s", cmd.c_str());
1568 
1569 	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1570 		// Return key if input privEcKey was null/empty.
1571 		if (security_akm == DppAkm::DPP && privEcKey.empty()) {
1572 			std::string k(key);
1573 			std::vector<uint8_t> vKey(k.begin(), k.end());
1574 			return {vKey, ndk::ScopedAStatus::ok()};
1575 		}
1576 		return {std::vector<uint8_t>(), ndk::ScopedAStatus::ok()};
1577 	}
1578 #endif
1579 	return {std::vector<uint8_t>(), createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1580 }
1581 
startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id)1582 ndk::ScopedAStatus StaIface::startDppEnrolleeInitiatorInternal(
1583 	uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id) {
1584 #ifdef CONFIG_DPP
1585 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1586 	std::string cmd = "";
1587 
1588 	/* Report received configuration to AIDL and create an internal profile */
1589 	wpa_s->conf->dpp_config_processing = 1;
1590 
1591 	cmd += " peer=" + std::to_string(peer_bootstrap_id);
1592 	cmd += (own_bootstrap_id > 0) ?
1593 			" own=" + std::to_string(own_bootstrap_id) : "";
1594 
1595 	cmd += " role=enrollee";
1596 
1597 	wpa_printf(MSG_DEBUG,
1598 		   "DPP initiator command: %s", cmd.c_str());
1599 
1600 	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1601 		return ndk::ScopedAStatus::ok();
1602 	}
1603 #endif
1604 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1605 }
stopDppInitiatorInternal()1606 ndk::ScopedAStatus StaIface::stopDppInitiatorInternal()
1607 {
1608 #ifdef CONFIG_DPP
1609 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1610 
1611 	wpas_dpp_stop(wpa_s);
1612 	return ndk::ScopedAStatus::ok();
1613 #else
1614 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1615 #endif
1616 }
1617 
1618 std::pair<DppResponderBootstrapInfo, ndk::ScopedAStatus>
generateDppBootstrapInfoForResponderInternal(const std::vector<uint8_t> & mac_address,const std::string & device_info,DppCurve curve)1619 StaIface::generateDppBootstrapInfoForResponderInternal(
1620 	const std::vector<uint8_t> &mac_address,
1621 	const std::string& device_info, DppCurve curve)
1622 {
1623 #ifdef CONFIG_DPP
1624 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1625 	std::string cmd = "type=qrcode";
1626 	int32_t id;
1627 	int32_t listen_channel = 0;
1628 	DppResponderBootstrapInfo bootstrap_info;
1629 	const char *uri;
1630 	std::string listen_channel_str;
1631 	std::string mac_addr_str;
1632 	char buf[3] = {0};
1633 
1634 	cmd += (device_info.empty()) ? "" : " info=" + device_info;
1635 
1636 	listen_channel_str = getDppListenChannel(wpa_s, &listen_channel);
1637 	if (listen_channel == 0) {
1638 		wpa_printf(MSG_ERROR, "StaIface: Failed to derive DPP listen channel");
1639 		return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1640 	}
1641 	cmd += " chan=" + listen_channel_str;
1642 
1643 	if (mac_address.size() != ETH_ALEN) {
1644 		return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1645 	}
1646 	cmd += " mac=";
1647 	for (int i = 0;i < 6;i++) {
1648 		snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
1649 		mac_addr_str.append(buf);
1650 	}
1651 	cmd += mac_addr_str;
1652 
1653 	cmd += " curve=" + convertCurveTypeToName(curve);
1654 
1655 	id = dpp_bootstrap_gen(wpa_s->dpp, cmd.c_str());
1656 	wpa_printf(MSG_DEBUG,
1657 		   "DPP generate bootstrap QR code command: %s id: %d", cmd.c_str(), id);
1658 	if (id > 0) {
1659 		uri = dpp_bootstrap_get_uri(wpa_s->dpp, id);
1660 		if (uri) {
1661 			wpa_printf(MSG_DEBUG, "DPP Bootstrap info: id: %d "
1662 				   "listen_channel: %d uri: %s", id, listen_channel, uri);
1663 			bootstrap_info.bootstrapId = id;
1664 			bootstrap_info.listenChannel = listen_channel;
1665 			bootstrap_info.uri = uri;
1666 			return {bootstrap_info, ndk::ScopedAStatus::ok()};
1667 		}
1668 	}
1669 	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1670 #else
1671 	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
1672 #endif
1673 }
1674 
startDppEnrolleeResponderInternal(uint32_t listen_channel)1675 ndk::ScopedAStatus StaIface::startDppEnrolleeResponderInternal(uint32_t listen_channel)
1676 {
1677 #ifdef CONFIG_DPP
1678 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1679 	std::string cmd = "";
1680 	uint32_t freq = (listen_channel <= 14 ? 2407 : 5000) + listen_channel * 5;
1681 
1682 	/* Report received configuration to AIDL and create an internal profile */
1683 	wpa_s->conf->dpp_config_processing = 1;
1684 
1685 	cmd += std::to_string(freq);
1686 	cmd += " role=enrollee netrole=sta";
1687 
1688 	wpa_printf(MSG_DEBUG,
1689 		   "DPP Enrollee Responder command: %s", cmd.c_str());
1690 
1691 	if (wpas_dpp_listen(wpa_s, cmd.c_str()) == 0) {
1692 		return ndk::ScopedAStatus::ok();
1693 	}
1694 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1695 #else
1696 	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1697 #endif
1698 }
1699 
stopDppResponderInternal(uint32_t own_bootstrap_id)1700 ndk::ScopedAStatus StaIface::stopDppResponderInternal(uint32_t own_bootstrap_id)
1701 {
1702 #ifdef CONFIG_DPP
1703 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1704 	std::string bootstrap_id_str;
1705 
1706 	if (own_bootstrap_id == 0) {
1707 		bootstrap_id_str = "*";
1708 	}
1709 	else {
1710 		bootstrap_id_str = std::to_string(own_bootstrap_id);
1711 	}
1712 
1713 	wpa_printf(MSG_DEBUG, "DPP Stop DPP Responder id: %d ", own_bootstrap_id);
1714 	wpas_dpp_stop(wpa_s);
1715 	wpas_dpp_listen_stop(wpa_s);
1716 
1717 	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) < 0) {
1718 		wpa_printf(MSG_ERROR, "StaIface: dpp_bootstrap_remove failed");
1719 	}
1720 
1721 	return ndk::ScopedAStatus::ok();
1722 #else
1723 	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1724 #endif
1725 }
1726 
generateSelfDppConfigurationInternal(const std::string & ssid,const std::vector<uint8_t> & privEcKey)1727 ndk::ScopedAStatus StaIface::generateSelfDppConfigurationInternal(const std::string& ssid,
1728 		const std::vector<uint8_t> &privEcKey)
1729 {
1730 #ifdef CONFIG_DPP
1731 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1732 	std::string cmd = "";
1733 	char *ssid_hex_str;
1734 	int len;
1735 	int32_t id;
1736 
1737 	if (ssid.empty() || privEcKey.empty()) {
1738 		wpa_printf(MSG_ERROR, "DPP generate self configuration failed. ssid/key empty");
1739 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1740 	}
1741 
1742 	cmd += " key=" + std::string(privEcKey.begin(), privEcKey.end());
1743 
1744 	id = dpp_configurator_add(wpa_s->dpp, cmd.c_str());
1745 	if (id < 0) {
1746 		wpa_printf(MSG_ERROR, "DPP configurator add failed. Input key might be incorrect");
1747 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1748 	}
1749 
1750 	cmd = " conf=sta-dpp";
1751 	cmd += " configurator=" + std::to_string(id);
1752 
1753 	ssid_hex_str = (char *) os_zalloc(ssid.size() * 2 + 1);
1754 	if (!ssid_hex_str) {
1755 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1756 	}
1757 
1758 	wpa_snprintf_hex(ssid_hex_str, ssid.size() * 2 + 1, (u8*)ssid.data(), ssid.size());
1759 	cmd += " ssid=" + std::string(ssid_hex_str);
1760 
1761 	/* Report received configuration to AIDL and create an internal profile */
1762 	wpa_s->conf->dpp_config_processing = 1;
1763 
1764 	if (wpas_dpp_configurator_sign(wpa_s, cmd.c_str()) == 0) {
1765 		os_free(ssid_hex_str);
1766 		return ndk::ScopedAStatus::ok();
1767 	}
1768 
1769 	os_free(ssid_hex_str);
1770 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1771 #else
1772 	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1773 #endif
1774 }
1775 
1776 std::pair<ConnectionCapabilities, ndk::ScopedAStatus>
getConnectionCapabilitiesInternal()1777 StaIface::getConnectionCapabilitiesInternal()
1778 {
1779 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1780 	ConnectionCapabilities capa;
1781 
1782 	if (wpa_s->connection_set) {
1783 		capa.legacyMode = LegacyMode::UNKNOWN;
1784 		if (wpa_s->connection_he) {
1785 			capa.technology = WifiTechnology::HE;
1786 		} else if (wpa_s->connection_vht) {
1787 			capa.technology = WifiTechnology::VHT;
1788 		} else if (wpa_s->connection_ht) {
1789 			capa.technology = WifiTechnology::HT;
1790 		} else {
1791 			capa.technology = WifiTechnology::LEGACY;
1792 			if (wpas_freq_to_band(wpa_s->assoc_freq) == BAND_2_4_GHZ) {
1793 				capa.legacyMode = (wpa_s->connection_11b_only) ? LegacyMode::B_MODE
1794 						: LegacyMode::G_MODE;
1795 			} else {
1796 				capa.legacyMode = LegacyMode::A_MODE;
1797 			}
1798 		}
1799 		switch (wpa_s->connection_channel_bandwidth) {
1800 		case CHAN_WIDTH_20:
1801 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1802 			break;
1803 		case CHAN_WIDTH_40:
1804 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_40;
1805 			break;
1806 		case CHAN_WIDTH_80:
1807 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80;
1808 			break;
1809 		case CHAN_WIDTH_160:
1810 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_160;
1811 			break;
1812 		case CHAN_WIDTH_80P80:
1813 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
1814 			break;
1815 		default:
1816 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1817 			break;
1818 		}
1819 		capa.maxNumberRxSpatialStreams = wpa_s->connection_max_nss_rx;
1820 		capa.maxNumberTxSpatialStreams = wpa_s->connection_max_nss_tx;
1821 	} else {
1822 		capa.technology = WifiTechnology::UNKNOWN;
1823 		capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1824 		capa.maxNumberTxSpatialStreams = 1;
1825 		capa.maxNumberRxSpatialStreams = 1;
1826 		capa.legacyMode = LegacyMode::UNKNOWN;
1827 	}
1828 	return {capa, ndk::ScopedAStatus::ok()};
1829 }
1830 
1831 std::pair<WpaDriverCapabilitiesMask, ndk::ScopedAStatus>
getWpaDriverCapabilitiesInternal()1832 StaIface::getWpaDriverCapabilitiesInternal()
1833 {
1834 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1835 	uint32_t mask = 0;
1836 
1837 #ifdef CONFIG_MBO
1838 	/* MBO has no capability flags. It's mainly legacy 802.11v BSS
1839 	 * transition + Cellular steering. 11v is a default feature in
1840 	 * supplicant. And cellular steering is handled in framework.
1841 	 */
1842 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::MBO);
1843 	if (wpa_s->enable_oce & OCE_STA) {
1844 		mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::OCE);
1845 	}
1846 #endif
1847 #ifdef CONFIG_SAE_PK
1848 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SAE_PK);
1849 #endif
1850 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::WFD_R2);
1851 
1852 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
1853 
1854 	wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
1855 
1856 	return {static_cast<WpaDriverCapabilitiesMask>(mask),
1857 		ndk::ScopedAStatus::ok()};
1858 }
1859 
setMboCellularDataStatusInternal(bool available)1860 ndk::ScopedAStatus StaIface::setMboCellularDataStatusInternal(bool available)
1861 {
1862 #ifdef CONFIG_MBO
1863 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1864 	enum mbo_cellular_capa mbo_cell_capa;
1865 
1866 	if (available) {
1867 		mbo_cell_capa = MBO_CELL_CAPA_AVAILABLE;
1868 	} else {
1869 		mbo_cell_capa = MBO_CELL_CAPA_NOT_AVAILABLE;
1870 	}
1871 
1872 #ifdef ENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
1873 	char mbo_cmd[32];
1874 	char buf[32];
1875 
1876 	os_snprintf(mbo_cmd, sizeof(mbo_cmd), "%s %d", "MBO CELL_DATA_CAP", mbo_cell_capa);
1877 	if (wpa_drv_driver_cmd(wpa_s, mbo_cmd, buf, sizeof(buf)) < 0) {
1878 		wpa_printf(MSG_ERROR, "MBO CELL_DATA_CAP cmd failed CAP:%d", mbo_cell_capa);
1879 	}
1880 #else
1881 	wpas_mbo_update_cell_capa(wpa_s, mbo_cell_capa);
1882 #endif
1883 
1884 	return ndk::ScopedAStatus::ok();
1885 #else
1886 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1887 #endif
1888 }
1889 
1890 std::pair<KeyMgmtMask, ndk::ScopedAStatus>
getKeyMgmtCapabilitiesInternal()1891 StaIface::getKeyMgmtCapabilitiesInternal()
1892 {
1893 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1894 	struct wpa_driver_capa capa;
1895 
1896 	/* Get capabilities from driver and populate the key management mask */
1897 	if (wpa_drv_get_capa(wpa_s, &capa) < 0) {
1898 		return {static_cast<KeyMgmtMask>(0),
1899 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1900 	}
1901 
1902 	return {convertWpaKeyMgmtCapabilitiesToAidl(wpa_s, &capa),
1903 		ndk::ScopedAStatus::ok()};
1904 }
1905 
setQosPolicyFeatureEnabledInternal(bool enable)1906 ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabledInternal(bool enable)
1907 {
1908 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1909 	wpa_s->enable_dscp_policy_capa = enable ? 1 : 0;
1910 	return ndk::ScopedAStatus::ok();
1911 }
1912 
sendQosPolicyResponseInternal(int32_t qos_policy_request_id,bool more_policies,const std::vector<QosPolicyStatus> & qos_policy_status_list)1913 ndk::ScopedAStatus StaIface::sendQosPolicyResponseInternal(
1914 	int32_t qos_policy_request_id, bool more_policies,
1915 	const std::vector<QosPolicyStatus>& qos_policy_status_list)
1916 {
1917 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1918 	struct dscp_resp_data resp_data;
1919 	int num_policies = qos_policy_status_list.size();
1920 
1921 	memset(&resp_data, 0, sizeof(resp_data));
1922 
1923 	resp_data.more = more_policies ? 1 : 0;
1924 	resp_data.policy = (struct dscp_policy_status *) malloc(
1925 		sizeof(struct dscp_policy_status) * num_policies);
1926 	if (num_policies && !resp_data.policy){
1927 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1928 	}
1929 
1930 	resp_data.solicited = true;
1931 	wpa_s->dscp_req_dialog_token = qos_policy_request_id;
1932 
1933 	for (int i = 0; i < num_policies; i++) {
1934 		resp_data.policy[i].id = qos_policy_status_list.at(i).policyId;
1935 		resp_data.policy[i].status =
1936 			static_cast<uint8_t>(qos_policy_status_list.at(i).status);
1937 	}
1938 	resp_data.num_policies = num_policies;
1939 
1940 	if (wpas_send_dscp_response(wpa_s, &resp_data)) {
1941 		free(resp_data.policy);
1942 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1943 	}
1944 
1945 	free(resp_data.policy);
1946 	return ndk::ScopedAStatus::ok();
1947 }
1948 
removeAllQosPoliciesInternal()1949 ndk::ScopedAStatus StaIface::removeAllQosPoliciesInternal()
1950 {
1951 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1952 	struct dscp_resp_data resp_data;
1953 
1954 	memset(&resp_data, 0, sizeof(resp_data));
1955 	resp_data.reset = true;
1956 	resp_data.solicited = false;
1957 	wpa_s->dscp_req_dialog_token = 0;
1958 
1959 	if (wpas_send_dscp_response(wpa_s, &resp_data)) {
1960 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1961 	}
1962 	return ndk::ScopedAStatus::ok();
1963 }
1964 
getConnectionMloLinksInfoInternal()1965 std::pair<MloLinksInfo, ndk::ScopedAStatus> StaIface::getConnectionMloLinksInfoInternal()
1966 {
1967 	MloLinksInfo linksInfo;
1968 	return {linksInfo, ndk::ScopedAStatus::ok()};
1969 }
1970 
1971 /**
1972  * Retrieve the underlying |wpa_supplicant| struct
1973  * pointer for this iface.
1974  * If the underlying iface is removed, then all RPC method calls on this object
1975  * will return failure.
1976  */
retrieveIfacePtr()1977 wpa_supplicant *StaIface::retrieveIfacePtr()
1978 {
1979 	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
1980 }
1981 }  // namespace supplicant
1982 }  // namespace wifi
1983 }  // namespace hardware
1984 }  // namespace android
1985 }  // namespace aidl
1986