• 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_320	= 7,
54   WIDTH_INVALID = -1
55 };
56 
57 constexpr uint32_t kMaxAnqpElems = 100;
58 constexpr char kGetMacAddress[] = "MACADDR";
59 constexpr char kStartRxFilter[] = "RXFILTER-START";
60 constexpr char kStopRxFilter[] = "RXFILTER-STOP";
61 constexpr char kAddRxFilter[] = "RXFILTER-ADD";
62 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
63 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
64 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
65 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
66 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
67 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
68 constexpr char kSetCountryCode[] = "COUNTRY";
69 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec =
70 	static_cast<uint32_t>(ISupplicant::EXT_RADIO_WORK_TIMEOUT_IN_SECS);
71 constexpr char kExtRadioWorkNamePrefix[] = "ext:";
72 
convertAidlRxFilterTypeToInternal(RxFilterType type)73 uint8_t convertAidlRxFilterTypeToInternal(
74 	RxFilterType type)
75 {
76 	switch (type) {
77 	case RxFilterType::V4_MULTICAST:
78 		return 2;
79 	case RxFilterType::V6_MULTICAST:
80 		return 3;
81 	};
82 	WPA_ASSERT(false);
83 }
84 
convertAidlBtCoexModeToInternal(BtCoexistenceMode mode)85 uint8_t convertAidlBtCoexModeToInternal(
86 	BtCoexistenceMode mode)
87 {
88 	switch (mode) {
89 	case BtCoexistenceMode::ENABLED:
90 		return 0;
91 	case BtCoexistenceMode::DISABLED:
92 		return 1;
93 	case BtCoexistenceMode::SENSE:
94 		return 2;
95 	};
96 	WPA_ASSERT(false);
97 }
98 
doZeroArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd)99 ndk::ScopedAStatus doZeroArgDriverCommand(
100 	struct wpa_supplicant *wpa_s, const char *cmd)
101 {
102 	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
103 	char driver_cmd_reply_buf[4096] = {};
104 	if (wpa_drv_driver_cmd(
105 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
106 		sizeof(driver_cmd_reply_buf))) {
107 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
108 	}
109 	return ndk::ScopedAStatus::ok();
110 }
111 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,uint8_t arg)112 ndk::ScopedAStatus doOneArgDriverCommand(
113 	struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
114 {
115 	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
116 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
117 }
118 
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,const std::string & arg)119 ndk::ScopedAStatus doOneArgDriverCommand(
120 	struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
121 {
122 	std::string cmd_str = std::string(cmd) + " " + arg;
123 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
124 }
125 
endExtRadioWork(struct wpa_radio_work * work)126 void endExtRadioWork(struct wpa_radio_work *work)
127 {
128 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
129 	work->wpa_s->ext_work_in_progress = 0;
130 	radio_work_done(work);
131 	os_free(ework);
132 }
133 
extRadioWorkTimeoutCb(void * eloop_ctx,void * timeout_ctx)134 void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
135 {
136 	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
137 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
138 	wpa_dbg(
139 		work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
140 		ework->id, work->type);
141 
142 	AidlManager *aidl_manager = AidlManager::getInstance();
143 	WPA_ASSERT(aidl_manager);
144 	aidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
145 
146 	endExtRadioWork(work);
147 }
148 
startExtRadioWork(struct wpa_radio_work * work)149 void startExtRadioWork(struct wpa_radio_work *work)
150 {
151 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
152 	work->wpa_s->ext_work_in_progress = 1;
153 	if (!ework->timeout) {
154 		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
155 	}
156 	eloop_register_timeout(
157 		ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
158 }
159 
extRadioWorkStartCb(struct wpa_radio_work * work,int deinit)160 void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
161 {
162 	// deinit==1 is invoked during interface removal. Since the AIDL
163 	// interface does not support interface addition/removal, we don't
164 	// need to handle this scenario.
165 	WPA_ASSERT(!deinit);
166 
167 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
168 	wpa_dbg(
169 		work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
170 		ework->id, ework->type);
171 
172 	AidlManager *aidl_manager = AidlManager::getInstance();
173 	WPA_ASSERT(aidl_manager);
174 	aidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
175 
176 	startExtRadioWork(work);
177 }
178 
convertWpaKeyMgmtCapabilitiesToAidl(struct wpa_supplicant * wpa_s,struct wpa_driver_capa * capa)179 KeyMgmtMask convertWpaKeyMgmtCapabilitiesToAidl (
180 	struct wpa_supplicant *wpa_s, struct wpa_driver_capa *capa) {
181 
182 	uint32_t mask = 0;
183 	/* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability
184 	 * flags and always enabled.
185 	 */
186 	mask |=
187 		(static_cast<uint32_t>(KeyMgmtMask::NONE) |
188 		 static_cast<uint32_t>(KeyMgmtMask::IEEE8021X));
189 
190 	if (capa->key_mgmt &
191 		(WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
192 		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_EAP);
193 	}
194 
195 	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
196 				 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
197 		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_PSK);
198 	}
199 #ifdef CONFIG_SUITEB192
200 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
201 		mask |= static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192);
202 	}
203 #endif /* CONFIG_SUITEB192 */
204 #ifdef CONFIG_OWE
205 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
206 		mask |= static_cast<uint32_t>(KeyMgmtMask::OWE);
207 	}
208 #endif /* CONFIG_OWE */
209 #ifdef CONFIG_SAE
210 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
211 		mask |= static_cast<uint32_t>(KeyMgmtMask::SAE);
212 	}
213 #endif /* CONFIG_SAE */
214 #ifdef CONFIG_DPP
215 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
216 		mask |= static_cast<uint32_t>(KeyMgmtMask::DPP);
217 	}
218 #endif
219 #ifdef CONFIG_WAPI_INTERFACE
220 	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK);
221 	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT);
222 #endif /* CONFIG_WAPI_INTERFACE */
223 #ifdef CONFIG_FILS
224 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
225 		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256);
226 	}
227 	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
228 		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384);
229 	}
230 #endif /* CONFIG_FILS */
231 	return static_cast<KeyMgmtMask>(mask);
232 }
233 
getDppListenChannel(struct wpa_supplicant * wpa_s,int32_t * listen_channel)234 const std::string getDppListenChannel(struct wpa_supplicant *wpa_s, int32_t *listen_channel)
235 {
236 	struct hostapd_hw_modes *mode;
237 	int chan44 = 0, chan149 = 0;
238 	*listen_channel = 0;
239 
240 	/* Check if device support 2.4GHz band*/
241 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
242 			HOSTAPD_MODE_IEEE80211G, 0);
243 	if (mode) {
244 		*listen_channel = 6;
245 		return "81/6";
246 	}
247 	/* Check if device support 5GHz band */
248 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
249 			HOSTAPD_MODE_IEEE80211A, 0);
250 	if (mode) {
251 		for (int i = 0; i < mode->num_channels; i++) {
252 			struct hostapd_channel_data *chan = &mode->channels[i];
253 
254 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
255 					  HOSTAPD_CHAN_RADAR))
256 				continue;
257 			if (chan->freq == 5220)
258 				chan44 = 1;
259 			if (chan->freq == 5745)
260 				chan149 = 1;
261 		}
262 		if (chan149) {
263 			*listen_channel = 149;
264 			return "124/149";
265 		} else if (chan44) {
266 			*listen_channel = 44;
267 			return "115/44";
268 		}
269 	}
270 
271 	return "";
272 }
273 
convertCurveTypeToName(DppCurve curve)274 const std::string convertCurveTypeToName(DppCurve curve)
275 {
276 	switch (curve) {
277 	case DppCurve::PRIME256V1:
278 		return "prime256v1";
279 	case DppCurve::SECP384R1:
280 		return "secp384r1";
281 	case DppCurve::SECP521R1:
282 		return "secp521r1";
283 	case DppCurve::BRAINPOOLP256R1:
284 		return "brainpoolP256r1";
285 	case DppCurve::BRAINPOOLP384R1:
286 		return "brainpoolP384r1";
287 	case DppCurve::BRAINPOOLP512R1:
288 		return "brainpoolP512r1";
289 	}
290 	WPA_ASSERT(false);
291 }
292 
macAddrToArray(const uint8_t * mac_addr)293 inline std::array<uint8_t, ETH_ALEN> macAddrToArray(const uint8_t* mac_addr) {
294 	std::array<uint8_t, ETH_ALEN> arr;
295 	std::copy(mac_addr, mac_addr + ETH_ALEN, std::begin(arr));
296 	return arr;
297 }
298 
299 }  // namespace
300 
301 namespace aidl {
302 namespace android {
303 namespace hardware {
304 namespace wifi {
305 namespace supplicant {
306 using aidl_return_util::validateAndCall;
307 using misc_utils::createStatus;
308 
StaIface(struct wpa_global * wpa_global,const char ifname[])309 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
310 	: wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
311 {}
312 
invalidate()313 void StaIface::invalidate() { is_valid_ = false; }
isValid()314 bool StaIface::isValid()
315 {
316 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
317 }
318 
getName(std::string * _aidl_return)319 ::ndk::ScopedAStatus StaIface::getName(
320 	std::string* _aidl_return)
321 {
322 	return validateAndCall(
323 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
324 		&StaIface::getNameInternal, _aidl_return);
325 }
326 
getType(IfaceType * _aidl_return)327 ::ndk::ScopedAStatus StaIface::getType(
328 	IfaceType* _aidl_return)
329 {
330 	return validateAndCall(
331 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
332 		&StaIface::getTypeInternal, _aidl_return);
333 }
334 
addNetwork(std::shared_ptr<ISupplicantStaNetwork> * _aidl_return)335 ::ndk::ScopedAStatus StaIface::addNetwork(
336 	std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
337 {
338 	return validateAndCall(
339 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
340 		&StaIface::addNetworkInternal, _aidl_return);
341 }
342 
removeNetwork(int32_t in_id)343 ::ndk::ScopedAStatus StaIface::removeNetwork(
344 	int32_t in_id)
345 {
346 	return validateAndCall(
347 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
348 		&StaIface::removeNetworkInternal, in_id);
349 }
350 
filsHlpFlushRequest()351 ::ndk::ScopedAStatus StaIface::filsHlpFlushRequest()
352 {
353 	return validateAndCall(
354 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
355 		&StaIface::filsHlpFlushRequestInternal);
356 }
357 
filsHlpAddRequest(const std::vector<uint8_t> & in_dst_mac,const std::vector<uint8_t> & in_pkt)358 ::ndk::ScopedAStatus StaIface::filsHlpAddRequest(
359 	const std::vector<uint8_t>& in_dst_mac,
360 	const std::vector<uint8_t>& in_pkt)
361 {
362 	return validateAndCall(
363 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
364 		&StaIface::filsHlpAddRequestInternal, in_dst_mac, in_pkt);
365 }
366 
getNetwork(int32_t in_id,std::shared_ptr<ISupplicantStaNetwork> * _aidl_return)367 ::ndk::ScopedAStatus StaIface::getNetwork(
368 	int32_t in_id, std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
369 {
370 	return validateAndCall(
371 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
372 		&StaIface::getNetworkInternal, _aidl_return, in_id);
373 }
374 
listNetworks(std::vector<int32_t> * _aidl_return)375 ::ndk::ScopedAStatus StaIface::listNetworks(
376 	std::vector<int32_t>* _aidl_return)
377 {
378 	return validateAndCall(
379 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
380 		&StaIface::listNetworksInternal, _aidl_return);
381 }
382 
registerCallback(const std::shared_ptr<ISupplicantStaIfaceCallback> & in_callback)383 ::ndk::ScopedAStatus StaIface::registerCallback(
384 	const std::shared_ptr<ISupplicantStaIfaceCallback>& in_callback)
385 {
386 	return validateAndCall(
387 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
388 		&StaIface::registerCallbackInternal, in_callback);
389 }
390 
reassociate()391 ::ndk::ScopedAStatus StaIface::reassociate()
392 {
393 	return validateAndCall(
394 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
395 		&StaIface::reassociateInternal);
396 }
397 
reconnect()398 ::ndk::ScopedAStatus StaIface::reconnect()
399 {
400 	return validateAndCall(
401 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
402 		&StaIface::reconnectInternal);
403 }
404 
disconnect()405 ::ndk::ScopedAStatus StaIface::disconnect()
406 {
407 	return validateAndCall(
408 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
409 		&StaIface::disconnectInternal);
410 }
411 
setPowerSave(bool in_enable)412 ::ndk::ScopedAStatus StaIface::setPowerSave(
413 	bool in_enable)
414 {
415 	return validateAndCall(
416 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
417 		&StaIface::setPowerSaveInternal, in_enable);
418 }
419 
initiateTdlsDiscover(const std::vector<uint8_t> & in_macAddress)420 ::ndk::ScopedAStatus StaIface::initiateTdlsDiscover(
421 	const std::vector<uint8_t>& in_macAddress)
422 {
423 	return validateAndCall(
424 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
425 		&StaIface::initiateTdlsDiscoverInternal, in_macAddress);
426 }
427 
initiateTdlsSetup(const std::vector<uint8_t> & in_macAddress)428 ::ndk::ScopedAStatus StaIface::initiateTdlsSetup(
429 	const std::vector<uint8_t>& in_macAddress)
430 {
431 	return validateAndCall(
432 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
433 		&StaIface::initiateTdlsSetupInternal, in_macAddress);
434 }
435 
initiateTdlsTeardown(const std::vector<uint8_t> & in_macAddress)436 ::ndk::ScopedAStatus StaIface::initiateTdlsTeardown(
437 	const std::vector<uint8_t>& in_macAddress)
438 {
439 	return validateAndCall(
440 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
441 		&StaIface::initiateTdlsTeardownInternal, in_macAddress);
442 }
443 
initiateAnqpQuery(const std::vector<uint8_t> & in_macAddress,const std::vector<AnqpInfoId> & in_infoElements,const std::vector<Hs20AnqpSubtypes> & in_subTypes)444 ::ndk::ScopedAStatus StaIface::initiateAnqpQuery(
445 	const std::vector<uint8_t>& in_macAddress,
446 	const std::vector<AnqpInfoId>& in_infoElements,
447 	const std::vector<Hs20AnqpSubtypes>& in_subTypes)
448 {
449 	return validateAndCall(
450 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
451 		&StaIface::initiateAnqpQueryInternal, in_macAddress,
452 		in_infoElements, in_subTypes);
453 }
454 
initiateVenueUrlAnqpQuery(const std::vector<uint8_t> & in_macAddress)455 ::ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQuery(
456 	const std::vector<uint8_t>& in_macAddress)
457 {
458 	return validateAndCall(
459 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
460 		&StaIface::initiateVenueUrlAnqpQueryInternal, in_macAddress);
461 }
462 
initiateHs20IconQuery(const std::vector<uint8_t> & in_macAddress,const std::string & in_fileName)463 ::ndk::ScopedAStatus StaIface::initiateHs20IconQuery(
464 	const std::vector<uint8_t>& in_macAddress,
465 	const std::string& in_fileName)
466 {
467 	return validateAndCall(
468 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
469 		&StaIface::initiateHs20IconQueryInternal, in_macAddress,
470 		in_fileName);
471 }
472 
getMacAddress(std::vector<uint8_t> * _aidl_return)473 ::ndk::ScopedAStatus StaIface::getMacAddress(
474 	std::vector<uint8_t>* _aidl_return)
475 {
476 	return validateAndCall(
477 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
478 		&StaIface::getMacAddressInternal, _aidl_return);
479 }
480 
startRxFilter()481 ::ndk::ScopedAStatus StaIface::startRxFilter()
482 {
483 	return validateAndCall(
484 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
485 		&StaIface::startRxFilterInternal);
486 }
487 
stopRxFilter()488 ::ndk::ScopedAStatus StaIface::stopRxFilter()
489 {
490 	return validateAndCall(
491 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
492 		&StaIface::stopRxFilterInternal);
493 }
494 
addRxFilter(RxFilterType in_type)495 ::ndk::ScopedAStatus StaIface::addRxFilter(
496 	RxFilterType in_type)
497 {
498 	return validateAndCall(
499 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
500 		&StaIface::addRxFilterInternal, in_type);
501 }
502 
removeRxFilter(RxFilterType in_type)503 ::ndk::ScopedAStatus StaIface::removeRxFilter(
504 	RxFilterType in_type)
505 {
506 	return validateAndCall(
507 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
508 		&StaIface::removeRxFilterInternal, in_type);
509 }
510 
setBtCoexistenceMode(BtCoexistenceMode in_mode)511 ::ndk::ScopedAStatus StaIface::setBtCoexistenceMode(
512 	BtCoexistenceMode in_mode)
513 {
514 	return validateAndCall(
515 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
516 		&StaIface::setBtCoexistenceModeInternal, in_mode);
517 }
518 
setBtCoexistenceScanModeEnabled(bool in_enable)519 ::ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabled(
520 	bool in_enable)
521 {
522 	return validateAndCall(
523 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
524 		&StaIface::setBtCoexistenceScanModeEnabledInternal,
525 		in_enable);
526 }
527 
setSuspendModeEnabled(bool in_enable)528 ::ndk::ScopedAStatus StaIface::setSuspendModeEnabled(
529 	bool in_enable)
530 {
531 	return validateAndCall(
532 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
533 		&StaIface::setSuspendModeEnabledInternal, in_enable);
534 }
535 
setCountryCode(const std::vector<uint8_t> & in_code)536 ::ndk::ScopedAStatus StaIface::setCountryCode(
537 	const std::vector<uint8_t>& in_code)
538 {
539 	return validateAndCall(
540 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
541 		&StaIface::setCountryCodeInternal, in_code);
542 }
543 
startWpsRegistrar(const std::vector<uint8_t> & in_bssid,const std::string & in_pin)544 ::ndk::ScopedAStatus StaIface::startWpsRegistrar(
545 	const std::vector<uint8_t>& in_bssid,
546 	const std::string& in_pin)
547 {
548 	return validateAndCall(
549 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
550 		&StaIface::startWpsRegistrarInternal, in_bssid, in_pin);
551 }
552 
startWpsPbc(const std::vector<uint8_t> & in_bssid)553 ::ndk::ScopedAStatus StaIface::startWpsPbc(
554 	const std::vector<uint8_t>& in_bssid)
555 {
556 	return validateAndCall(
557 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
558 		&StaIface::startWpsPbcInternal, in_bssid);
559 }
560 
startWpsPinKeypad(const std::string & in_pin)561 ::ndk::ScopedAStatus StaIface::startWpsPinKeypad(
562 	const std::string& in_pin)
563 {
564 	return validateAndCall(
565 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
566 		&StaIface::startWpsPinKeypadInternal, in_pin);
567 }
568 
startWpsPinDisplay(const std::vector<uint8_t> & in_bssid,std::string * _aidl_return)569 ::ndk::ScopedAStatus StaIface::startWpsPinDisplay(
570 	const std::vector<uint8_t>& in_bssid,
571 	std::string* _aidl_return)
572 {
573 	return validateAndCall(
574 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
575 		&StaIface::startWpsPinDisplayInternal, _aidl_return, in_bssid);
576 }
577 
cancelWps()578 ::ndk::ScopedAStatus StaIface::cancelWps()
579 {
580 	return validateAndCall(
581 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
582 		&StaIface::cancelWpsInternal);
583 }
584 
setWpsDeviceName(const std::string & in_name)585 ::ndk::ScopedAStatus StaIface::setWpsDeviceName(
586 	const std::string& in_name)
587 {
588 	return validateAndCall(
589 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
590 		&StaIface::setWpsDeviceNameInternal, in_name);
591 }
592 
setWpsDeviceType(const std::vector<uint8_t> & in_type)593 ::ndk::ScopedAStatus StaIface::setWpsDeviceType(
594 	const std::vector<uint8_t>& in_type)
595 {
596 	return validateAndCall(
597 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
598 		&StaIface::setWpsDeviceTypeInternal, in_type);
599 }
600 
setWpsManufacturer(const std::string & in_manufacturer)601 ::ndk::ScopedAStatus StaIface::setWpsManufacturer(
602 	const std::string& in_manufacturer)
603 {
604 	return validateAndCall(
605 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
606 		&StaIface::setWpsManufacturerInternal, in_manufacturer);
607 }
608 
setWpsModelName(const std::string & in_modelName)609 ::ndk::ScopedAStatus StaIface::setWpsModelName(
610 	const std::string& in_modelName)
611 {
612 	return validateAndCall(
613 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
614 		&StaIface::setWpsModelNameInternal, in_modelName);
615 }
616 
setWpsModelNumber(const std::string & in_modelNumber)617 ::ndk::ScopedAStatus StaIface::setWpsModelNumber(
618 	const std::string& in_modelNumber)
619 {
620 	return validateAndCall(
621 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
622 		&StaIface::setWpsModelNumberInternal, in_modelNumber);
623 }
624 
setWpsSerialNumber(const std::string & in_serialNumber)625 ::ndk::ScopedAStatus StaIface::setWpsSerialNumber(
626 	const std::string& in_serialNumber)
627 {
628 	return validateAndCall(
629 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
630 		&StaIface::setWpsSerialNumberInternal, in_serialNumber);
631 }
632 
setWpsConfigMethods(WpsConfigMethods in_configMethods)633 ::ndk::ScopedAStatus StaIface::setWpsConfigMethods(
634 	WpsConfigMethods in_configMethods)
635 {
636 	return validateAndCall(
637 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
638 		&StaIface::setWpsConfigMethodsInternal, in_configMethods);
639 }
640 
setExternalSim(bool in_useExternalSim)641 ::ndk::ScopedAStatus StaIface::setExternalSim(
642 	bool in_useExternalSim)
643 {
644 	return validateAndCall(
645 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
646 		&StaIface::setExternalSimInternal, in_useExternalSim);
647 }
648 
addExtRadioWork(const std::string & in_name,int32_t in_freqInMhz,int32_t in_timeoutInSec,int32_t * _aidl_return)649 ::ndk::ScopedAStatus StaIface::addExtRadioWork(
650 	const std::string& in_name, int32_t in_freqInMhz,
651 	int32_t in_timeoutInSec,
652 	int32_t* _aidl_return)
653 {
654 	return validateAndCall(
655 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
656 		&StaIface::addExtRadioWorkInternal, _aidl_return, in_name, in_freqInMhz,
657 		in_timeoutInSec);
658 }
659 
removeExtRadioWork(int32_t in_id)660 ::ndk::ScopedAStatus StaIface::removeExtRadioWork(
661 	int32_t in_id)
662 {
663 	return validateAndCall(
664 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
665 		&StaIface::removeExtRadioWorkInternal, in_id);
666 }
667 
enableAutoReconnect(bool in_enable)668 ::ndk::ScopedAStatus StaIface::enableAutoReconnect(
669 	bool in_enable)
670 {
671 	return validateAndCall(
672 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
673 		&StaIface::enableAutoReconnectInternal, in_enable);
674 }
675 
getKeyMgmtCapabilities(KeyMgmtMask * _aidl_return)676 ::ndk::ScopedAStatus StaIface::getKeyMgmtCapabilities(
677 	KeyMgmtMask* _aidl_return)
678 {
679 	return validateAndCall(
680 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
681 		&StaIface::getKeyMgmtCapabilitiesInternal, _aidl_return);
682 }
683 
addDppPeerUri(const std::string & in_uri,int32_t * _aidl_return)684 ::ndk::ScopedAStatus StaIface::addDppPeerUri(
685 	const std::string& in_uri, int32_t* _aidl_return)
686 {
687 	return validateAndCall(
688 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
689 		&StaIface::addDppPeerUriInternal, _aidl_return, in_uri);
690 }
691 
removeDppUri(int32_t in_id)692 ::ndk::ScopedAStatus StaIface::removeDppUri(
693 	int32_t in_id)
694 {
695 	return validateAndCall(
696 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
697 		&StaIface::removeDppUriInternal, in_id);
698 }
699 
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)700 ::ndk::ScopedAStatus StaIface::startDppConfiguratorInitiator(
701 	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId,
702 	const std::string& in_ssid, const std::string& in_password,
703 	const std::string& in_psk, DppNetRole in_netRole,
704 	DppAkm in_securityAkm, const std::vector<uint8_t>& in_privEcKey,
705 	std::vector<uint8_t>* _aidl_return)
706 {
707 	return validateAndCall(
708 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
709 		&StaIface::startDppConfiguratorInitiatorInternal, _aidl_return,
710 		in_peerBootstrapId,in_ownBootstrapId, in_ssid, in_password,
711 		in_psk, in_netRole, in_securityAkm, in_privEcKey);
712 }
713 
startDppEnrolleeInitiator(int32_t in_peerBootstrapId,int32_t in_ownBootstrapId)714 ::ndk::ScopedAStatus StaIface::startDppEnrolleeInitiator(
715 	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId)
716 {
717 	return validateAndCall(
718 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
719 		&StaIface::startDppEnrolleeInitiatorInternal, in_peerBootstrapId,
720 		in_ownBootstrapId);
721 }
722 
stopDppInitiator()723 ::ndk::ScopedAStatus StaIface::stopDppInitiator()
724 {
725 	return validateAndCall(
726 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
727 		&StaIface::stopDppInitiatorInternal);
728 }
729 
getConnectionCapabilities(ConnectionCapabilities * _aidl_return)730 ::ndk::ScopedAStatus StaIface::getConnectionCapabilities(
731 	ConnectionCapabilities* _aidl_return)
732 {
733 	return validateAndCall(
734 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
735 		&StaIface::getConnectionCapabilitiesInternal,
736 		_aidl_return);
737 }
738 
generateDppBootstrapInfoForResponder(const std::vector<uint8_t> & in_macAddress,const std::string & in_deviceInfo,DppCurve in_curve,DppResponderBootstrapInfo * _aidl_return)739 ::ndk::ScopedAStatus StaIface::generateDppBootstrapInfoForResponder(
740 	const std::vector<uint8_t>& in_macAddress, const std::string& in_deviceInfo,
741 	DppCurve in_curve, DppResponderBootstrapInfo* _aidl_return)
742 {
743 	return validateAndCall(
744 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
745 		&StaIface::generateDppBootstrapInfoForResponderInternal, _aidl_return,
746 		in_macAddress, in_deviceInfo, in_curve);
747 }
748 
startDppEnrolleeResponder(int32_t in_listenChannel)749 ::ndk::ScopedAStatus StaIface::startDppEnrolleeResponder(
750 	int32_t in_listenChannel)
751 {
752 	return validateAndCall(
753 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
754 		&StaIface::startDppEnrolleeResponderInternal, in_listenChannel);
755 }
756 
stopDppResponder(int32_t in_ownBootstrapId)757 ::ndk::ScopedAStatus StaIface::stopDppResponder(
758 	int32_t in_ownBootstrapId)
759 {
760 	return validateAndCall(
761 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
762 		&StaIface::stopDppResponderInternal, in_ownBootstrapId);
763 }
764 
generateSelfDppConfiguration(const std::string & in_ssid,const std::vector<uint8_t> & in_privEcKey)765 ::ndk::ScopedAStatus StaIface::generateSelfDppConfiguration(
766 	const std::string& in_ssid, const std::vector<uint8_t>& in_privEcKey)
767 {
768 	return validateAndCall(
769 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
770 		&StaIface::generateSelfDppConfigurationInternal, in_ssid, in_privEcKey);
771 }
772 
getWpaDriverCapabilities(WpaDriverCapabilitiesMask * _aidl_return)773 ::ndk::ScopedAStatus StaIface::getWpaDriverCapabilities(
774 	WpaDriverCapabilitiesMask* _aidl_return)
775 {
776 	return validateAndCall(
777 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
778 		&StaIface::getWpaDriverCapabilitiesInternal, _aidl_return);
779 }
780 
setMboCellularDataStatus(bool in_available)781 ::ndk::ScopedAStatus StaIface::setMboCellularDataStatus(
782 	bool in_available)
783 {
784 	return validateAndCall(
785 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
786 		&StaIface::setMboCellularDataStatusInternal, in_available);
787 }
788 
setQosPolicyFeatureEnabled(bool in_enable)789 ::ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabled(
790 	bool in_enable)
791 {
792 	return validateAndCall(
793 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
794 		&StaIface::setQosPolicyFeatureEnabledInternal, in_enable);
795 }
796 
sendQosPolicyResponse(int32_t in_qosPolicyRequestId,bool in_morePolicies,const std::vector<QosPolicyStatus> & in_qosPolicyStatusList)797 ::ndk::ScopedAStatus StaIface::sendQosPolicyResponse(
798 	int32_t in_qosPolicyRequestId, bool in_morePolicies,
799 	const std::vector<QosPolicyStatus>& in_qosPolicyStatusList)
800 {
801 	return validateAndCall(
802 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
803 		&StaIface::sendQosPolicyResponseInternal, in_qosPolicyRequestId,
804 		in_morePolicies, in_qosPolicyStatusList);
805 }
806 
removeAllQosPolicies()807 ::ndk::ScopedAStatus StaIface::removeAllQosPolicies()
808 {
809 	return validateAndCall(
810 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
811 		&StaIface::removeAllQosPoliciesInternal);
812 }
813 
getConnectionMloLinksInfo(MloLinksInfo * _aidl_return)814 ::ndk::ScopedAStatus StaIface::getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) {
815 	return validateAndCall(
816 		this, SupplicantStatusCode::FAILURE_UNKNOWN,
817 		&StaIface::getConnectionMloLinksInfoInternal, _aidl_return);
818 }
819 
getSignalPollResults(std::vector<SignalPollResult> * results)820 ::ndk::ScopedAStatus StaIface::getSignalPollResults(
821     std::vector<SignalPollResult> *results)
822 {
823 	return validateAndCall(
824 	    this, SupplicantStatusCode::FAILURE_UNKNOWN,
825 	    &StaIface::getSignalPollResultsInternal, results);
826 }
827 
addQosPolicyRequestForScs(const std::vector<QosPolicyScsData> & in_qosPolicyData,std::vector<QosPolicyScsRequestStatus> * _aidl_return)828 ::ndk::ScopedAStatus StaIface::addQosPolicyRequestForScs(
829 		const std::vector<QosPolicyScsData>& in_qosPolicyData,
830 		std::vector<QosPolicyScsRequestStatus>* _aidl_return)
831 {
832 	return validateAndCall(
833 	    this, SupplicantStatusCode::FAILURE_UNKNOWN,
834 	    &StaIface::addQosPolicyRequestForScsInternal, _aidl_return, in_qosPolicyData);
835 }
836 
removeQosPolicyForScs(const std::vector<uint8_t> & in_scsPolicyIds,std::vector<QosPolicyScsRequestStatus> * _aidl_return)837 ::ndk::ScopedAStatus StaIface::removeQosPolicyForScs(
838 		const std::vector<uint8_t>& in_scsPolicyIds,
839 		std::vector<QosPolicyScsRequestStatus>* _aidl_return)
840 {
841 	return validateAndCall(
842 	    this, SupplicantStatusCode::FAILURE_UNKNOWN,
843 	    &StaIface::removeQosPolicyForScsInternal, _aidl_return, in_scsPolicyIds);
844 }
845 
getNameInternal()846 std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
847 {
848 	return {ifname_, ndk::ScopedAStatus::ok()};
849 }
850 
getTypeInternal()851 std::pair<IfaceType, ndk::ScopedAStatus> StaIface::getTypeInternal()
852 {
853 	return {IfaceType::STA, ndk::ScopedAStatus::ok()};
854 }
855 
filsHlpFlushRequestInternal()856 ndk::ScopedAStatus StaIface::filsHlpFlushRequestInternal()
857 {
858 #ifdef CONFIG_FILS
859 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
860 
861 	wpas_flush_fils_hlp_req(wpa_s);
862 	return ndk::ScopedAStatus::ok();
863 #else /* CONFIG_FILS */
864 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN, "");
865 #endif /* CONFIG_FILS */
866 }
867 
filsHlpAddRequestInternal(const std::vector<uint8_t> & dst_mac,const std::vector<uint8_t> & pkt)868 ndk::ScopedAStatus StaIface::filsHlpAddRequestInternal(
869 	const std::vector<uint8_t> &dst_mac, const std::vector<uint8_t> &pkt)
870 {
871 #ifdef CONFIG_FILS
872 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
873 	struct fils_hlp_req *req;
874 
875 	if (!pkt.size())
876 		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
877 	if (dst_mac.size() != ETH_ALEN)
878 		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
879 
880 
881 	req = (struct fils_hlp_req *)os_zalloc(sizeof(*req));
882 	if (!req)
883 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
884 
885 	os_memcpy(req->dst, dst_mac.data(), ETH_ALEN);
886 
887 	req->pkt = wpabuf_alloc_copy(pkt.data(), pkt.size());
888 	if (!req->pkt) {
889 		os_free(req);
890 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
891 	}
892 
893 	dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
894 	return ndk::ScopedAStatus::ok();
895 #else /* CONFIG_FILS */
896 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
897 #endif /* CONFIG_FILS */
898 }
899 
900 std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
addNetworkInternal()901 StaIface::addNetworkInternal()
902 {
903 	std::shared_ptr<ISupplicantStaNetwork> network;
904 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
905 	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
906 	if (!ssid) {
907 		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
908 	}
909 	AidlManager *aidl_manager = AidlManager::getInstance();
910 	if (!aidl_manager ||
911 		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
912 		wpa_s->ifname, ssid->id, &network)) {
913 		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
914 	}
915 	return {network, ndk::ScopedAStatus::ok()};
916 }
917 
removeNetworkInternal(int32_t id)918 ndk::ScopedAStatus StaIface::removeNetworkInternal(int32_t id)
919 {
920 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
921 	int result = wpa_supplicant_remove_network(wpa_s, id);
922 	if (result == -1) {
923 		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
924 	}
925 	if (result != 0) {
926 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
927 	}
928 	return ndk::ScopedAStatus::ok();
929 }
930 
931 std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
getNetworkInternal(int32_t id)932 StaIface::getNetworkInternal(int32_t id)
933 {
934 	std::shared_ptr<ISupplicantStaNetwork> network;
935 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
936 	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
937 	if (!ssid) {
938 		return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
939 	}
940 	AidlManager *aidl_manager = AidlManager::getInstance();
941 	if (!aidl_manager ||
942 		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
943 		wpa_s->ifname, ssid->id, &network)) {
944 		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
945 	}
946 	return {network, ndk::ScopedAStatus::ok()};
947 }
948 
949 std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
listNetworksInternal()950 StaIface::listNetworksInternal()
951 {
952 	std::vector<int32_t> network_ids;
953 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
954 	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
955 		 wpa_ssid = wpa_ssid->next) {
956 		network_ids.emplace_back(wpa_ssid->id);
957 	}
958 	return {std::move(network_ids), ndk::ScopedAStatus::ok()};
959 }
960 
registerCallbackInternal(const std::shared_ptr<ISupplicantStaIfaceCallback> & callback)961 ndk::ScopedAStatus StaIface::registerCallbackInternal(
962 	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
963 {
964 	AidlManager *aidl_manager = AidlManager::getInstance();
965 	if (!aidl_manager ||
966 		aidl_manager->addStaIfaceCallbackAidlObject(ifname_, callback)) {
967 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
968 	}
969 	return ndk::ScopedAStatus::ok();
970 }
971 
reassociateInternal()972 ndk::ScopedAStatus StaIface::reassociateInternal()
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 	wpas_request_connection(wpa_s);
979 	return ndk::ScopedAStatus::ok();
980 }
981 
reconnectInternal()982 ndk::ScopedAStatus StaIface::reconnectInternal()
983 {
984 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
985 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
986 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
987 	}
988 	if (!wpa_s->disconnected) {
989 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
990 	}
991 	wpas_request_connection(wpa_s);
992 	return ndk::ScopedAStatus::ok();
993 }
994 
disconnectInternal()995 ndk::ScopedAStatus StaIface::disconnectInternal()
996 {
997 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
998 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
999 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
1000 	}
1001 	wpas_request_disconnection(wpa_s);
1002 	return ndk::ScopedAStatus::ok();
1003 }
1004 
setPowerSaveInternal(bool enable)1005 ndk::ScopedAStatus StaIface::setPowerSaveInternal(bool enable)
1006 {
1007 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1008 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
1009 		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
1010 	}
1011 	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
1012 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1013 	}
1014 	return ndk::ScopedAStatus::ok();
1015 }
1016 
initiateTdlsDiscoverInternal(const std::vector<uint8_t> & mac_address)1017 ndk::ScopedAStatus StaIface::initiateTdlsDiscoverInternal(
1018 	const std::vector<uint8_t> &mac_address)
1019 {
1020 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1021 	int ret;
1022 	if (mac_address.size() != ETH_ALEN) {
1023 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1024 	}
1025 	const u8 *peer = mac_address.data();
1026 	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
1027 		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
1028 	} else {
1029 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
1030 	}
1031 	if (ret) {
1032 		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
1033 	}
1034 	return ndk::ScopedAStatus::ok();
1035 }
1036 
initiateTdlsSetupInternal(const std::vector<uint8_t> & mac_address)1037 ndk::ScopedAStatus StaIface::initiateTdlsSetupInternal(
1038 	const std::vector<uint8_t> &mac_address)
1039 {
1040 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1041 	int ret;
1042 	if (mac_address.size() != ETH_ALEN) {
1043 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1044 	}
1045 	const u8 *peer = mac_address.data();
1046 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
1047 		!(wpa_s->conf->tdls_external_control)) {
1048 		wpa_tdls_remove(wpa_s->wpa, peer);
1049 		ret = wpa_tdls_start(wpa_s->wpa, peer);
1050 	} else {
1051 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
1052 	}
1053 	if (ret) {
1054 		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
1055 	}
1056 	return ndk::ScopedAStatus::ok();
1057 }
1058 
initiateTdlsTeardownInternal(const std::vector<uint8_t> & mac_address)1059 ndk::ScopedAStatus StaIface::initiateTdlsTeardownInternal(
1060 	const std::vector<uint8_t> &mac_address)
1061 {
1062 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1063 	int ret;
1064 	if (mac_address.size() != ETH_ALEN) {
1065 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1066 	}
1067 	const u8 *peer = mac_address.data();
1068 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
1069 		!(wpa_s->conf->tdls_external_control)) {
1070 		ret = wpa_tdls_teardown_link(
1071 			wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
1072 	} else {
1073 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
1074 	}
1075 	if (ret) {
1076 		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
1077 	}
1078 	return ndk::ScopedAStatus::ok();
1079 }
1080 
initiateAnqpQueryInternal(const std::vector<uint8_t> & mac_address,const std::vector<AnqpInfoId> & info_elements,const std::vector<Hs20AnqpSubtypes> & sub_types)1081 ndk::ScopedAStatus StaIface::initiateAnqpQueryInternal(
1082 	const std::vector<uint8_t> &mac_address,
1083 	const std::vector<AnqpInfoId> &info_elements,
1084 	const std::vector<Hs20AnqpSubtypes> &sub_types)
1085 {
1086 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1087 	if (info_elements.size() > kMaxAnqpElems) {
1088 		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
1089 	}
1090 	uint16_t info_elems_buf[kMaxAnqpElems];
1091 	uint32_t num_info_elems = 0;
1092 	for (const auto &info_element : info_elements) {
1093 		info_elems_buf[num_info_elems++] =
1094 			static_cast<std::underlying_type<
1095 			AnqpInfoId>::type>(info_element);
1096 	}
1097 	uint32_t sub_types_bitmask = 0;
1098 	for (const auto &type : sub_types) {
1099 		sub_types_bitmask |= BIT(
1100 			static_cast<std::underlying_type<
1101 			Hs20AnqpSubtypes>::type>(type));
1102 	}
1103 	if (mac_address.size() != ETH_ALEN) {
1104 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1105 	}
1106 
1107 	if (anqp_send_req(
1108 		wpa_s, mac_address.data(), 0, info_elems_buf, num_info_elems,
1109 		sub_types_bitmask, 0)) {
1110 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1111 	}
1112 	return ndk::ScopedAStatus::ok();
1113 }
1114 
initiateVenueUrlAnqpQueryInternal(const std::vector<uint8_t> & mac_address)1115 ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQueryInternal(
1116 	const std::vector<uint8_t> &mac_address)
1117 {
1118 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1119 	uint16_t info_elems_buf[1] = {ANQP_VENUE_URL};
1120 	if (mac_address.size() != ETH_ALEN) {
1121 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1122 	}
1123 
1124 	if (anqp_send_req(
1125 		wpa_s, mac_address.data(), 0, info_elems_buf, 1, 0, 0)) {
1126 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1127 	}
1128 	return ndk::ScopedAStatus::ok();
1129 }
1130 
initiateHs20IconQueryInternal(const std::vector<uint8_t> & mac_address,const std::string & file_name)1131 ndk::ScopedAStatus StaIface::initiateHs20IconQueryInternal(
1132 	const std::vector<uint8_t> &mac_address, const std::string &file_name)
1133 {
1134 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1135 	if (mac_address.size() != ETH_ALEN) {
1136 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1137 	}
1138 	wpa_s->fetch_osu_icon_in_progress = 0;
1139 	if (hs20_anqp_send_req(
1140 		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
1141 		reinterpret_cast<const uint8_t *>(file_name.c_str()),
1142 		file_name.size(), true)) {
1143 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1144 	}
1145 	return ndk::ScopedAStatus::ok();
1146 }
1147 
1148 std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
getMacAddressInternal()1149 StaIface::getMacAddressInternal()
1150 {
1151 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1152 	std::vector<char> cmd(
1153 		kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
1154 	char driver_cmd_reply_buf[4096] = {};
1155 	int ret = wpa_drv_driver_cmd(
1156 		wpa_s, cmd.data(), driver_cmd_reply_buf,
1157 		sizeof(driver_cmd_reply_buf));
1158 	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
1159 	std::string reply_str = driver_cmd_reply_buf;
1160 	if (ret < 0 || reply_str.empty() ||
1161 		reply_str.find("=") == std::string::npos) {
1162 		return {std::vector<uint8_t>(),
1163 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1164 	}
1165 	// Remove all whitespace first and then split using the delimiter "=".
1166 	reply_str.erase(
1167 		remove_if(reply_str.begin(), reply_str.end(), isspace),
1168 		reply_str.end());
1169 	std::string mac_addr_str =
1170 		reply_str.substr(reply_str.find("=") + 1, reply_str.size());
1171 	std::vector<uint8_t> mac_addr(6);
1172 	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
1173 		return {std::vector<uint8_t>(),
1174 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1175 	}
1176 	return {mac_addr, ndk::ScopedAStatus::ok()};
1177 }
1178 
startRxFilterInternal()1179 ndk::ScopedAStatus StaIface::startRxFilterInternal()
1180 {
1181 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
1182 }
1183 
stopRxFilterInternal()1184 ndk::ScopedAStatus StaIface::stopRxFilterInternal()
1185 {
1186 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
1187 }
1188 
addRxFilterInternal(RxFilterType type)1189 ndk::ScopedAStatus StaIface::addRxFilterInternal(
1190 	RxFilterType type)
1191 {
1192 	return doOneArgDriverCommand(
1193 		retrieveIfacePtr(), kAddRxFilter,
1194 		convertAidlRxFilterTypeToInternal(type));
1195 }
1196 
removeRxFilterInternal(RxFilterType type)1197 ndk::ScopedAStatus StaIface::removeRxFilterInternal(
1198 	RxFilterType type)
1199 {
1200 	return doOneArgDriverCommand(
1201 		retrieveIfacePtr(), kRemoveRxFilter,
1202 		convertAidlRxFilterTypeToInternal(type));
1203 }
1204 
setBtCoexistenceModeInternal(BtCoexistenceMode mode)1205 ndk::ScopedAStatus StaIface::setBtCoexistenceModeInternal(
1206 	BtCoexistenceMode mode)
1207 {
1208 	return doOneArgDriverCommand(
1209 		retrieveIfacePtr(), kSetBtCoexistenceMode,
1210 		convertAidlBtCoexModeToInternal(mode));
1211 }
1212 
setBtCoexistenceScanModeEnabledInternal(bool enable)1213 ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
1214 {
1215 	const char *cmd;
1216 	if (enable) {
1217 		cmd = kSetBtCoexistenceScanStart;
1218 	} else {
1219 		cmd = kSetBtCoexistenceScanStop;
1220 	}
1221 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
1222 }
1223 
setSuspendModeEnabledInternal(bool enable)1224 ndk::ScopedAStatus StaIface::setSuspendModeEnabledInternal(bool enable)
1225 {
1226 	const char *cmd;
1227 	if (enable) {
1228 		cmd = kSetSupendModeEnabled;
1229 	} else {
1230 		cmd = kSetSupendModeDisabled;
1231 	}
1232 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
1233 }
1234 
setCountryCodeInternal(const std::vector<uint8_t> & code)1235 ndk::ScopedAStatus StaIface::setCountryCodeInternal(
1236 	const std::vector<uint8_t> &code)
1237 {
1238 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1239 	//2-Character alphanumeric country code
1240 	if (code.size() != 2) {
1241 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1242 	}
1243 	ndk::ScopedAStatus status = doOneArgDriverCommand(
1244 		wpa_s, kSetCountryCode,
1245 		std::string(std::begin(code), std::end(code)));
1246 	if (!status.isOk()) {
1247 		return status;
1248 	}
1249 	struct p2p_data *p2p = wpa_s->global->p2p;
1250 	if (p2p) {
1251 		char country[3];
1252 		country[0] = code[0];
1253 		country[1] = code[1];
1254 		country[2] = 0x04;
1255 		p2p_set_country(p2p, country);
1256 	}
1257 	return ndk::ScopedAStatus::ok();
1258 }
1259 
startWpsRegistrarInternal(const std::vector<uint8_t> & bssid,const std::string & pin)1260 ndk::ScopedAStatus StaIface::startWpsRegistrarInternal(
1261 	const std::vector<uint8_t> &bssid, const std::string &pin)
1262 {
1263 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1264 	if (bssid.size() != ETH_ALEN) {
1265 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1266 	}
1267 	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
1268 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1269 	}
1270 	return ndk::ScopedAStatus::ok();
1271 }
1272 
startWpsPbcInternal(const std::vector<uint8_t> & bssid)1273 ndk::ScopedAStatus StaIface::startWpsPbcInternal(
1274 	const std::vector<uint8_t> &bssid)
1275 {
1276 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1277 	if (bssid.size() != ETH_ALEN) {
1278 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1279 	}
1280 	const uint8_t *bssid_addr =
1281 		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1282 	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
1283 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1284 	}
1285 	return ndk::ScopedAStatus::ok();
1286 }
1287 
startWpsPinKeypadInternal(const std::string & pin)1288 ndk::ScopedAStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
1289 {
1290 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1291 	if (wpas_wps_start_pin(
1292 		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
1293 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1294 	}
1295 	return ndk::ScopedAStatus::ok();
1296 }
1297 
startWpsPinDisplayInternal(const std::vector<uint8_t> & bssid)1298 std::pair<std::string, ndk::ScopedAStatus> StaIface::startWpsPinDisplayInternal(
1299 	const std::vector<uint8_t> &bssid)
1300 {
1301 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1302 	if (bssid.size() != ETH_ALEN) {
1303 		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1304 	}
1305 	const uint8_t *bssid_addr =
1306 		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1307 	int pin =
1308 		wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
1309 	if (pin < 0) {
1310 		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1311 	}
1312 	return {misc_utils::convertWpsPinToString(pin),
1313 		ndk::ScopedAStatus::ok()};
1314 }
1315 
cancelWpsInternal()1316 ndk::ScopedAStatus StaIface::cancelWpsInternal()
1317 {
1318 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1319 	if (wpas_wps_cancel(wpa_s)) {
1320 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1321 	}
1322 	return ndk::ScopedAStatus::ok();
1323 }
1324 
setWpsDeviceNameInternal(const std::string & name)1325 ndk::ScopedAStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
1326 {
1327 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
1328 }
1329 
setWpsDeviceTypeInternal(const std::vector<uint8_t> & type)1330 ndk::ScopedAStatus StaIface::setWpsDeviceTypeInternal(
1331 	const std::vector<uint8_t> &type)
1332 {
1333 	std::array<uint8_t, 8> type_arr;
1334 	std::copy_n(type.begin(), 8, type_arr.begin());
1335 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
1336 }
1337 
setWpsManufacturerInternal(const std::string & manufacturer)1338 ndk::ScopedAStatus StaIface::setWpsManufacturerInternal(
1339 	const std::string &manufacturer)
1340 {
1341 	return iface_config_utils::setWpsManufacturer(
1342 		retrieveIfacePtr(), manufacturer);
1343 }
1344 
setWpsModelNameInternal(const std::string & model_name)1345 ndk::ScopedAStatus StaIface::setWpsModelNameInternal(
1346 	const std::string &model_name)
1347 {
1348 	return iface_config_utils::setWpsModelName(
1349 		retrieveIfacePtr(), model_name);
1350 }
1351 
setWpsModelNumberInternal(const std::string & model_number)1352 ndk::ScopedAStatus StaIface::setWpsModelNumberInternal(
1353 	const std::string &model_number)
1354 {
1355 	return iface_config_utils::setWpsModelNumber(
1356 		retrieveIfacePtr(), model_number);
1357 }
1358 
setWpsSerialNumberInternal(const std::string & serial_number)1359 ndk::ScopedAStatus StaIface::setWpsSerialNumberInternal(
1360 	const std::string &serial_number)
1361 {
1362 	return iface_config_utils::setWpsSerialNumber(
1363 		retrieveIfacePtr(), serial_number);
1364 }
1365 
setWpsConfigMethodsInternal(WpsConfigMethods config_methods)1366 ndk::ScopedAStatus StaIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
1367 {
1368 	return iface_config_utils::setWpsConfigMethods(
1369 		retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
1370 }
1371 
setExternalSimInternal(bool useExternalSim)1372 ndk::ScopedAStatus StaIface::setExternalSimInternal(bool useExternalSim)
1373 {
1374 	return iface_config_utils::setExternalSim(
1375 		retrieveIfacePtr(), useExternalSim);
1376 }
1377 
addExtRadioWorkInternal(const std::string & name,uint32_t freq_in_mhz,uint32_t timeout_in_sec)1378 std::pair<uint32_t, ndk::ScopedAStatus> StaIface::addExtRadioWorkInternal(
1379 	const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
1380 {
1381 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1382 	auto *ework = static_cast<struct wpa_external_work *>(
1383 		os_zalloc(sizeof(struct wpa_external_work)));
1384 	if (!ework) {
1385 		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1386 	}
1387 
1388 	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
1389 	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
1390 	ework->timeout = timeout_in_sec;
1391 	wpa_s->ext_work_id++;
1392 	if (wpa_s->ext_work_id == 0) {
1393 		wpa_s->ext_work_id++;
1394 	}
1395 	ework->id = wpa_s->ext_work_id;
1396 
1397 	if (radio_add_work(
1398 		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
1399 		ework)) {
1400 		os_free(ework);
1401 		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1402 	}
1403 	return {ework->id, ndk::ScopedAStatus::ok()};
1404 }
1405 
removeExtRadioWorkInternal(uint32_t id)1406 ndk::ScopedAStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
1407 {
1408 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1409 	struct wpa_radio_work *work;
1410 	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
1411 	{
1412 		if (os_strncmp(
1413 			work->type, kExtRadioWorkNamePrefix,
1414 			sizeof(kExtRadioWorkNamePrefix)) != 0)
1415 			continue;
1416 
1417 		auto *ework =
1418 			static_cast<struct wpa_external_work *>(work->ctx);
1419 		if (ework->id != id)
1420 			continue;
1421 
1422 		wpa_dbg(
1423 			wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
1424 			ework->id, ework->type);
1425 		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
1426 		endExtRadioWork(work);
1427 
1428 		return ndk::ScopedAStatus::ok();
1429 	}
1430 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1431 }
1432 
enableAutoReconnectInternal(bool enable)1433 ndk::ScopedAStatus StaIface::enableAutoReconnectInternal(bool enable)
1434 {
1435 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1436 	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
1437 	return ndk::ScopedAStatus::ok();
1438 }
1439 
1440 std::pair<uint32_t, ndk::ScopedAStatus>
addDppPeerUriInternal(const std::string & uri)1441 StaIface::addDppPeerUriInternal(const std::string& uri)
1442 {
1443 #ifdef CONFIG_DPP
1444 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1445 	int32_t id;
1446 
1447 	id = wpas_dpp_qr_code(wpa_s, uri.c_str());
1448 
1449 	if (id > 0) {
1450 		return {id, ndk::ScopedAStatus::ok()};
1451 	}
1452 #endif
1453 	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1454 }
1455 
removeDppUriInternal(uint32_t bootstrap_id)1456 ndk::ScopedAStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id)
1457 {
1458 #ifdef CONFIG_DPP
1459 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1460 	std::string bootstrap_id_str;
1461 
1462 	if (bootstrap_id == 0) {
1463 		bootstrap_id_str = "*";
1464 	}
1465 	else {
1466 		bootstrap_id_str = std::to_string(bootstrap_id);
1467 	}
1468 
1469 	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
1470 		return ndk::ScopedAStatus::ok();
1471 	}
1472 #endif
1473 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1474 }
1475 
1476 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)1477 StaIface::startDppConfiguratorInitiatorInternal(
1478 		uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id,
1479 		const std::string& ssid, const std::string& password,
1480 		const std::string& psk, DppNetRole net_role, DppAkm security_akm,
1481 		const std::vector<uint8_t> &privEcKey)
1482 {
1483 #ifdef CONFIG_DPP
1484 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1485 	std::string cmd = "";
1486 	std::string cmd2 = "";
1487 	int32_t id;
1488 	char key[1024];
1489 
1490 	if (net_role != DppNetRole::AP &&
1491 			net_role != DppNetRole::STA) {
1492 		wpa_printf(MSG_ERROR,
1493 			   "DPP: Error: Invalid network role specified: %d", net_role);
1494 		return {std::vector<uint8_t>(),
1495 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1496 	}
1497 
1498 	cmd += " peer=" + std::to_string(peer_bootstrap_id);
1499 	cmd += (own_bootstrap_id > 0) ?
1500 			" own=" + std::to_string(own_bootstrap_id) : "";
1501 
1502 	/* Check for supported AKMs */
1503 	if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
1504 			security_akm != DppAkm::PSK_SAE && security_akm != DppAkm::DPP) {
1505 		wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
1506 				security_akm);
1507 		return {std::vector<uint8_t>(),
1508 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1509 	}
1510 
1511 	/* SAE AKM requires SSID and password to be initialized */
1512 	if ((security_akm == DppAkm::SAE ||
1513 			security_akm == DppAkm::PSK_SAE) &&
1514 			(ssid.empty() || password.empty())) {
1515 		wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified");
1516 		return {std::vector<uint8_t>(),
1517 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1518 	} else if (security_akm == DppAkm::PSK ||
1519 			security_akm == DppAkm::PSK_SAE) {
1520 		/* PSK AKM requires SSID and password/psk to be initialized */
1521 		if (ssid.empty()) {
1522 			wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified");
1523 			return {std::vector<uint8_t>(),
1524 				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1525 		}
1526 		if (password.empty() && psk.empty()) {
1527 			wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
1528 			return {std::vector<uint8_t>(),
1529 				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1530 		}
1531 	}
1532 
1533 	cmd += " role=configurator";
1534 	cmd += (ssid.empty()) ? "" : " ssid=" + ssid;
1535 
1536 	if (!psk.empty()) {
1537 		cmd += " psk=" + psk;
1538 	} else {
1539 		cmd += (password.empty()) ? "" : " pass=" + password;
1540 	}
1541 
1542 	std::string role = "";
1543 	if (net_role == DppNetRole::AP) {
1544 		role = "ap-";
1545 	}
1546 	else {
1547 		role = "sta-";
1548 	}
1549 
1550 	switch (security_akm) {
1551 	case DppAkm::PSK:
1552 		role += "psk";
1553 		break;
1554 
1555 	case DppAkm::SAE:
1556 		role += "sae";
1557 		break;
1558 
1559 	case DppAkm::PSK_SAE:
1560 		role += "psk-sae";
1561 		break;
1562 
1563 	case DppAkm::DPP:
1564 		role += "dpp";
1565 		break;
1566 
1567 	default:
1568 		wpa_printf(MSG_ERROR,
1569 			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
1570 		return {std::vector<uint8_t>(),
1571 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1572 	}
1573 
1574 	cmd += " conf=";
1575 	cmd += role;
1576 
1577 	if (net_role == DppNetRole::STA) {
1578 		/* DPP R2 connection status request */
1579 		cmd += " conn_status=1";
1580 	}
1581 
1582 	if (security_akm == DppAkm::DPP) {
1583 		if (!privEcKey.empty()) {
1584 			cmd2 += " key=" + std::string(privEcKey.begin(), privEcKey.end());
1585 		}
1586 		id = dpp_configurator_add(wpa_s->dpp, cmd2.c_str());
1587 		if (id < 0 || (privEcKey.empty() &&
1588 			       (dpp_configurator_get_key_id(wpa_s->dpp, id, key, sizeof(key)) < 0)))
1589 		{
1590 			wpa_printf(MSG_ERROR, "DPP configurator add failed. "
1591 			           "Input key might be incorrect");
1592 			return {std::vector<uint8_t>(),
1593 				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1594 		}
1595 
1596 		cmd += " configurator=" + std::to_string(id);
1597 	}
1598 
1599 	wpa_printf(MSG_DEBUG,
1600 		   "DPP initiator command: %s", cmd.c_str());
1601 
1602 	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1603 		// Return key if input privEcKey was null/empty.
1604 		if (security_akm == DppAkm::DPP && privEcKey.empty()) {
1605 			std::string k(key);
1606 			std::vector<uint8_t> vKey(k.begin(), k.end());
1607 			return {vKey, ndk::ScopedAStatus::ok()};
1608 		}
1609 		return {std::vector<uint8_t>(), ndk::ScopedAStatus::ok()};
1610 	}
1611 #endif
1612 	return {std::vector<uint8_t>(), createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1613 }
1614 
startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id)1615 ndk::ScopedAStatus StaIface::startDppEnrolleeInitiatorInternal(
1616 	uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id) {
1617 #ifdef CONFIG_DPP
1618 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1619 	std::string cmd = "";
1620 
1621 	/* Report received configuration to AIDL and create an internal profile */
1622 	wpa_s->conf->dpp_config_processing = 1;
1623 
1624 	cmd += " peer=" + std::to_string(peer_bootstrap_id);
1625 	cmd += (own_bootstrap_id > 0) ?
1626 			" own=" + std::to_string(own_bootstrap_id) : "";
1627 
1628 	cmd += " role=enrollee";
1629 
1630 	wpa_printf(MSG_DEBUG,
1631 		   "DPP initiator command: %s", cmd.c_str());
1632 
1633 	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1634 		return ndk::ScopedAStatus::ok();
1635 	}
1636 #endif
1637 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1638 }
stopDppInitiatorInternal()1639 ndk::ScopedAStatus StaIface::stopDppInitiatorInternal()
1640 {
1641 #ifdef CONFIG_DPP
1642 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1643 
1644 	wpas_dpp_stop(wpa_s);
1645 	return ndk::ScopedAStatus::ok();
1646 #else
1647 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1648 #endif
1649 }
1650 
1651 std::pair<DppResponderBootstrapInfo, ndk::ScopedAStatus>
generateDppBootstrapInfoForResponderInternal(const std::vector<uint8_t> & mac_address,const std::string & device_info,DppCurve curve)1652 StaIface::generateDppBootstrapInfoForResponderInternal(
1653 	const std::vector<uint8_t> &mac_address,
1654 	const std::string& device_info, DppCurve curve)
1655 {
1656 #ifdef CONFIG_DPP
1657 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1658 	std::string cmd = "type=qrcode";
1659 	int32_t id;
1660 	int32_t listen_channel = 0;
1661 	DppResponderBootstrapInfo bootstrap_info;
1662 	const char *uri;
1663 	std::string listen_channel_str;
1664 	std::string mac_addr_str;
1665 	char buf[3] = {0};
1666 
1667 	cmd += (device_info.empty()) ? "" : " info=" + device_info;
1668 
1669 	listen_channel_str = getDppListenChannel(wpa_s, &listen_channel);
1670 	if (listen_channel == 0) {
1671 		wpa_printf(MSG_ERROR, "StaIface: Failed to derive DPP listen channel");
1672 		return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1673 	}
1674 	cmd += " chan=" + listen_channel_str;
1675 
1676 	if (mac_address.size() != ETH_ALEN) {
1677 		return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1678 	}
1679 	cmd += " mac=";
1680 	for (int i = 0;i < 6;i++) {
1681 		snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
1682 		mac_addr_str.append(buf);
1683 	}
1684 	cmd += mac_addr_str;
1685 
1686 	cmd += " curve=" + convertCurveTypeToName(curve);
1687 
1688 	id = dpp_bootstrap_gen(wpa_s->dpp, cmd.c_str());
1689 	wpa_printf(MSG_DEBUG,
1690 		   "DPP generate bootstrap QR code command: %s id: %d", cmd.c_str(), id);
1691 	if (id > 0) {
1692 		uri = dpp_bootstrap_get_uri(wpa_s->dpp, id);
1693 		if (uri) {
1694 			wpa_printf(MSG_DEBUG, "DPP Bootstrap info: id: %d "
1695 				   "listen_channel: %d uri: %s", id, listen_channel, uri);
1696 			bootstrap_info.bootstrapId = id;
1697 			bootstrap_info.listenChannel = listen_channel;
1698 			bootstrap_info.uri = uri;
1699 			return {bootstrap_info, ndk::ScopedAStatus::ok()};
1700 		}
1701 	}
1702 	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1703 #else
1704 	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
1705 #endif
1706 }
1707 
startDppEnrolleeResponderInternal(uint32_t listen_channel)1708 ndk::ScopedAStatus StaIface::startDppEnrolleeResponderInternal(uint32_t listen_channel)
1709 {
1710 #ifdef CONFIG_DPP
1711 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1712 	std::string cmd = "";
1713 	uint32_t freq = (listen_channel <= 14 ? 2407 : 5000) + listen_channel * 5;
1714 
1715 	/* Report received configuration to AIDL and create an internal profile */
1716 	wpa_s->conf->dpp_config_processing = 1;
1717 
1718 	cmd += std::to_string(freq);
1719 	cmd += " role=enrollee netrole=sta";
1720 
1721 	wpa_printf(MSG_DEBUG,
1722 		   "DPP Enrollee Responder command: %s", cmd.c_str());
1723 
1724 	if (wpas_dpp_listen(wpa_s, cmd.c_str()) == 0) {
1725 		return ndk::ScopedAStatus::ok();
1726 	}
1727 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1728 #else
1729 	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1730 #endif
1731 }
1732 
stopDppResponderInternal(uint32_t own_bootstrap_id)1733 ndk::ScopedAStatus StaIface::stopDppResponderInternal(uint32_t own_bootstrap_id)
1734 {
1735 #ifdef CONFIG_DPP
1736 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1737 	std::string bootstrap_id_str;
1738 
1739 	if (own_bootstrap_id == 0) {
1740 		bootstrap_id_str = "*";
1741 	}
1742 	else {
1743 		bootstrap_id_str = std::to_string(own_bootstrap_id);
1744 	}
1745 
1746 	wpa_printf(MSG_DEBUG, "DPP Stop DPP Responder id: %d ", own_bootstrap_id);
1747 	wpas_dpp_stop(wpa_s);
1748 	wpas_dpp_listen_stop(wpa_s);
1749 
1750 	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) < 0) {
1751 		wpa_printf(MSG_ERROR, "StaIface: dpp_bootstrap_remove failed");
1752 	}
1753 
1754 	return ndk::ScopedAStatus::ok();
1755 #else
1756 	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1757 #endif
1758 }
1759 
generateSelfDppConfigurationInternal(const std::string & ssid,const std::vector<uint8_t> & privEcKey)1760 ndk::ScopedAStatus StaIface::generateSelfDppConfigurationInternal(const std::string& ssid,
1761 		const std::vector<uint8_t> &privEcKey)
1762 {
1763 #ifdef CONFIG_DPP
1764 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1765 	std::string cmd = "";
1766 	char *ssid_hex_str;
1767 	int len;
1768 	int32_t id;
1769 
1770 	if (ssid.empty() || privEcKey.empty()) {
1771 		wpa_printf(MSG_ERROR, "DPP generate self configuration failed. ssid/key empty");
1772 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1773 	}
1774 
1775 	cmd += " key=" + std::string(privEcKey.begin(), privEcKey.end());
1776 
1777 	id = dpp_configurator_add(wpa_s->dpp, cmd.c_str());
1778 	if (id < 0) {
1779 		wpa_printf(MSG_ERROR, "DPP configurator add failed. Input key might be incorrect");
1780 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1781 	}
1782 
1783 	cmd = " conf=sta-dpp";
1784 	cmd += " configurator=" + std::to_string(id);
1785 
1786 	ssid_hex_str = (char *) os_zalloc(ssid.size() * 2 + 1);
1787 	if (!ssid_hex_str) {
1788 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1789 	}
1790 
1791 	wpa_snprintf_hex(ssid_hex_str, ssid.size() * 2 + 1, (u8*)ssid.data(), ssid.size());
1792 	cmd += " ssid=" + std::string(ssid_hex_str);
1793 
1794 	/* Report received configuration to AIDL and create an internal profile */
1795 	wpa_s->conf->dpp_config_processing = 1;
1796 
1797 	if (wpas_dpp_configurator_sign(wpa_s, cmd.c_str()) == 0) {
1798 		os_free(ssid_hex_str);
1799 		return ndk::ScopedAStatus::ok();
1800 	}
1801 
1802 	os_free(ssid_hex_str);
1803 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1804 #else
1805 	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1806 #endif
1807 }
1808 
1809 std::pair<ConnectionCapabilities, ndk::ScopedAStatus>
getConnectionCapabilitiesInternal()1810 StaIface::getConnectionCapabilitiesInternal()
1811 {
1812 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1813 	ConnectionCapabilities capa;
1814 
1815 	if (wpa_s->connection_set) {
1816 		capa.legacyMode = LegacyMode::UNKNOWN;
1817 		if (wpa_s->connection_eht) {
1818 			capa.technology = WifiTechnology::EHT;
1819 		} else if (wpa_s->connection_he) {
1820 			capa.technology = WifiTechnology::HE;
1821 		} else if (wpa_s->connection_vht) {
1822 			capa.technology = WifiTechnology::VHT;
1823 		} else if (wpa_s->connection_ht) {
1824 			capa.technology = WifiTechnology::HT;
1825 		} else {
1826 			capa.technology = WifiTechnology::LEGACY;
1827 			if (wpas_freq_to_band(wpa_s->assoc_freq) == BAND_2_4_GHZ) {
1828 				capa.legacyMode = (wpa_s->connection_11b_only) ? LegacyMode::B_MODE
1829 						: LegacyMode::G_MODE;
1830 			} else {
1831 				capa.legacyMode = LegacyMode::A_MODE;
1832 			}
1833 		}
1834 		switch (wpa_s->connection_channel_bandwidth) {
1835 		case CHAN_WIDTH_20:
1836 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1837 			break;
1838 		case CHAN_WIDTH_40:
1839 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_40;
1840 			break;
1841 		case CHAN_WIDTH_80:
1842 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80;
1843 			break;
1844 		case CHAN_WIDTH_160:
1845 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_160;
1846 			break;
1847 		case CHAN_WIDTH_80P80:
1848 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
1849 			break;
1850 		case CHAN_WIDTH_320:
1851 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_320;
1852 			break;
1853 		default:
1854 			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1855 			break;
1856 		}
1857 		capa.maxNumberRxSpatialStreams = wpa_s->connection_max_nss_rx;
1858 		capa.maxNumberTxSpatialStreams = wpa_s->connection_max_nss_tx;
1859 	} else {
1860 		capa.technology = WifiTechnology::UNKNOWN;
1861 		capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1862 		capa.maxNumberTxSpatialStreams = 1;
1863 		capa.maxNumberRxSpatialStreams = 1;
1864 		capa.legacyMode = LegacyMode::UNKNOWN;
1865 	}
1866 	return {capa, ndk::ScopedAStatus::ok()};
1867 }
1868 
1869 std::pair<WpaDriverCapabilitiesMask, ndk::ScopedAStatus>
getWpaDriverCapabilitiesInternal()1870 StaIface::getWpaDriverCapabilitiesInternal()
1871 {
1872 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1873 	uint32_t mask = 0;
1874 
1875 #ifdef CONFIG_MBO
1876 	/* MBO has no capability flags. It's mainly legacy 802.11v BSS
1877 	 * transition + Cellular steering. 11v is a default feature in
1878 	 * supplicant. And cellular steering is handled in framework.
1879 	 */
1880 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::MBO);
1881 	if (wpa_s->enable_oce & OCE_STA) {
1882 		mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::OCE);
1883 	}
1884 #endif
1885 #ifdef CONFIG_SAE_PK
1886 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SAE_PK);
1887 #endif
1888 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::WFD_R2);
1889 
1890 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
1891 
1892 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SET_TLS_MINIMUM_VERSION);
1893 
1894 #ifdef EAP_TLSV1_3
1895 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TLS_V1_3);
1896 #endif
1897 
1898 	wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
1899 
1900 	return {static_cast<WpaDriverCapabilitiesMask>(mask),
1901 		ndk::ScopedAStatus::ok()};
1902 }
1903 
setMboCellularDataStatusInternal(bool available)1904 ndk::ScopedAStatus StaIface::setMboCellularDataStatusInternal(bool available)
1905 {
1906 #ifdef CONFIG_MBO
1907 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1908 	enum mbo_cellular_capa mbo_cell_capa;
1909 
1910 	if (available) {
1911 		mbo_cell_capa = MBO_CELL_CAPA_AVAILABLE;
1912 	} else {
1913 		mbo_cell_capa = MBO_CELL_CAPA_NOT_AVAILABLE;
1914 	}
1915 
1916 #ifdef ENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
1917 	char mbo_cmd[32];
1918 	char buf[32];
1919 
1920 	os_snprintf(mbo_cmd, sizeof(mbo_cmd), "%s %d", "MBO CELL_DATA_CAP", mbo_cell_capa);
1921 	if (wpa_drv_driver_cmd(wpa_s, mbo_cmd, buf, sizeof(buf)) < 0) {
1922 		wpa_printf(MSG_ERROR, "MBO CELL_DATA_CAP cmd failed CAP:%d", mbo_cell_capa);
1923 	}
1924 #else
1925 	wpas_mbo_update_cell_capa(wpa_s, mbo_cell_capa);
1926 #endif
1927 
1928 	return ndk::ScopedAStatus::ok();
1929 #else
1930 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1931 #endif
1932 }
1933 
1934 std::pair<KeyMgmtMask, ndk::ScopedAStatus>
getKeyMgmtCapabilitiesInternal()1935 StaIface::getKeyMgmtCapabilitiesInternal()
1936 {
1937 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1938 	struct wpa_driver_capa capa;
1939 
1940 	/* Get capabilities from driver and populate the key management mask */
1941 	if (wpa_drv_get_capa(wpa_s, &capa) < 0) {
1942 		return {static_cast<KeyMgmtMask>(0),
1943 			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1944 	}
1945 
1946 	return {convertWpaKeyMgmtCapabilitiesToAidl(wpa_s, &capa),
1947 		ndk::ScopedAStatus::ok()};
1948 }
1949 
setQosPolicyFeatureEnabledInternal(bool enable)1950 ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabledInternal(bool enable)
1951 {
1952 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1953 	wpa_s->enable_dscp_policy_capa = enable ? 1 : 0;
1954 	return ndk::ScopedAStatus::ok();
1955 }
1956 
sendQosPolicyResponseInternal(int32_t qos_policy_request_id,bool more_policies,const std::vector<QosPolicyStatus> & qos_policy_status_list)1957 ndk::ScopedAStatus StaIface::sendQosPolicyResponseInternal(
1958 	int32_t qos_policy_request_id, bool more_policies,
1959 	const std::vector<QosPolicyStatus>& qos_policy_status_list)
1960 {
1961 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1962 	struct dscp_resp_data resp_data;
1963 	int num_policies = qos_policy_status_list.size();
1964 
1965 	memset(&resp_data, 0, sizeof(resp_data));
1966 
1967 	resp_data.more = more_policies ? 1 : 0;
1968 	resp_data.policy = (struct dscp_policy_status *) malloc(
1969 		sizeof(struct dscp_policy_status) * num_policies);
1970 	if (num_policies && !resp_data.policy){
1971 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1972 	}
1973 
1974 	resp_data.solicited = true;
1975 	wpa_s->dscp_req_dialog_token = qos_policy_request_id;
1976 
1977 	for (int i = 0; i < num_policies; i++) {
1978 		resp_data.policy[i].id = qos_policy_status_list.at(i).policyId;
1979 		resp_data.policy[i].status =
1980 			static_cast<uint8_t>(qos_policy_status_list.at(i).status);
1981 	}
1982 	resp_data.num_policies = num_policies;
1983 
1984 	if (wpas_send_dscp_response(wpa_s, &resp_data)) {
1985 		free(resp_data.policy);
1986 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1987 	}
1988 
1989 	free(resp_data.policy);
1990 	return ndk::ScopedAStatus::ok();
1991 }
1992 
removeAllQosPoliciesInternal()1993 ndk::ScopedAStatus StaIface::removeAllQosPoliciesInternal()
1994 {
1995 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1996 	struct dscp_resp_data resp_data;
1997 
1998 	memset(&resp_data, 0, sizeof(resp_data));
1999 	resp_data.reset = true;
2000 	resp_data.solicited = false;
2001 	wpa_s->dscp_req_dialog_token = 0;
2002 
2003 	if (wpas_send_dscp_response(wpa_s, &resp_data)) {
2004 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
2005 	}
2006 	return ndk::ScopedAStatus::ok();
2007 }
2008 
getConnectionMloLinksInfoInternal()2009 std::pair<MloLinksInfo, ndk::ScopedAStatus> StaIface::getConnectionMloLinksInfoInternal()
2010 {
2011 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
2012 	struct driver_sta_mlo_info mlo;
2013 	MloLinksInfo linksInfo;
2014 	MloLink link;
2015 
2016 	linksInfo.apMldMacAddress = macAddrToArray(wpa_s->ap_mld_addr);
2017 	if (!wpa_s->valid_links)
2018 		 return {linksInfo, ndk::ScopedAStatus::ok()};
2019 
2020 	wpas_drv_get_sta_mlo_info(wpa_s, &mlo);
2021 	for (int i = 0; i < MAX_NUM_MLD_LINKS; i++) {
2022 		if (!(wpa_s->valid_links & BIT(i)))
2023 			continue;
2024 
2025 		wpa_printf(MSG_DEBUG, "Add MLO Link ID %d info", i);
2026 		// Associated link id.
2027 		if (os_memcmp(wpa_s->links[i].bssid, wpa_s->bssid, ETH_ALEN) == 0) {
2028 			linksInfo.apMloLinkId = i;
2029 		}
2030 		link.linkId = i;
2031 		link.staLinkMacAddress.assign(
2032 		    wpa_s->links[i].addr, wpa_s->links[i].addr + ETH_ALEN);
2033 		link.apLinkMacAddress = macAddrToArray(wpa_s->links[i].bssid);
2034 		link.frequencyMHz = wpa_s->links[i].freq;
2035 		// TODO (b/259710591): Once supplicant implements TID-to-link
2036 		// mapping, copy it here. Mapping can be changed in two
2037 		// scenarios
2038 		//    1. Mandatory mapping from AP
2039 		//    2. Negotiated mapping
2040 		// After association, framework call this API to get
2041 		// MloLinksInfo. If there is an update in mapping later, notify
2042 		// framework on the change using the callback,
2043 		// ISupplicantStaIfaceCallback.onMloLinksInfoChanged() with
2044 		// reason code as TID_TO_LINK_MAP. In absence of an advertised
2045 		// mapping by the AP, a default TID-to-link mapping is assumed
2046 		// unless an individual TID-to-link mapping is successfully
2047 		// negotiated.
2048 		if (!mlo.default_map) {
2049 			link.tidsUplinkMap = mlo.links[i].t2lmap.uplink;
2050 			link.tidsDownlinkMap = mlo.links[i].t2lmap.downlink;
2051 		} else {
2052 			link.tidsUplinkMap = 0xFF;
2053 			link.tidsDownlinkMap = 0xFF;
2054 		}
2055 		linksInfo.links.push_back(link);
2056 	}
2057 
2058 	return {linksInfo, ndk::ScopedAStatus::ok()};
2059 }
2060 
2061 std::pair<std::vector<SignalPollResult>, ndk::ScopedAStatus>
getSignalPollResultsInternal()2062 StaIface::getSignalPollResultsInternal()
2063 {
2064 	std::vector<SignalPollResult> results;
2065 	struct wpa_signal_info si;
2066 	struct wpa_mlo_signal_info mlo_si;
2067 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
2068 
2069 	if (wpa_s->valid_links && (wpa_drv_mlo_signal_poll(wpa_s, &mlo_si) == 0)) {
2070 		for (int i = 0; i < MAX_NUM_MLD_LINKS; i++) {
2071 			if (!(mlo_si.valid_links & BIT(i)))
2072 				continue;
2073 
2074 			SignalPollResult result;
2075 			result.linkId = i;
2076 			result.currentRssiDbm = mlo_si.links[i].data.signal;
2077 			result.txBitrateMbps = mlo_si.links[i].data.current_tx_rate / 1000;
2078 			result.rxBitrateMbps = mlo_si.links[i].data.current_rx_rate / 1000;
2079 			result.frequencyMhz = mlo_si.links[i].frequency;
2080 			results.push_back(result);
2081 		}
2082 	} else if (wpa_drv_signal_poll(wpa_s, &si) == 0) {
2083 		SignalPollResult result;
2084 		result.linkId = 0;
2085 		result.currentRssiDbm = si.data.signal;
2086 		result.txBitrateMbps = si.data.current_tx_rate / 1000;
2087 		result.rxBitrateMbps = si.data.current_rx_rate / 1000;
2088 		result.frequencyMhz = si.frequency;
2089 		results.push_back(result);
2090 	}
2091 
2092 	return {results, ndk::ScopedAStatus::ok()};
2093 }
2094 
set_type4_frame_classifier(QosPolicyScsData qos_policy_data,struct type4_params * param)2095 static int set_type4_frame_classifier(QosPolicyScsData qos_policy_data,
2096 				      struct type4_params *param)
2097 {
2098 	u8 classifier_mask = 0;
2099 	uint32_t inMask = static_cast<uint32_t>(qos_policy_data.classifierParams.classifierParamMask);
2100 
2101 	if (qos_policy_data.classifierParams.ipVersion ==
2102 	    IpVersion::VERSION_4) {
2103 		param->ip_version = IPV4;
2104 	} else if (qos_policy_data.classifierParams.ipVersion ==
2105 	    IpVersion::VERSION_6) {
2106 		param->ip_version = IPV6;
2107 	} else {
2108 		wpa_printf(MSG_ERROR, "IP version missing/invalid");
2109 		return -1;
2110 	}
2111 
2112 	/* Classifier Mask - bit 0 = Ip Version */
2113 	classifier_mask |= BIT(0);
2114 
2115 	if (inMask & static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_IP)) {
2116 		if (param->ip_version == IPV4) {
2117 			if (qos_policy_data.classifierParams.srcIp.size() !=
2118 			    sizeof(param->ip_params.v4.src_ip)) {
2119 				wpa_printf(MSG_ERROR, "Invalid source IP");
2120 				return -1;
2121 			}
2122 			os_memcpy(&param->ip_params.v4.src_ip, qos_policy_data.classifierParams.srcIp.data(), 4);
2123 		} else {
2124 			if (qos_policy_data.classifierParams.srcIp.size() !=
2125 			    sizeof(param->ip_params.v6.src_ip)) {
2126 				wpa_printf(MSG_ERROR, "Invalid source IP");
2127 				return -1;
2128 			}
2129 			os_memcpy(&param->ip_params.v6.src_ip, qos_policy_data.classifierParams.srcIp.data(), 16);
2130 		}
2131 
2132 		/* Classifier Mask - bit 1 = Source IP Address */
2133 		classifier_mask |= BIT(1);
2134 	}
2135 
2136 	if (inMask & static_cast<uint32_t>(QosPolicyClassifierParamsMask::DST_IP)) {
2137 		if (param->ip_version == IPV4) {
2138 			if (qos_policy_data.classifierParams.dstIp.size() !=
2139 			    sizeof(param->ip_params.v4.dst_ip)) {
2140 				wpa_printf(MSG_ERROR, "Invalid destination IP");
2141 				return -1;
2142 			}
2143 			os_memcpy(&param->ip_params.v4.dst_ip, qos_policy_data.classifierParams.dstIp.data(), 4);
2144 		} else {
2145 			if (qos_policy_data.classifierParams.dstIp.size() !=
2146 			    sizeof(param->ip_params.v6.dst_ip)) {
2147 				wpa_printf(MSG_ERROR, "Invalid destination IP");
2148 				return -1;
2149 			}
2150 			os_memcpy(&param->ip_params.v6.dst_ip, qos_policy_data.classifierParams.dstIp.data(), 16);
2151 		}
2152 
2153 		/* Classifier Mask - bit 2 = Destination IP Address */
2154 		classifier_mask |= BIT(2);
2155 	}
2156 
2157 	if ((inMask & static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_PORT))
2158 			&& (qos_policy_data.classifierParams.srcPort > 0)) {
2159 		if (param->ip_version == IPV4)
2160 			param->ip_params.v4.src_port = qos_policy_data.classifierParams.srcPort;
2161 		else
2162 			param->ip_params.v6.src_port = qos_policy_data.classifierParams.srcPort;
2163 
2164 		/* Classifier Mask - bit 3 = Source Port */
2165 		classifier_mask |= BIT(3);
2166 	}
2167 
2168 	if ((inMask & static_cast<uint32_t>(QosPolicyClassifierParamsMask::DST_PORT_RANGE))
2169 			&& (qos_policy_data.classifierParams.dstPortRange.startPort > 0)) {
2170 		if (param->ip_version == IPV4)
2171 			param->ip_params.v4.dst_port = qos_policy_data.classifierParams.dstPortRange.startPort;
2172 		else
2173 			param->ip_params.v6.dst_port = qos_policy_data.classifierParams.dstPortRange.startPort;
2174 
2175 		/* Classifier Mask - bit 4 = Destination Port range */
2176 		classifier_mask |= BIT(4);
2177 	}
2178 
2179 	if ((inMask & static_cast<uint32_t>(QosPolicyClassifierParamsMask::DSCP))
2180 			&& (qos_policy_data.classifierParams.dscp > 0)) {
2181 		if (param->ip_version == IPV4)
2182 			param->ip_params.v4.dscp = qos_policy_data.classifierParams.dscp;
2183 		else
2184 			param->ip_params.v6.dscp = qos_policy_data.classifierParams.dscp;
2185 
2186 		/* Classifier Mask - bit 5 = DSCP */
2187 		classifier_mask |= BIT(5);
2188 	}
2189 
2190 	if (inMask & static_cast<uint32_t>(QosPolicyClassifierParamsMask::PROTOCOL_NEXT_HEADER)) {
2191 		if (!((qos_policy_data.classifierParams.protocolNextHdr ==
2192 		       ProtocolNextHeader::TCP) ||
2193 		      (qos_policy_data.classifierParams.protocolNextHdr ==
2194 		       ProtocolNextHeader::UDP) ||
2195 		      (qos_policy_data.classifierParams.protocolNextHdr ==
2196 		       ProtocolNextHeader::ESP))) {
2197 			wpa_printf(MSG_ERROR, "Invalid protocol");
2198 			return -1;
2199 		}
2200 		if (param->ip_version == IPV4) {
2201 			param->ip_params.v4.protocol =
2202 				(u8)qos_policy_data.classifierParams.protocolNextHdr;
2203 		} else {
2204 			param->ip_params.v6.next_header =
2205 				(u8)qos_policy_data.classifierParams.protocolNextHdr;
2206 		}
2207 
2208 		/* Classifier Mask - bit 6 = Protocol Number*/
2209 		classifier_mask |= BIT(6);
2210 	}
2211 
2212 	if (inMask & static_cast<uint32_t>(QosPolicyClassifierParamsMask::FLOW_LABEL)) {
2213 		if (qos_policy_data.classifierParams.flowLabelIpv6.size() !=
2214 		    sizeof(param->ip_params.v6.flow_label)) {
2215 			wpa_printf(MSG_ERROR, "Invalid flow label");
2216 			return -1;
2217 		}
2218 		os_memcpy(param->ip_params.v6.flow_label, qos_policy_data.classifierParams.flowLabelIpv6.data(),
2219 			  sizeof(qos_policy_data.classifierParams.flowLabelIpv6));
2220 
2221 		/* Classifier Mask - bit 7 = flow level */
2222 		classifier_mask |= BIT(7);
2223 	}
2224 
2225 	param->classifier_mask = classifier_mask;
2226 	return 0;
2227 }
2228 
scs_parse_type4(struct tclas_element * elem,QosPolicyScsData qos_policy_data)2229 static int scs_parse_type4(struct tclas_element *elem, QosPolicyScsData qos_policy_data)
2230 {
2231 	struct type4_params type4_param;
2232 	memset(&type4_param, 0, sizeof(type4_param));
2233 
2234 	if (set_type4_frame_classifier(qos_policy_data, &type4_param) < 0) {
2235 		wpa_printf(MSG_ERROR, "Failed to set frame_classifier 4");
2236 		return -1;
2237 	}
2238 
2239 	os_memcpy(&elem->frame_classifier.type4_param,
2240 		  &type4_param, sizeof(struct type4_params));
2241 	return 0;
2242 }
2243 
2244 /**
2245  * This is a request to the AP (if it supports the feature) to apply the QoS policy
2246  * on traffic in the Downlink.
2247  */
2248 std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
addQosPolicyRequestForScsInternal(const std::vector<QosPolicyScsData> & qosPolicyData)2249 StaIface::addQosPolicyRequestForScsInternal(const std::vector<QosPolicyScsData>& qosPolicyData)
2250 {
2251 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
2252 	struct scs_robust_av_data *scs_data = &wpa_s->scs_robust_av_req;
2253 	struct scs_desc_elem desc_elem;
2254 	int user_priority, num_qos_policies;
2255 	unsigned int num_scs_ids = 0;
2256 	std::vector<QosPolicyScsRequestStatus> reports;
2257 
2258 	if (wpa_s->ongoing_scs_req) {
2259 		wpa_printf(MSG_ERROR, "AIDL: SCS Request already in queue");
2260 		return {std::vector<QosPolicyScsRequestStatus>(),
2261 			createStatus(SupplicantStatusCode::FAILURE_ONGOING_REQUEST)};
2262 	}
2263 	free_up_scs_desc(scs_data);
2264 
2265 	/**
2266 	 * format:
2267 	 * [scs_id=<decimal number>] [scs_up=<0-7>]
2268 	 * [classifier params based on classifier type]
2269 	 * [scs_id=<decimal number>] ...
2270 	 */
2271 	num_qos_policies = qosPolicyData.size();
2272 	for (int i = 0; i < num_qos_policies; i++) {
2273 		struct scs_desc_elem *new_desc_elems;
2274 		struct active_scs_elem *active_scs_desc;
2275 		struct tclas_element *elem;
2276 		bool scsid_active = false;
2277 		QosPolicyScsRequestStatus status;
2278 
2279 		memset(&desc_elem, 0, sizeof(desc_elem));
2280 		desc_elem.scs_id = qosPolicyData[i].policyId;
2281 		status.policyId = desc_elem.scs_id;
2282 		desc_elem.request_type = SCS_REQ_ADD;
2283 		dl_list_for_each(active_scs_desc, &wpa_s->active_scs_ids,
2284 				 struct active_scs_elem, list) {
2285 			if (desc_elem.scs_id == active_scs_desc->scs_id) {
2286 				scsid_active = true;
2287 				break;
2288 			}
2289 		}
2290 
2291 		if (scsid_active) {
2292 			wpa_printf(MSG_ERROR, "SCSID %d already active",
2293 				   desc_elem.scs_id);
2294 			status.qosPolicyScsRequestStatusCode = QosPolicyScsRequestStatusCode::ALREADY_ACTIVE;
2295 			reports.push_back(status);
2296 			continue;
2297 		}
2298 
2299 		status.qosPolicyScsRequestStatusCode = QosPolicyScsRequestStatusCode::INVALID;
2300 		user_priority = qosPolicyData[i].userPriority;
2301 		if (user_priority < 0 || user_priority > 7) {
2302 			wpa_printf(MSG_ERROR,
2303 				   "Intra-Access user priority invalid %d", user_priority);
2304 			reports.push_back(status);
2305 			continue;
2306 		}
2307 
2308 		desc_elem.intra_access_priority = user_priority;
2309 		desc_elem.scs_up_avail = true;
2310 
2311 		/**
2312 		 * Supported classifier type 4.
2313 		 */
2314 		desc_elem.tclas_elems = (struct tclas_element *) os_malloc(sizeof(struct tclas_element));
2315 		if (!desc_elem.tclas_elems) {
2316 			wpa_printf(MSG_ERROR,
2317 				   "Classifier type4 failed with Bad malloc");
2318 			reports.push_back(status);
2319 			continue;
2320 		}
2321 
2322 		elem = desc_elem.tclas_elems;
2323 		memset(elem, 0, sizeof(struct tclas_element));
2324 		elem->classifier_type = 4;
2325 		if (scs_parse_type4(elem, qosPolicyData[i]) < 0) {
2326 			os_free(elem);
2327 			reports.push_back(status);
2328 			continue;
2329 		}
2330 
2331 		desc_elem.num_tclas_elem = 1;
2332 
2333 		/* Reallocate memory to scs_desc_elems to accomodate further policies */
2334 		new_desc_elems = static_cast<struct scs_desc_elem *>(os_realloc(scs_data->scs_desc_elems,
2335 				(num_scs_ids + 1) * sizeof(struct scs_desc_elem)));
2336 		if (!new_desc_elems) {
2337 			os_free(elem);
2338 			reports.push_back(status);
2339 			continue;
2340 		}
2341 
2342 		scs_data->scs_desc_elems = new_desc_elems;
2343 		os_memcpy((u8 *) scs_data->scs_desc_elems + num_scs_ids *
2344 			  sizeof(desc_elem), &desc_elem, sizeof(desc_elem));
2345 		num_scs_ids++;
2346 		scs_data->num_scs_desc = num_scs_ids;
2347 		status.qosPolicyScsRequestStatusCode = QosPolicyScsRequestStatusCode::SENT;
2348 		reports.push_back(status);
2349 	}
2350 	wpas_send_scs_req(wpa_s);
2351 	return {std::vector<QosPolicyScsRequestStatus>(reports),
2352 		ndk::ScopedAStatus::ok()};
2353 }
2354 
2355 std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
removeQosPolicyForScsInternal(const std::vector<uint8_t> & scsPolicyIds)2356 StaIface::removeQosPolicyForScsInternal(const std::vector<uint8_t>& scsPolicyIds)
2357 {
2358 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
2359 	struct scs_robust_av_data *scs_data = &wpa_s->scs_robust_av_req;
2360 	struct scs_desc_elem desc_elem;
2361 	int count;
2362 	unsigned int num_scs_ids = 0;
2363 	std::vector<QosPolicyScsRequestStatus> reports;
2364 	struct active_scs_elem *scs_desc;
2365 
2366 	if (wpa_s->ongoing_scs_req) {
2367 		wpa_printf(MSG_ERROR, "AIDL: SCS Request already in queue");
2368 		return {std::vector<QosPolicyScsRequestStatus>(),
2369 			createStatus(SupplicantStatusCode::FAILURE_ONGOING_REQUEST)};
2370 	}
2371 	free_up_scs_desc(scs_data);
2372 
2373 	count = scsPolicyIds.size();
2374 	for (int i = 0; i < count; i++) {
2375 		struct scs_desc_elem *new_desc_elems;
2376 		QosPolicyScsRequestStatus status;
2377 		bool policy_id_exists = false;
2378 
2379 		memset(&desc_elem, 0, sizeof(desc_elem));
2380 		desc_elem.scs_id = scsPolicyIds[i];
2381 		status.policyId = scsPolicyIds[i];
2382 		desc_elem.request_type = SCS_REQ_REMOVE;
2383 		dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
2384 				struct active_scs_elem, list) {
2385 			if (desc_elem.scs_id == scs_desc->scs_id) {
2386 				policy_id_exists = true;
2387 				break;
2388 			}
2389 		}
2390 		if (policy_id_exists == false) {
2391 			status.qosPolicyScsRequestStatusCode = QosPolicyScsRequestStatusCode::NOT_EXIST;
2392 			reports.push_back(status);
2393 			continue;
2394 		}
2395 
2396 		new_desc_elems = static_cast<struct scs_desc_elem *>(os_realloc(scs_data->scs_desc_elems, (num_scs_ids + 1) *
2397 				sizeof(struct scs_desc_elem)));
2398 		if (!new_desc_elems) {
2399 			status.qosPolicyScsRequestStatusCode = QosPolicyScsRequestStatusCode::INVALID;
2400 			reports.push_back(status);
2401 			continue;
2402 		}
2403 
2404 		scs_data->scs_desc_elems = new_desc_elems;
2405 		os_memcpy((u8 *) scs_data->scs_desc_elems + num_scs_ids *
2406 			  sizeof(desc_elem), &desc_elem, sizeof(desc_elem));
2407 		num_scs_ids++;
2408 		scs_data->num_scs_desc = num_scs_ids;
2409 		status.qosPolicyScsRequestStatusCode = QosPolicyScsRequestStatusCode::SENT;
2410 		reports.push_back(status);
2411 	}
2412 	wpas_send_scs_req(wpa_s);
2413 
2414 	return {std::vector<QosPolicyScsRequestStatus>(reports),
2415 		ndk::ScopedAStatus::ok()};
2416 }
2417 
2418 /**
2419  * Retrieve the underlying |wpa_supplicant| struct
2420  * pointer for this iface.
2421  * If the underlying iface is removed, then all RPC method calls on this object
2422  * will return failure.
2423  */
retrieveIfacePtr()2424 wpa_supplicant *StaIface::retrieveIfacePtr()
2425 {
2426 	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
2427 }
2428 }  // namespace supplicant
2429 }  // namespace wifi
2430 }  // namespace hardware
2431 }  // namespace android
2432 }  // namespace aidl
2433