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