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