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(¶m->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(¶m->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(¶m->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(¶m->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