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