1 /*
2 * WPA Supplicant - Sta Iface Aidl interface
3 * Copyright (c) 2021, Google Inc. All rights reserved.
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "aidl_manager.h"
10 #include "aidl_return_util.h"
11 #include "iface_config_utils.h"
12 #include "misc_utils.h"
13 #include "sta_iface.h"
14
15 extern "C"
16 {
17 #include "utils/eloop.h"
18 #include "gas_query.h"
19 #include "interworking.h"
20 #include "hs20_supplicant.h"
21 #include "wps_supplicant.h"
22 #include "dpp.h"
23 #include "dpp_supplicant.h"
24 #include "rsn_supp/wpa.h"
25 #include "rsn_supp/pmksa_cache.h"
26 }
27
28 namespace {
29 using aidl::android::hardware::wifi::supplicant::AidlManager;
30 using aidl::android::hardware::wifi::supplicant::BtCoexistenceMode;
31 using aidl::android::hardware::wifi::supplicant::ConnectionCapabilities;
32 using aidl::android::hardware::wifi::supplicant::DppCurve;
33 using aidl::android::hardware::wifi::supplicant::DppResponderBootstrapInfo;
34 using aidl::android::hardware::wifi::supplicant::ISupplicant;
35 using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
36 using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
37 using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
38 using aidl::android::hardware::wifi::supplicant::LegacyMode;
39 using aidl::android::hardware::wifi::supplicant::RxFilterType;
40 using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
41 using aidl::android::hardware::wifi::supplicant::WifiTechnology;
42 using aidl::android::hardware::wifi::supplicant::misc_utils::createStatus;
43
44 // TODO (b/204810426): Import from wifi vendor AIDL interface when it exists
45 enum WifiChannelWidthInMhz {
46 WIDTH_20 = 0,
47 WIDTH_40 = 1,
48 WIDTH_80 = 2,
49 WIDTH_160 = 3,
50 WIDTH_80P80 = 4,
51 WIDTH_5 = 5,
52 WIDTH_10 = 6,
53 WIDTH_INVALID = -1
54 };
55
56 constexpr uint32_t kMaxAnqpElems = 100;
57 constexpr char kGetMacAddress[] = "MACADDR";
58 constexpr char kStartRxFilter[] = "RXFILTER-START";
59 constexpr char kStopRxFilter[] = "RXFILTER-STOP";
60 constexpr char kAddRxFilter[] = "RXFILTER-ADD";
61 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
62 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
63 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
64 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
65 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
66 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
67 constexpr char kSetCountryCode[] = "COUNTRY";
68 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec =
69 static_cast<uint32_t>(ISupplicant::EXT_RADIO_WORK_TIMEOUT_IN_SECS);
70 constexpr char kExtRadioWorkNamePrefix[] = "ext:";
71
convertAidlRxFilterTypeToInternal(RxFilterType type)72 uint8_t convertAidlRxFilterTypeToInternal(
73 RxFilterType type)
74 {
75 switch (type) {
76 case RxFilterType::V4_MULTICAST:
77 return 2;
78 case RxFilterType::V6_MULTICAST:
79 return 3;
80 };
81 WPA_ASSERT(false);
82 }
83
convertAidlBtCoexModeToInternal(BtCoexistenceMode mode)84 uint8_t convertAidlBtCoexModeToInternal(
85 BtCoexistenceMode mode)
86 {
87 switch (mode) {
88 case BtCoexistenceMode::ENABLED:
89 return 0;
90 case BtCoexistenceMode::DISABLED:
91 return 1;
92 case BtCoexistenceMode::SENSE:
93 return 2;
94 };
95 WPA_ASSERT(false);
96 }
97
doZeroArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd)98 ndk::ScopedAStatus doZeroArgDriverCommand(
99 struct wpa_supplicant *wpa_s, const char *cmd)
100 {
101 std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
102 char driver_cmd_reply_buf[4096] = {};
103 if (wpa_drv_driver_cmd(
104 wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
105 sizeof(driver_cmd_reply_buf))) {
106 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
107 }
108 return ndk::ScopedAStatus::ok();
109 }
110
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,uint8_t arg)111 ndk::ScopedAStatus doOneArgDriverCommand(
112 struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
113 {
114 std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
115 return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
116 }
117
doOneArgDriverCommand(struct wpa_supplicant * wpa_s,const char * cmd,const std::string & arg)118 ndk::ScopedAStatus doOneArgDriverCommand(
119 struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
120 {
121 std::string cmd_str = std::string(cmd) + " " + arg;
122 return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
123 }
124
endExtRadioWork(struct wpa_radio_work * work)125 void endExtRadioWork(struct wpa_radio_work *work)
126 {
127 auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
128 work->wpa_s->ext_work_in_progress = 0;
129 radio_work_done(work);
130 os_free(ework);
131 }
132
extRadioWorkTimeoutCb(void * eloop_ctx,void * timeout_ctx)133 void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
134 {
135 auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
136 auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
137 wpa_dbg(
138 work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
139 ework->id, work->type);
140
141 AidlManager *aidl_manager = AidlManager::getInstance();
142 WPA_ASSERT(aidl_manager);
143 aidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
144
145 endExtRadioWork(work);
146 }
147
startExtRadioWork(struct wpa_radio_work * work)148 void startExtRadioWork(struct wpa_radio_work *work)
149 {
150 auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
151 work->wpa_s->ext_work_in_progress = 1;
152 if (!ework->timeout) {
153 ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
154 }
155 eloop_register_timeout(
156 ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
157 }
158
extRadioWorkStartCb(struct wpa_radio_work * work,int deinit)159 void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
160 {
161 // deinit==1 is invoked during interface removal. Since the AIDL
162 // interface does not support interface addition/removal, we don't
163 // need to handle this scenario.
164 WPA_ASSERT(!deinit);
165
166 auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
167 wpa_dbg(
168 work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
169 ework->id, ework->type);
170
171 AidlManager *aidl_manager = AidlManager::getInstance();
172 WPA_ASSERT(aidl_manager);
173 aidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
174
175 startExtRadioWork(work);
176 }
177
convertWpaKeyMgmtCapabilitiesToAidl(struct wpa_supplicant * wpa_s,struct wpa_driver_capa * capa)178 KeyMgmtMask convertWpaKeyMgmtCapabilitiesToAidl (
179 struct wpa_supplicant *wpa_s, struct wpa_driver_capa *capa) {
180
181 uint32_t mask = 0;
182 /* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability
183 * flags and always enabled.
184 */
185 mask |=
186 (static_cast<uint32_t>(KeyMgmtMask::NONE) |
187 static_cast<uint32_t>(KeyMgmtMask::IEEE8021X));
188
189 if (capa->key_mgmt &
190 (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
191 mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_EAP);
192 }
193
194 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
195 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
196 mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_PSK);
197 }
198 #ifdef CONFIG_SUITEB192
199 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
200 mask |= static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192);
201 }
202 #endif /* CONFIG_SUITEB192 */
203 #ifdef CONFIG_OWE
204 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
205 mask |= static_cast<uint32_t>(KeyMgmtMask::OWE);
206 }
207 #endif /* CONFIG_OWE */
208 #ifdef CONFIG_SAE
209 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
210 mask |= static_cast<uint32_t>(KeyMgmtMask::SAE);
211 }
212 #endif /* CONFIG_SAE */
213 #ifdef CONFIG_DPP
214 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
215 mask |= static_cast<uint32_t>(KeyMgmtMask::DPP);
216 }
217 #endif
218 #ifdef CONFIG_WAPI_INTERFACE
219 mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK);
220 mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT);
221 #endif /* CONFIG_WAPI_INTERFACE */
222 #ifdef CONFIG_FILS
223 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
224 mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256);
225 }
226 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
227 mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384);
228 }
229 #endif /* CONFIG_FILS */
230 return static_cast<KeyMgmtMask>(mask);
231 }
232
getDppListenChannel(struct wpa_supplicant * wpa_s,int32_t * listen_channel)233 const std::string getDppListenChannel(struct wpa_supplicant *wpa_s, int32_t *listen_channel)
234 {
235 struct hostapd_hw_modes *mode;
236 int chan44 = 0, chan149 = 0;
237 *listen_channel = 0;
238
239 /* Check if device support 2.4GHz band*/
240 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
241 HOSTAPD_MODE_IEEE80211G, 0);
242 if (mode) {
243 *listen_channel = 6;
244 return "81/6";
245 }
246 /* Check if device support 5GHz band */
247 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
248 HOSTAPD_MODE_IEEE80211A, 0);
249 if (mode) {
250 for (int i = 0; i < mode->num_channels; i++) {
251 struct hostapd_channel_data *chan = &mode->channels[i];
252
253 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
254 HOSTAPD_CHAN_RADAR))
255 continue;
256 if (chan->freq == 5220)
257 chan44 = 1;
258 if (chan->freq == 5745)
259 chan149 = 1;
260 }
261 if (chan149) {
262 *listen_channel = 149;
263 return "124/149";
264 } else if (chan44) {
265 *listen_channel = 44;
266 return "115/44";
267 }
268 }
269
270 return "";
271 }
272
convertCurveTypeToName(DppCurve curve)273 const std::string convertCurveTypeToName(DppCurve curve)
274 {
275 switch (curve) {
276 case DppCurve::PRIME256V1:
277 return "prime256v1";
278 case DppCurve::SECP384R1:
279 return "secp384r1";
280 case DppCurve::SECP521R1:
281 return "secp521r1";
282 case DppCurve::BRAINPOOLP256R1:
283 return "brainpoolP256r1";
284 case DppCurve::BRAINPOOLP384R1:
285 return "brainpoolP384r1";
286 case DppCurve::BRAINPOOLP512R1:
287 return "brainpoolP512r1";
288 }
289 WPA_ASSERT(false);
290 }
291
292 } // namespace
293
294 namespace aidl {
295 namespace android {
296 namespace hardware {
297 namespace wifi {
298 namespace supplicant {
299 using aidl_return_util::validateAndCall;
300 using misc_utils::createStatus;
301
StaIface(struct wpa_global * wpa_global,const char ifname[])302 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
303 : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
304 {}
305
invalidate()306 void StaIface::invalidate() { is_valid_ = false; }
isValid()307 bool StaIface::isValid()
308 {
309 return (is_valid_ && (retrieveIfacePtr() != nullptr));
310 }
311
getName(std::string * _aidl_return)312 ::ndk::ScopedAStatus StaIface::getName(
313 std::string* _aidl_return)
314 {
315 return validateAndCall(
316 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
317 &StaIface::getNameInternal, _aidl_return);
318 }
319
getType(IfaceType * _aidl_return)320 ::ndk::ScopedAStatus StaIface::getType(
321 IfaceType* _aidl_return)
322 {
323 return validateAndCall(
324 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
325 &StaIface::getTypeInternal, _aidl_return);
326 }
327
addNetwork(std::shared_ptr<ISupplicantStaNetwork> * _aidl_return)328 ::ndk::ScopedAStatus StaIface::addNetwork(
329 std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
330 {
331 return validateAndCall(
332 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
333 &StaIface::addNetworkInternal, _aidl_return);
334 }
335
removeNetwork(int32_t in_id)336 ::ndk::ScopedAStatus StaIface::removeNetwork(
337 int32_t in_id)
338 {
339 return validateAndCall(
340 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
341 &StaIface::removeNetworkInternal, in_id);
342 }
343
filsHlpFlushRequest()344 ::ndk::ScopedAStatus StaIface::filsHlpFlushRequest()
345 {
346 return validateAndCall(
347 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
348 &StaIface::filsHlpFlushRequestInternal);
349 }
350
filsHlpAddRequest(const std::vector<uint8_t> & in_dst_mac,const std::vector<uint8_t> & in_pkt)351 ::ndk::ScopedAStatus StaIface::filsHlpAddRequest(
352 const std::vector<uint8_t>& in_dst_mac,
353 const std::vector<uint8_t>& in_pkt)
354 {
355 return validateAndCall(
356 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
357 &StaIface::filsHlpAddRequestInternal, in_dst_mac, in_pkt);
358 }
359
getNetwork(int32_t in_id,std::shared_ptr<ISupplicantStaNetwork> * _aidl_return)360 ::ndk::ScopedAStatus StaIface::getNetwork(
361 int32_t in_id, std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
362 {
363 return validateAndCall(
364 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
365 &StaIface::getNetworkInternal, _aidl_return, in_id);
366 }
367
listNetworks(std::vector<int32_t> * _aidl_return)368 ::ndk::ScopedAStatus StaIface::listNetworks(
369 std::vector<int32_t>* _aidl_return)
370 {
371 return validateAndCall(
372 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
373 &StaIface::listNetworksInternal, _aidl_return);
374 }
375
registerCallback(const std::shared_ptr<ISupplicantStaIfaceCallback> & in_callback)376 ::ndk::ScopedAStatus StaIface::registerCallback(
377 const std::shared_ptr<ISupplicantStaIfaceCallback>& in_callback)
378 {
379 return validateAndCall(
380 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
381 &StaIface::registerCallbackInternal, in_callback);
382 }
383
reassociate()384 ::ndk::ScopedAStatus StaIface::reassociate()
385 {
386 return validateAndCall(
387 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
388 &StaIface::reassociateInternal);
389 }
390
reconnect()391 ::ndk::ScopedAStatus StaIface::reconnect()
392 {
393 return validateAndCall(
394 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
395 &StaIface::reconnectInternal);
396 }
397
disconnect()398 ::ndk::ScopedAStatus StaIface::disconnect()
399 {
400 return validateAndCall(
401 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
402 &StaIface::disconnectInternal);
403 }
404
setPowerSave(bool in_enable)405 ::ndk::ScopedAStatus StaIface::setPowerSave(
406 bool in_enable)
407 {
408 return validateAndCall(
409 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
410 &StaIface::setPowerSaveInternal, in_enable);
411 }
412
initiateTdlsDiscover(const std::vector<uint8_t> & in_macAddress)413 ::ndk::ScopedAStatus StaIface::initiateTdlsDiscover(
414 const std::vector<uint8_t>& in_macAddress)
415 {
416 return validateAndCall(
417 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
418 &StaIface::initiateTdlsDiscoverInternal, in_macAddress);
419 }
420
initiateTdlsSetup(const std::vector<uint8_t> & in_macAddress)421 ::ndk::ScopedAStatus StaIface::initiateTdlsSetup(
422 const std::vector<uint8_t>& in_macAddress)
423 {
424 return validateAndCall(
425 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
426 &StaIface::initiateTdlsSetupInternal, in_macAddress);
427 }
428
initiateTdlsTeardown(const std::vector<uint8_t> & in_macAddress)429 ::ndk::ScopedAStatus StaIface::initiateTdlsTeardown(
430 const std::vector<uint8_t>& in_macAddress)
431 {
432 return validateAndCall(
433 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
434 &StaIface::initiateTdlsTeardownInternal, in_macAddress);
435 }
436
initiateAnqpQuery(const std::vector<uint8_t> & in_macAddress,const std::vector<AnqpInfoId> & in_infoElements,const std::vector<Hs20AnqpSubtypes> & in_subTypes)437 ::ndk::ScopedAStatus StaIface::initiateAnqpQuery(
438 const std::vector<uint8_t>& in_macAddress,
439 const std::vector<AnqpInfoId>& in_infoElements,
440 const std::vector<Hs20AnqpSubtypes>& in_subTypes)
441 {
442 return validateAndCall(
443 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
444 &StaIface::initiateAnqpQueryInternal, in_macAddress,
445 in_infoElements, in_subTypes);
446 }
447
initiateVenueUrlAnqpQuery(const std::vector<uint8_t> & in_macAddress)448 ::ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQuery(
449 const std::vector<uint8_t>& in_macAddress)
450 {
451 return validateAndCall(
452 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
453 &StaIface::initiateVenueUrlAnqpQueryInternal, in_macAddress);
454 }
455
initiateHs20IconQuery(const std::vector<uint8_t> & in_macAddress,const std::string & in_fileName)456 ::ndk::ScopedAStatus StaIface::initiateHs20IconQuery(
457 const std::vector<uint8_t>& in_macAddress,
458 const std::string& in_fileName)
459 {
460 return validateAndCall(
461 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
462 &StaIface::initiateHs20IconQueryInternal, in_macAddress,
463 in_fileName);
464 }
465
getMacAddress(std::vector<uint8_t> * _aidl_return)466 ::ndk::ScopedAStatus StaIface::getMacAddress(
467 std::vector<uint8_t>* _aidl_return)
468 {
469 return validateAndCall(
470 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
471 &StaIface::getMacAddressInternal, _aidl_return);
472 }
473
startRxFilter()474 ::ndk::ScopedAStatus StaIface::startRxFilter()
475 {
476 return validateAndCall(
477 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
478 &StaIface::startRxFilterInternal);
479 }
480
stopRxFilter()481 ::ndk::ScopedAStatus StaIface::stopRxFilter()
482 {
483 return validateAndCall(
484 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
485 &StaIface::stopRxFilterInternal);
486 }
487
addRxFilter(RxFilterType in_type)488 ::ndk::ScopedAStatus StaIface::addRxFilter(
489 RxFilterType in_type)
490 {
491 return validateAndCall(
492 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
493 &StaIface::addRxFilterInternal, in_type);
494 }
495
removeRxFilter(RxFilterType in_type)496 ::ndk::ScopedAStatus StaIface::removeRxFilter(
497 RxFilterType in_type)
498 {
499 return validateAndCall(
500 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
501 &StaIface::removeRxFilterInternal, in_type);
502 }
503
setBtCoexistenceMode(BtCoexistenceMode in_mode)504 ::ndk::ScopedAStatus StaIface::setBtCoexistenceMode(
505 BtCoexistenceMode in_mode)
506 {
507 return validateAndCall(
508 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
509 &StaIface::setBtCoexistenceModeInternal, in_mode);
510 }
511
setBtCoexistenceScanModeEnabled(bool in_enable)512 ::ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabled(
513 bool in_enable)
514 {
515 return validateAndCall(
516 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
517 &StaIface::setBtCoexistenceScanModeEnabledInternal,
518 in_enable);
519 }
520
setSuspendModeEnabled(bool in_enable)521 ::ndk::ScopedAStatus StaIface::setSuspendModeEnabled(
522 bool in_enable)
523 {
524 return validateAndCall(
525 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
526 &StaIface::setSuspendModeEnabledInternal, in_enable);
527 }
528
setCountryCode(const std::vector<uint8_t> & in_code)529 ::ndk::ScopedAStatus StaIface::setCountryCode(
530 const std::vector<uint8_t>& in_code)
531 {
532 return validateAndCall(
533 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
534 &StaIface::setCountryCodeInternal, in_code);
535 }
536
startWpsRegistrar(const std::vector<uint8_t> & in_bssid,const std::string & in_pin)537 ::ndk::ScopedAStatus StaIface::startWpsRegistrar(
538 const std::vector<uint8_t>& in_bssid,
539 const std::string& in_pin)
540 {
541 return validateAndCall(
542 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
543 &StaIface::startWpsRegistrarInternal, in_bssid, in_pin);
544 }
545
startWpsPbc(const std::vector<uint8_t> & in_bssid)546 ::ndk::ScopedAStatus StaIface::startWpsPbc(
547 const std::vector<uint8_t>& in_bssid)
548 {
549 return validateAndCall(
550 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
551 &StaIface::startWpsPbcInternal, in_bssid);
552 }
553
startWpsPinKeypad(const std::string & in_pin)554 ::ndk::ScopedAStatus StaIface::startWpsPinKeypad(
555 const std::string& in_pin)
556 {
557 return validateAndCall(
558 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
559 &StaIface::startWpsPinKeypadInternal, in_pin);
560 }
561
startWpsPinDisplay(const std::vector<uint8_t> & in_bssid,std::string * _aidl_return)562 ::ndk::ScopedAStatus StaIface::startWpsPinDisplay(
563 const std::vector<uint8_t>& in_bssid,
564 std::string* _aidl_return)
565 {
566 return validateAndCall(
567 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
568 &StaIface::startWpsPinDisplayInternal, _aidl_return, in_bssid);
569 }
570
cancelWps()571 ::ndk::ScopedAStatus StaIface::cancelWps()
572 {
573 return validateAndCall(
574 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
575 &StaIface::cancelWpsInternal);
576 }
577
setWpsDeviceName(const std::string & in_name)578 ::ndk::ScopedAStatus StaIface::setWpsDeviceName(
579 const std::string& in_name)
580 {
581 return validateAndCall(
582 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
583 &StaIface::setWpsDeviceNameInternal, in_name);
584 }
585
setWpsDeviceType(const std::vector<uint8_t> & in_type)586 ::ndk::ScopedAStatus StaIface::setWpsDeviceType(
587 const std::vector<uint8_t>& in_type)
588 {
589 return validateAndCall(
590 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
591 &StaIface::setWpsDeviceTypeInternal, in_type);
592 }
593
setWpsManufacturer(const std::string & in_manufacturer)594 ::ndk::ScopedAStatus StaIface::setWpsManufacturer(
595 const std::string& in_manufacturer)
596 {
597 return validateAndCall(
598 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
599 &StaIface::setWpsManufacturerInternal, in_manufacturer);
600 }
601
setWpsModelName(const std::string & in_modelName)602 ::ndk::ScopedAStatus StaIface::setWpsModelName(
603 const std::string& in_modelName)
604 {
605 return validateAndCall(
606 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
607 &StaIface::setWpsModelNameInternal, in_modelName);
608 }
609
setWpsModelNumber(const std::string & in_modelNumber)610 ::ndk::ScopedAStatus StaIface::setWpsModelNumber(
611 const std::string& in_modelNumber)
612 {
613 return validateAndCall(
614 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
615 &StaIface::setWpsModelNumberInternal, in_modelNumber);
616 }
617
setWpsSerialNumber(const std::string & in_serialNumber)618 ::ndk::ScopedAStatus StaIface::setWpsSerialNumber(
619 const std::string& in_serialNumber)
620 {
621 return validateAndCall(
622 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
623 &StaIface::setWpsSerialNumberInternal, in_serialNumber);
624 }
625
setWpsConfigMethods(WpsConfigMethods in_configMethods)626 ::ndk::ScopedAStatus StaIface::setWpsConfigMethods(
627 WpsConfigMethods in_configMethods)
628 {
629 return validateAndCall(
630 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
631 &StaIface::setWpsConfigMethodsInternal, in_configMethods);
632 }
633
setExternalSim(bool in_useExternalSim)634 ::ndk::ScopedAStatus StaIface::setExternalSim(
635 bool in_useExternalSim)
636 {
637 return validateAndCall(
638 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
639 &StaIface::setExternalSimInternal, in_useExternalSim);
640 }
641
addExtRadioWork(const std::string & in_name,int32_t in_freqInMhz,int32_t in_timeoutInSec,int32_t * _aidl_return)642 ::ndk::ScopedAStatus StaIface::addExtRadioWork(
643 const std::string& in_name, int32_t in_freqInMhz,
644 int32_t in_timeoutInSec,
645 int32_t* _aidl_return)
646 {
647 return validateAndCall(
648 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
649 &StaIface::addExtRadioWorkInternal, _aidl_return, in_name, in_freqInMhz,
650 in_timeoutInSec);
651 }
652
removeExtRadioWork(int32_t in_id)653 ::ndk::ScopedAStatus StaIface::removeExtRadioWork(
654 int32_t in_id)
655 {
656 return validateAndCall(
657 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
658 &StaIface::removeExtRadioWorkInternal, in_id);
659 }
660
enableAutoReconnect(bool in_enable)661 ::ndk::ScopedAStatus StaIface::enableAutoReconnect(
662 bool in_enable)
663 {
664 return validateAndCall(
665 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
666 &StaIface::enableAutoReconnectInternal, in_enable);
667 }
668
getKeyMgmtCapabilities(KeyMgmtMask * _aidl_return)669 ::ndk::ScopedAStatus StaIface::getKeyMgmtCapabilities(
670 KeyMgmtMask* _aidl_return)
671 {
672 return validateAndCall(
673 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
674 &StaIface::getKeyMgmtCapabilitiesInternal, _aidl_return);
675 }
676
addDppPeerUri(const std::string & in_uri,int32_t * _aidl_return)677 ::ndk::ScopedAStatus StaIface::addDppPeerUri(
678 const std::string& in_uri, int32_t* _aidl_return)
679 {
680 return validateAndCall(
681 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
682 &StaIface::addDppPeerUriInternal, _aidl_return, in_uri);
683 }
684
removeDppUri(int32_t in_id)685 ::ndk::ScopedAStatus StaIface::removeDppUri(
686 int32_t in_id)
687 {
688 return validateAndCall(
689 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
690 &StaIface::removeDppUriInternal, in_id);
691 }
692
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)693 ::ndk::ScopedAStatus StaIface::startDppConfiguratorInitiator(
694 int32_t in_peerBootstrapId, int32_t in_ownBootstrapId,
695 const std::string& in_ssid, const std::string& in_password,
696 const std::string& in_psk, DppNetRole in_netRole,
697 DppAkm in_securityAkm, const std::vector<uint8_t>& in_privEcKey,
698 std::vector<uint8_t>* _aidl_return)
699 {
700 return validateAndCall(
701 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
702 &StaIface::startDppConfiguratorInitiatorInternal, _aidl_return,
703 in_peerBootstrapId,in_ownBootstrapId, in_ssid, in_password,
704 in_psk, in_netRole, in_securityAkm, in_privEcKey);
705 }
706
startDppEnrolleeInitiator(int32_t in_peerBootstrapId,int32_t in_ownBootstrapId)707 ::ndk::ScopedAStatus StaIface::startDppEnrolleeInitiator(
708 int32_t in_peerBootstrapId, int32_t in_ownBootstrapId)
709 {
710 return validateAndCall(
711 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
712 &StaIface::startDppEnrolleeInitiatorInternal, in_peerBootstrapId,
713 in_ownBootstrapId);
714 }
715
stopDppInitiator()716 ::ndk::ScopedAStatus StaIface::stopDppInitiator()
717 {
718 return validateAndCall(
719 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
720 &StaIface::stopDppInitiatorInternal);
721 }
722
getConnectionCapabilities(ConnectionCapabilities * _aidl_return)723 ::ndk::ScopedAStatus StaIface::getConnectionCapabilities(
724 ConnectionCapabilities* _aidl_return)
725 {
726 return validateAndCall(
727 this, SupplicantStatusCode::FAILURE_UNKNOWN,
728 &StaIface::getConnectionCapabilitiesInternal,
729 _aidl_return);
730 }
731
generateDppBootstrapInfoForResponder(const std::vector<uint8_t> & in_macAddress,const std::string & in_deviceInfo,DppCurve in_curve,DppResponderBootstrapInfo * _aidl_return)732 ::ndk::ScopedAStatus StaIface::generateDppBootstrapInfoForResponder(
733 const std::vector<uint8_t>& in_macAddress, const std::string& in_deviceInfo,
734 DppCurve in_curve, DppResponderBootstrapInfo* _aidl_return)
735 {
736 return validateAndCall(
737 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
738 &StaIface::generateDppBootstrapInfoForResponderInternal, _aidl_return,
739 in_macAddress, in_deviceInfo, in_curve);
740 }
741
startDppEnrolleeResponder(int32_t in_listenChannel)742 ::ndk::ScopedAStatus StaIface::startDppEnrolleeResponder(
743 int32_t in_listenChannel)
744 {
745 return validateAndCall(
746 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
747 &StaIface::startDppEnrolleeResponderInternal, in_listenChannel);
748 }
749
stopDppResponder(int32_t in_ownBootstrapId)750 ::ndk::ScopedAStatus StaIface::stopDppResponder(
751 int32_t in_ownBootstrapId)
752 {
753 return validateAndCall(
754 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
755 &StaIface::stopDppResponderInternal, in_ownBootstrapId);
756 }
757
generateSelfDppConfiguration(const std::string & in_ssid,const std::vector<uint8_t> & in_privEcKey)758 ::ndk::ScopedAStatus StaIface::generateSelfDppConfiguration(
759 const std::string& in_ssid, const std::vector<uint8_t>& in_privEcKey)
760 {
761 return validateAndCall(
762 this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
763 &StaIface::generateSelfDppConfigurationInternal, in_ssid, in_privEcKey);
764 }
765
getWpaDriverCapabilities(WpaDriverCapabilitiesMask * _aidl_return)766 ::ndk::ScopedAStatus StaIface::getWpaDriverCapabilities(
767 WpaDriverCapabilitiesMask* _aidl_return)
768 {
769 return validateAndCall(
770 this, SupplicantStatusCode::FAILURE_UNKNOWN,
771 &StaIface::getWpaDriverCapabilitiesInternal, _aidl_return);
772 }
773
setMboCellularDataStatus(bool in_available)774 ::ndk::ScopedAStatus StaIface::setMboCellularDataStatus(
775 bool in_available)
776 {
777 return validateAndCall(
778 this, SupplicantStatusCode::FAILURE_UNKNOWN,
779 &StaIface::setMboCellularDataStatusInternal, in_available);
780 }
781
setQosPolicyFeatureEnabled(bool in_enable)782 ::ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabled(
783 bool in_enable)
784 {
785 return validateAndCall(
786 this, SupplicantStatusCode::FAILURE_UNKNOWN,
787 &StaIface::setQosPolicyFeatureEnabledInternal, in_enable);
788 }
789
sendQosPolicyResponse(int32_t in_qosPolicyRequestId,bool in_morePolicies,const std::vector<QosPolicyStatus> & in_qosPolicyStatusList)790 ::ndk::ScopedAStatus StaIface::sendQosPolicyResponse(
791 int32_t in_qosPolicyRequestId, bool in_morePolicies,
792 const std::vector<QosPolicyStatus>& in_qosPolicyStatusList)
793 {
794 return validateAndCall(
795 this, SupplicantStatusCode::FAILURE_UNKNOWN,
796 &StaIface::sendQosPolicyResponseInternal, in_qosPolicyRequestId,
797 in_morePolicies, in_qosPolicyStatusList);
798 }
799
removeAllQosPolicies()800 ::ndk::ScopedAStatus StaIface::removeAllQosPolicies()
801 {
802 return validateAndCall(
803 this, SupplicantStatusCode::FAILURE_UNKNOWN,
804 &StaIface::removeAllQosPoliciesInternal);
805 }
806
getConnectionMloLinksInfo(MloLinksInfo * _aidl_return)807 ::ndk::ScopedAStatus StaIface::getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) {
808 return validateAndCall(
809 this, SupplicantStatusCode::FAILURE_UNKNOWN,
810 &StaIface::getConnectionMloLinksInfoInternal, _aidl_return);
811 }
812
getNameInternal()813 std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
814 {
815 return {ifname_, ndk::ScopedAStatus::ok()};
816 }
817
getTypeInternal()818 std::pair<IfaceType, ndk::ScopedAStatus> StaIface::getTypeInternal()
819 {
820 return {IfaceType::STA, ndk::ScopedAStatus::ok()};
821 }
822
filsHlpFlushRequestInternal()823 ndk::ScopedAStatus StaIface::filsHlpFlushRequestInternal()
824 {
825 #ifdef CONFIG_FILS
826 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
827
828 wpas_flush_fils_hlp_req(wpa_s);
829 return ndk::ScopedAStatus::ok();
830 #else /* CONFIG_FILS */
831 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN, "");
832 #endif /* CONFIG_FILS */
833 }
834
filsHlpAddRequestInternal(const std::vector<uint8_t> & dst_mac,const std::vector<uint8_t> & pkt)835 ndk::ScopedAStatus StaIface::filsHlpAddRequestInternal(
836 const std::vector<uint8_t> &dst_mac, const std::vector<uint8_t> &pkt)
837 {
838 #ifdef CONFIG_FILS
839 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
840 struct fils_hlp_req *req;
841
842 if (!pkt.size())
843 return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
844 if (dst_mac.size() != ETH_ALEN)
845 return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
846
847
848 req = (struct fils_hlp_req *)os_zalloc(sizeof(*req));
849 if (!req)
850 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
851
852 os_memcpy(req->dst, dst_mac.data(), ETH_ALEN);
853
854 req->pkt = wpabuf_alloc_copy(pkt.data(), pkt.size());
855 if (!req->pkt) {
856 os_free(req);
857 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
858 }
859
860 dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
861 return ndk::ScopedAStatus::ok();
862 #else /* CONFIG_FILS */
863 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
864 #endif /* CONFIG_FILS */
865 }
866
867 std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
addNetworkInternal()868 StaIface::addNetworkInternal()
869 {
870 std::shared_ptr<ISupplicantStaNetwork> network;
871 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
872 struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
873 if (!ssid) {
874 return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
875 }
876 AidlManager *aidl_manager = AidlManager::getInstance();
877 if (!aidl_manager ||
878 aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
879 wpa_s->ifname, ssid->id, &network)) {
880 return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
881 }
882 return {network, ndk::ScopedAStatus::ok()};
883 }
884
removeNetworkInternal(int32_t id)885 ndk::ScopedAStatus StaIface::removeNetworkInternal(int32_t id)
886 {
887 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
888 int result = wpa_supplicant_remove_network(wpa_s, id);
889 if (result == -1) {
890 return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
891 }
892 if (result != 0) {
893 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
894 }
895 return ndk::ScopedAStatus::ok();
896 }
897
898 std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
getNetworkInternal(int32_t id)899 StaIface::getNetworkInternal(int32_t id)
900 {
901 std::shared_ptr<ISupplicantStaNetwork> network;
902 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
903 struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
904 if (!ssid) {
905 return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
906 }
907 AidlManager *aidl_manager = AidlManager::getInstance();
908 if (!aidl_manager ||
909 aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
910 wpa_s->ifname, ssid->id, &network)) {
911 return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
912 }
913 return {network, ndk::ScopedAStatus::ok()};
914 }
915
916 std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
listNetworksInternal()917 StaIface::listNetworksInternal()
918 {
919 std::vector<int32_t> network_ids;
920 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
921 for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
922 wpa_ssid = wpa_ssid->next) {
923 network_ids.emplace_back(wpa_ssid->id);
924 }
925 return {std::move(network_ids), ndk::ScopedAStatus::ok()};
926 }
927
registerCallbackInternal(const std::shared_ptr<ISupplicantStaIfaceCallback> & callback)928 ndk::ScopedAStatus StaIface::registerCallbackInternal(
929 const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
930 {
931 AidlManager *aidl_manager = AidlManager::getInstance();
932 if (!aidl_manager ||
933 aidl_manager->addStaIfaceCallbackAidlObject(ifname_, callback)) {
934 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
935 }
936 return ndk::ScopedAStatus::ok();
937 }
938
reassociateInternal()939 ndk::ScopedAStatus StaIface::reassociateInternal()
940 {
941 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
942 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
943 return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
944 }
945 wpas_request_connection(wpa_s);
946 return ndk::ScopedAStatus::ok();
947 }
948
reconnectInternal()949 ndk::ScopedAStatus StaIface::reconnectInternal()
950 {
951 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
952 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
953 return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
954 }
955 if (!wpa_s->disconnected) {
956 return createStatus(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
957 }
958 wpas_request_connection(wpa_s);
959 return ndk::ScopedAStatus::ok();
960 }
961
disconnectInternal()962 ndk::ScopedAStatus StaIface::disconnectInternal()
963 {
964 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
965 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
966 return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
967 }
968 wpas_request_disconnection(wpa_s);
969 return ndk::ScopedAStatus::ok();
970 }
971
setPowerSaveInternal(bool enable)972 ndk::ScopedAStatus StaIface::setPowerSaveInternal(bool enable)
973 {
974 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
975 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
976 return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
977 }
978 if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
979 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
980 }
981 return ndk::ScopedAStatus::ok();
982 }
983
initiateTdlsDiscoverInternal(const std::vector<uint8_t> & mac_address)984 ndk::ScopedAStatus StaIface::initiateTdlsDiscoverInternal(
985 const std::vector<uint8_t> &mac_address)
986 {
987 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
988 int ret;
989 if (mac_address.size() != ETH_ALEN) {
990 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
991 }
992 const u8 *peer = mac_address.data();
993 if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
994 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
995 } else {
996 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
997 }
998 if (ret) {
999 wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
1000 }
1001 return ndk::ScopedAStatus::ok();
1002 }
1003
initiateTdlsSetupInternal(const std::vector<uint8_t> & mac_address)1004 ndk::ScopedAStatus StaIface::initiateTdlsSetupInternal(
1005 const std::vector<uint8_t> &mac_address)
1006 {
1007 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1008 int ret;
1009 if (mac_address.size() != ETH_ALEN) {
1010 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1011 }
1012 const u8 *peer = mac_address.data();
1013 if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
1014 !(wpa_s->conf->tdls_external_control)) {
1015 wpa_tdls_remove(wpa_s->wpa, peer);
1016 ret = wpa_tdls_start(wpa_s->wpa, peer);
1017 } else {
1018 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
1019 }
1020 if (ret) {
1021 wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
1022 }
1023 return ndk::ScopedAStatus::ok();
1024 }
1025
initiateTdlsTeardownInternal(const std::vector<uint8_t> & mac_address)1026 ndk::ScopedAStatus StaIface::initiateTdlsTeardownInternal(
1027 const std::vector<uint8_t> &mac_address)
1028 {
1029 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1030 int ret;
1031 if (mac_address.size() != ETH_ALEN) {
1032 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1033 }
1034 const u8 *peer = mac_address.data();
1035 if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
1036 !(wpa_s->conf->tdls_external_control)) {
1037 ret = wpa_tdls_teardown_link(
1038 wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
1039 } else {
1040 ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
1041 }
1042 if (ret) {
1043 wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
1044 }
1045 return ndk::ScopedAStatus::ok();
1046 }
1047
initiateAnqpQueryInternal(const std::vector<uint8_t> & mac_address,const std::vector<AnqpInfoId> & info_elements,const std::vector<Hs20AnqpSubtypes> & sub_types)1048 ndk::ScopedAStatus StaIface::initiateAnqpQueryInternal(
1049 const std::vector<uint8_t> &mac_address,
1050 const std::vector<AnqpInfoId> &info_elements,
1051 const std::vector<Hs20AnqpSubtypes> &sub_types)
1052 {
1053 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1054 if (info_elements.size() > kMaxAnqpElems) {
1055 return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
1056 }
1057 uint16_t info_elems_buf[kMaxAnqpElems];
1058 uint32_t num_info_elems = 0;
1059 for (const auto &info_element : info_elements) {
1060 info_elems_buf[num_info_elems++] =
1061 static_cast<std::underlying_type<
1062 AnqpInfoId>::type>(info_element);
1063 }
1064 uint32_t sub_types_bitmask = 0;
1065 for (const auto &type : sub_types) {
1066 sub_types_bitmask |= BIT(
1067 static_cast<std::underlying_type<
1068 Hs20AnqpSubtypes>::type>(type));
1069 }
1070 if (mac_address.size() != ETH_ALEN) {
1071 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1072 }
1073
1074 if (anqp_send_req(
1075 wpa_s, mac_address.data(), 0, info_elems_buf, num_info_elems,
1076 sub_types_bitmask, 0)) {
1077 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1078 }
1079 return ndk::ScopedAStatus::ok();
1080 }
1081
initiateVenueUrlAnqpQueryInternal(const std::vector<uint8_t> & mac_address)1082 ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQueryInternal(
1083 const std::vector<uint8_t> &mac_address)
1084 {
1085 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1086 uint16_t info_elems_buf[1] = {ANQP_VENUE_URL};
1087 if (mac_address.size() != ETH_ALEN) {
1088 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1089 }
1090
1091 if (anqp_send_req(
1092 wpa_s, mac_address.data(), 0, info_elems_buf, 1, 0, 0)) {
1093 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1094 }
1095 return ndk::ScopedAStatus::ok();
1096 }
1097
initiateHs20IconQueryInternal(const std::vector<uint8_t> & mac_address,const std::string & file_name)1098 ndk::ScopedAStatus StaIface::initiateHs20IconQueryInternal(
1099 const std::vector<uint8_t> &mac_address, const std::string &file_name)
1100 {
1101 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1102 if (mac_address.size() != ETH_ALEN) {
1103 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1104 }
1105 wpa_s->fetch_osu_icon_in_progress = 0;
1106 if (hs20_anqp_send_req(
1107 wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
1108 reinterpret_cast<const uint8_t *>(file_name.c_str()),
1109 file_name.size(), true)) {
1110 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1111 }
1112 return ndk::ScopedAStatus::ok();
1113 }
1114
1115 std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
getMacAddressInternal()1116 StaIface::getMacAddressInternal()
1117 {
1118 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1119 std::vector<char> cmd(
1120 kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
1121 char driver_cmd_reply_buf[4096] = {};
1122 int ret = wpa_drv_driver_cmd(
1123 wpa_s, cmd.data(), driver_cmd_reply_buf,
1124 sizeof(driver_cmd_reply_buf));
1125 // Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
1126 std::string reply_str = driver_cmd_reply_buf;
1127 if (ret < 0 || reply_str.empty() ||
1128 reply_str.find("=") == std::string::npos) {
1129 return {std::vector<uint8_t>(),
1130 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1131 }
1132 // Remove all whitespace first and then split using the delimiter "=".
1133 reply_str.erase(
1134 remove_if(reply_str.begin(), reply_str.end(), isspace),
1135 reply_str.end());
1136 std::string mac_addr_str =
1137 reply_str.substr(reply_str.find("=") + 1, reply_str.size());
1138 std::vector<uint8_t> mac_addr(6);
1139 if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
1140 return {std::vector<uint8_t>(),
1141 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1142 }
1143 return {mac_addr, ndk::ScopedAStatus::ok()};
1144 }
1145
startRxFilterInternal()1146 ndk::ScopedAStatus StaIface::startRxFilterInternal()
1147 {
1148 return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
1149 }
1150
stopRxFilterInternal()1151 ndk::ScopedAStatus StaIface::stopRxFilterInternal()
1152 {
1153 return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
1154 }
1155
addRxFilterInternal(RxFilterType type)1156 ndk::ScopedAStatus StaIface::addRxFilterInternal(
1157 RxFilterType type)
1158 {
1159 return doOneArgDriverCommand(
1160 retrieveIfacePtr(), kAddRxFilter,
1161 convertAidlRxFilterTypeToInternal(type));
1162 }
1163
removeRxFilterInternal(RxFilterType type)1164 ndk::ScopedAStatus StaIface::removeRxFilterInternal(
1165 RxFilterType type)
1166 {
1167 return doOneArgDriverCommand(
1168 retrieveIfacePtr(), kRemoveRxFilter,
1169 convertAidlRxFilterTypeToInternal(type));
1170 }
1171
setBtCoexistenceModeInternal(BtCoexistenceMode mode)1172 ndk::ScopedAStatus StaIface::setBtCoexistenceModeInternal(
1173 BtCoexistenceMode mode)
1174 {
1175 return doOneArgDriverCommand(
1176 retrieveIfacePtr(), kSetBtCoexistenceMode,
1177 convertAidlBtCoexModeToInternal(mode));
1178 }
1179
setBtCoexistenceScanModeEnabledInternal(bool enable)1180 ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
1181 {
1182 const char *cmd;
1183 if (enable) {
1184 cmd = kSetBtCoexistenceScanStart;
1185 } else {
1186 cmd = kSetBtCoexistenceScanStop;
1187 }
1188 return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
1189 }
1190
setSuspendModeEnabledInternal(bool enable)1191 ndk::ScopedAStatus StaIface::setSuspendModeEnabledInternal(bool enable)
1192 {
1193 const char *cmd;
1194 if (enable) {
1195 cmd = kSetSupendModeEnabled;
1196 } else {
1197 cmd = kSetSupendModeDisabled;
1198 }
1199 return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
1200 }
1201
setCountryCodeInternal(const std::vector<uint8_t> & code)1202 ndk::ScopedAStatus StaIface::setCountryCodeInternal(
1203 const std::vector<uint8_t> &code)
1204 {
1205 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1206 //2-Character alphanumeric country code
1207 if (code.size() != 2) {
1208 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1209 }
1210 ndk::ScopedAStatus status = doOneArgDriverCommand(
1211 wpa_s, kSetCountryCode,
1212 std::string(std::begin(code), std::end(code)));
1213 if (!status.isOk()) {
1214 return status;
1215 }
1216 struct p2p_data *p2p = wpa_s->global->p2p;
1217 if (p2p) {
1218 char country[3];
1219 country[0] = code[0];
1220 country[1] = code[1];
1221 country[2] = 0x04;
1222 p2p_set_country(p2p, country);
1223 }
1224 return ndk::ScopedAStatus::ok();
1225 }
1226
startWpsRegistrarInternal(const std::vector<uint8_t> & bssid,const std::string & pin)1227 ndk::ScopedAStatus StaIface::startWpsRegistrarInternal(
1228 const std::vector<uint8_t> &bssid, const std::string &pin)
1229 {
1230 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1231 if (bssid.size() != ETH_ALEN) {
1232 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1233 }
1234 if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
1235 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1236 }
1237 return ndk::ScopedAStatus::ok();
1238 }
1239
startWpsPbcInternal(const std::vector<uint8_t> & bssid)1240 ndk::ScopedAStatus StaIface::startWpsPbcInternal(
1241 const std::vector<uint8_t> &bssid)
1242 {
1243 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1244 if (bssid.size() != ETH_ALEN) {
1245 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1246 }
1247 const uint8_t *bssid_addr =
1248 is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1249 if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
1250 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1251 }
1252 return ndk::ScopedAStatus::ok();
1253 }
1254
startWpsPinKeypadInternal(const std::string & pin)1255 ndk::ScopedAStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
1256 {
1257 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1258 if (wpas_wps_start_pin(
1259 wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
1260 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1261 }
1262 return ndk::ScopedAStatus::ok();
1263 }
1264
startWpsPinDisplayInternal(const std::vector<uint8_t> & bssid)1265 std::pair<std::string, ndk::ScopedAStatus> StaIface::startWpsPinDisplayInternal(
1266 const std::vector<uint8_t> &bssid)
1267 {
1268 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1269 if (bssid.size() != ETH_ALEN) {
1270 return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1271 }
1272 const uint8_t *bssid_addr =
1273 is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
1274 int pin =
1275 wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
1276 if (pin < 0) {
1277 return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1278 }
1279 return {misc_utils::convertWpsPinToString(pin),
1280 ndk::ScopedAStatus::ok()};
1281 }
1282
cancelWpsInternal()1283 ndk::ScopedAStatus StaIface::cancelWpsInternal()
1284 {
1285 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1286 if (wpas_wps_cancel(wpa_s)) {
1287 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1288 }
1289 return ndk::ScopedAStatus::ok();
1290 }
1291
setWpsDeviceNameInternal(const std::string & name)1292 ndk::ScopedAStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
1293 {
1294 return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
1295 }
1296
setWpsDeviceTypeInternal(const std::vector<uint8_t> & type)1297 ndk::ScopedAStatus StaIface::setWpsDeviceTypeInternal(
1298 const std::vector<uint8_t> &type)
1299 {
1300 std::array<uint8_t, 8> type_arr;
1301 std::copy_n(type.begin(), 8, type_arr.begin());
1302 return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
1303 }
1304
setWpsManufacturerInternal(const std::string & manufacturer)1305 ndk::ScopedAStatus StaIface::setWpsManufacturerInternal(
1306 const std::string &manufacturer)
1307 {
1308 return iface_config_utils::setWpsManufacturer(
1309 retrieveIfacePtr(), manufacturer);
1310 }
1311
setWpsModelNameInternal(const std::string & model_name)1312 ndk::ScopedAStatus StaIface::setWpsModelNameInternal(
1313 const std::string &model_name)
1314 {
1315 return iface_config_utils::setWpsModelName(
1316 retrieveIfacePtr(), model_name);
1317 }
1318
setWpsModelNumberInternal(const std::string & model_number)1319 ndk::ScopedAStatus StaIface::setWpsModelNumberInternal(
1320 const std::string &model_number)
1321 {
1322 return iface_config_utils::setWpsModelNumber(
1323 retrieveIfacePtr(), model_number);
1324 }
1325
setWpsSerialNumberInternal(const std::string & serial_number)1326 ndk::ScopedAStatus StaIface::setWpsSerialNumberInternal(
1327 const std::string &serial_number)
1328 {
1329 return iface_config_utils::setWpsSerialNumber(
1330 retrieveIfacePtr(), serial_number);
1331 }
1332
setWpsConfigMethodsInternal(WpsConfigMethods config_methods)1333 ndk::ScopedAStatus StaIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
1334 {
1335 return iface_config_utils::setWpsConfigMethods(
1336 retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
1337 }
1338
setExternalSimInternal(bool useExternalSim)1339 ndk::ScopedAStatus StaIface::setExternalSimInternal(bool useExternalSim)
1340 {
1341 return iface_config_utils::setExternalSim(
1342 retrieveIfacePtr(), useExternalSim);
1343 }
1344
addExtRadioWorkInternal(const std::string & name,uint32_t freq_in_mhz,uint32_t timeout_in_sec)1345 std::pair<uint32_t, ndk::ScopedAStatus> StaIface::addExtRadioWorkInternal(
1346 const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
1347 {
1348 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1349 auto *ework = static_cast<struct wpa_external_work *>(
1350 os_zalloc(sizeof(struct wpa_external_work)));
1351 if (!ework) {
1352 return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1353 }
1354
1355 std::string radio_work_name = kExtRadioWorkNamePrefix + name;
1356 os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
1357 ework->timeout = timeout_in_sec;
1358 wpa_s->ext_work_id++;
1359 if (wpa_s->ext_work_id == 0) {
1360 wpa_s->ext_work_id++;
1361 }
1362 ework->id = wpa_s->ext_work_id;
1363
1364 if (radio_add_work(
1365 wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
1366 ework)) {
1367 os_free(ework);
1368 return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1369 }
1370 return {ework->id, ndk::ScopedAStatus::ok()};
1371 }
1372
removeExtRadioWorkInternal(uint32_t id)1373 ndk::ScopedAStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
1374 {
1375 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1376 struct wpa_radio_work *work;
1377 dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
1378 {
1379 if (os_strncmp(
1380 work->type, kExtRadioWorkNamePrefix,
1381 sizeof(kExtRadioWorkNamePrefix)) != 0)
1382 continue;
1383
1384 auto *ework =
1385 static_cast<struct wpa_external_work *>(work->ctx);
1386 if (ework->id != id)
1387 continue;
1388
1389 wpa_dbg(
1390 wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
1391 ework->id, ework->type);
1392 eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
1393 endExtRadioWork(work);
1394
1395 return ndk::ScopedAStatus::ok();
1396 }
1397 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1398 }
1399
enableAutoReconnectInternal(bool enable)1400 ndk::ScopedAStatus StaIface::enableAutoReconnectInternal(bool enable)
1401 {
1402 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1403 wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
1404 return ndk::ScopedAStatus::ok();
1405 }
1406
1407 std::pair<uint32_t, ndk::ScopedAStatus>
addDppPeerUriInternal(const std::string & uri)1408 StaIface::addDppPeerUriInternal(const std::string& uri)
1409 {
1410 #ifdef CONFIG_DPP
1411 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1412 int32_t id;
1413
1414 id = wpas_dpp_qr_code(wpa_s, uri.c_str());
1415
1416 if (id > 0) {
1417 return {id, ndk::ScopedAStatus::ok()};
1418 }
1419 #endif
1420 return {-1, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1421 }
1422
removeDppUriInternal(uint32_t bootstrap_id)1423 ndk::ScopedAStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id)
1424 {
1425 #ifdef CONFIG_DPP
1426 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1427 std::string bootstrap_id_str;
1428
1429 if (bootstrap_id == 0) {
1430 bootstrap_id_str = "*";
1431 }
1432 else {
1433 bootstrap_id_str = std::to_string(bootstrap_id);
1434 }
1435
1436 if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
1437 return ndk::ScopedAStatus::ok();
1438 }
1439 #endif
1440 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1441 }
1442
1443 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)1444 StaIface::startDppConfiguratorInitiatorInternal(
1445 uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id,
1446 const std::string& ssid, const std::string& password,
1447 const std::string& psk, DppNetRole net_role, DppAkm security_akm,
1448 const std::vector<uint8_t> &privEcKey)
1449 {
1450 #ifdef CONFIG_DPP
1451 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1452 std::string cmd = "";
1453 std::string cmd2 = "";
1454 int32_t id;
1455 char key[1024];
1456
1457 if (net_role != DppNetRole::AP &&
1458 net_role != DppNetRole::STA) {
1459 wpa_printf(MSG_ERROR,
1460 "DPP: Error: Invalid network role specified: %d", net_role);
1461 return {std::vector<uint8_t>(),
1462 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1463 }
1464
1465 cmd += " peer=" + std::to_string(peer_bootstrap_id);
1466 cmd += (own_bootstrap_id > 0) ?
1467 " own=" + std::to_string(own_bootstrap_id) : "";
1468
1469 /* Check for supported AKMs */
1470 if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
1471 security_akm != DppAkm::PSK_SAE && security_akm != DppAkm::DPP) {
1472 wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
1473 security_akm);
1474 return {std::vector<uint8_t>(),
1475 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1476 }
1477
1478 /* SAE AKM requires SSID and password to be initialized */
1479 if ((security_akm == DppAkm::SAE ||
1480 security_akm == DppAkm::PSK_SAE) &&
1481 (ssid.empty() || password.empty())) {
1482 wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified");
1483 return {std::vector<uint8_t>(),
1484 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1485 } else if (security_akm == DppAkm::PSK ||
1486 security_akm == DppAkm::PSK_SAE) {
1487 /* PSK AKM requires SSID and password/psk to be initialized */
1488 if (ssid.empty()) {
1489 wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified");
1490 return {std::vector<uint8_t>(),
1491 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1492 }
1493 if (password.empty() && psk.empty()) {
1494 wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
1495 return {std::vector<uint8_t>(),
1496 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1497 }
1498 }
1499
1500 cmd += " role=configurator";
1501 cmd += (ssid.empty()) ? "" : " ssid=" + ssid;
1502
1503 if (!psk.empty()) {
1504 cmd += " psk=" + psk;
1505 } else {
1506 cmd += (password.empty()) ? "" : " pass=" + password;
1507 }
1508
1509 std::string role = "";
1510 if (net_role == DppNetRole::AP) {
1511 role = "ap-";
1512 }
1513 else {
1514 role = "sta-";
1515 }
1516
1517 switch (security_akm) {
1518 case DppAkm::PSK:
1519 role += "psk";
1520 break;
1521
1522 case DppAkm::SAE:
1523 role += "sae";
1524 break;
1525
1526 case DppAkm::PSK_SAE:
1527 role += "psk-sae";
1528 break;
1529
1530 case DppAkm::DPP:
1531 role += "dpp";
1532 break;
1533
1534 default:
1535 wpa_printf(MSG_ERROR,
1536 "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
1537 return {std::vector<uint8_t>(),
1538 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1539 }
1540
1541 cmd += " conf=";
1542 cmd += role;
1543
1544 if (net_role == DppNetRole::STA) {
1545 /* DPP R2 connection status request */
1546 cmd += " conn_status=1";
1547 }
1548
1549 if (security_akm == DppAkm::DPP) {
1550 if (!privEcKey.empty()) {
1551 cmd2 += " key=" + std::string(privEcKey.begin(), privEcKey.end());
1552 }
1553 id = dpp_configurator_add(wpa_s->dpp, cmd2.c_str());
1554 if (id < 0 || (privEcKey.empty() &&
1555 (dpp_configurator_get_key_id(wpa_s->dpp, id, key, sizeof(key)) < 0)))
1556 {
1557 wpa_printf(MSG_ERROR, "DPP configurator add failed. "
1558 "Input key might be incorrect");
1559 return {std::vector<uint8_t>(),
1560 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1561 }
1562
1563 cmd += " configurator=" + std::to_string(id);
1564 }
1565
1566 wpa_printf(MSG_DEBUG,
1567 "DPP initiator command: %s", cmd.c_str());
1568
1569 if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1570 // Return key if input privEcKey was null/empty.
1571 if (security_akm == DppAkm::DPP && privEcKey.empty()) {
1572 std::string k(key);
1573 std::vector<uint8_t> vKey(k.begin(), k.end());
1574 return {vKey, ndk::ScopedAStatus::ok()};
1575 }
1576 return {std::vector<uint8_t>(), ndk::ScopedAStatus::ok()};
1577 }
1578 #endif
1579 return {std::vector<uint8_t>(), createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1580 }
1581
startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,uint32_t own_bootstrap_id)1582 ndk::ScopedAStatus StaIface::startDppEnrolleeInitiatorInternal(
1583 uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id) {
1584 #ifdef CONFIG_DPP
1585 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1586 std::string cmd = "";
1587
1588 /* Report received configuration to AIDL and create an internal profile */
1589 wpa_s->conf->dpp_config_processing = 1;
1590
1591 cmd += " peer=" + std::to_string(peer_bootstrap_id);
1592 cmd += (own_bootstrap_id > 0) ?
1593 " own=" + std::to_string(own_bootstrap_id) : "";
1594
1595 cmd += " role=enrollee";
1596
1597 wpa_printf(MSG_DEBUG,
1598 "DPP initiator command: %s", cmd.c_str());
1599
1600 if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
1601 return ndk::ScopedAStatus::ok();
1602 }
1603 #endif
1604 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1605 }
stopDppInitiatorInternal()1606 ndk::ScopedAStatus StaIface::stopDppInitiatorInternal()
1607 {
1608 #ifdef CONFIG_DPP
1609 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1610
1611 wpas_dpp_stop(wpa_s);
1612 return ndk::ScopedAStatus::ok();
1613 #else
1614 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1615 #endif
1616 }
1617
1618 std::pair<DppResponderBootstrapInfo, ndk::ScopedAStatus>
generateDppBootstrapInfoForResponderInternal(const std::vector<uint8_t> & mac_address,const std::string & device_info,DppCurve curve)1619 StaIface::generateDppBootstrapInfoForResponderInternal(
1620 const std::vector<uint8_t> &mac_address,
1621 const std::string& device_info, DppCurve curve)
1622 {
1623 #ifdef CONFIG_DPP
1624 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1625 std::string cmd = "type=qrcode";
1626 int32_t id;
1627 int32_t listen_channel = 0;
1628 DppResponderBootstrapInfo bootstrap_info;
1629 const char *uri;
1630 std::string listen_channel_str;
1631 std::string mac_addr_str;
1632 char buf[3] = {0};
1633
1634 cmd += (device_info.empty()) ? "" : " info=" + device_info;
1635
1636 listen_channel_str = getDppListenChannel(wpa_s, &listen_channel);
1637 if (listen_channel == 0) {
1638 wpa_printf(MSG_ERROR, "StaIface: Failed to derive DPP listen channel");
1639 return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1640 }
1641 cmd += " chan=" + listen_channel_str;
1642
1643 if (mac_address.size() != ETH_ALEN) {
1644 return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1645 }
1646 cmd += " mac=";
1647 for (int i = 0;i < 6;i++) {
1648 snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
1649 mac_addr_str.append(buf);
1650 }
1651 cmd += mac_addr_str;
1652
1653 cmd += " curve=" + convertCurveTypeToName(curve);
1654
1655 id = dpp_bootstrap_gen(wpa_s->dpp, cmd.c_str());
1656 wpa_printf(MSG_DEBUG,
1657 "DPP generate bootstrap QR code command: %s id: %d", cmd.c_str(), id);
1658 if (id > 0) {
1659 uri = dpp_bootstrap_get_uri(wpa_s->dpp, id);
1660 if (uri) {
1661 wpa_printf(MSG_DEBUG, "DPP Bootstrap info: id: %d "
1662 "listen_channel: %d uri: %s", id, listen_channel, uri);
1663 bootstrap_info.bootstrapId = id;
1664 bootstrap_info.listenChannel = listen_channel;
1665 bootstrap_info.uri = uri;
1666 return {bootstrap_info, ndk::ScopedAStatus::ok()};
1667 }
1668 }
1669 return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1670 #else
1671 return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
1672 #endif
1673 }
1674
startDppEnrolleeResponderInternal(uint32_t listen_channel)1675 ndk::ScopedAStatus StaIface::startDppEnrolleeResponderInternal(uint32_t listen_channel)
1676 {
1677 #ifdef CONFIG_DPP
1678 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1679 std::string cmd = "";
1680 uint32_t freq = (listen_channel <= 14 ? 2407 : 5000) + listen_channel * 5;
1681
1682 /* Report received configuration to AIDL and create an internal profile */
1683 wpa_s->conf->dpp_config_processing = 1;
1684
1685 cmd += std::to_string(freq);
1686 cmd += " role=enrollee netrole=sta";
1687
1688 wpa_printf(MSG_DEBUG,
1689 "DPP Enrollee Responder command: %s", cmd.c_str());
1690
1691 if (wpas_dpp_listen(wpa_s, cmd.c_str()) == 0) {
1692 return ndk::ScopedAStatus::ok();
1693 }
1694 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1695 #else
1696 return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1697 #endif
1698 }
1699
stopDppResponderInternal(uint32_t own_bootstrap_id)1700 ndk::ScopedAStatus StaIface::stopDppResponderInternal(uint32_t own_bootstrap_id)
1701 {
1702 #ifdef CONFIG_DPP
1703 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1704 std::string bootstrap_id_str;
1705
1706 if (own_bootstrap_id == 0) {
1707 bootstrap_id_str = "*";
1708 }
1709 else {
1710 bootstrap_id_str = std::to_string(own_bootstrap_id);
1711 }
1712
1713 wpa_printf(MSG_DEBUG, "DPP Stop DPP Responder id: %d ", own_bootstrap_id);
1714 wpas_dpp_stop(wpa_s);
1715 wpas_dpp_listen_stop(wpa_s);
1716
1717 if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) < 0) {
1718 wpa_printf(MSG_ERROR, "StaIface: dpp_bootstrap_remove failed");
1719 }
1720
1721 return ndk::ScopedAStatus::ok();
1722 #else
1723 return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1724 #endif
1725 }
1726
generateSelfDppConfigurationInternal(const std::string & ssid,const std::vector<uint8_t> & privEcKey)1727 ndk::ScopedAStatus StaIface::generateSelfDppConfigurationInternal(const std::string& ssid,
1728 const std::vector<uint8_t> &privEcKey)
1729 {
1730 #ifdef CONFIG_DPP
1731 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1732 std::string cmd = "";
1733 char *ssid_hex_str;
1734 int len;
1735 int32_t id;
1736
1737 if (ssid.empty() || privEcKey.empty()) {
1738 wpa_printf(MSG_ERROR, "DPP generate self configuration failed. ssid/key empty");
1739 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1740 }
1741
1742 cmd += " key=" + std::string(privEcKey.begin(), privEcKey.end());
1743
1744 id = dpp_configurator_add(wpa_s->dpp, cmd.c_str());
1745 if (id < 0) {
1746 wpa_printf(MSG_ERROR, "DPP configurator add failed. Input key might be incorrect");
1747 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1748 }
1749
1750 cmd = " conf=sta-dpp";
1751 cmd += " configurator=" + std::to_string(id);
1752
1753 ssid_hex_str = (char *) os_zalloc(ssid.size() * 2 + 1);
1754 if (!ssid_hex_str) {
1755 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1756 }
1757
1758 wpa_snprintf_hex(ssid_hex_str, ssid.size() * 2 + 1, (u8*)ssid.data(), ssid.size());
1759 cmd += " ssid=" + std::string(ssid_hex_str);
1760
1761 /* Report received configuration to AIDL and create an internal profile */
1762 wpa_s->conf->dpp_config_processing = 1;
1763
1764 if (wpas_dpp_configurator_sign(wpa_s, cmd.c_str()) == 0) {
1765 os_free(ssid_hex_str);
1766 return ndk::ScopedAStatus::ok();
1767 }
1768
1769 os_free(ssid_hex_str);
1770 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1771 #else
1772 return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
1773 #endif
1774 }
1775
1776 std::pair<ConnectionCapabilities, ndk::ScopedAStatus>
getConnectionCapabilitiesInternal()1777 StaIface::getConnectionCapabilitiesInternal()
1778 {
1779 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1780 ConnectionCapabilities capa;
1781
1782 if (wpa_s->connection_set) {
1783 capa.legacyMode = LegacyMode::UNKNOWN;
1784 if (wpa_s->connection_he) {
1785 capa.technology = WifiTechnology::HE;
1786 } else if (wpa_s->connection_vht) {
1787 capa.technology = WifiTechnology::VHT;
1788 } else if (wpa_s->connection_ht) {
1789 capa.technology = WifiTechnology::HT;
1790 } else {
1791 capa.technology = WifiTechnology::LEGACY;
1792 if (wpas_freq_to_band(wpa_s->assoc_freq) == BAND_2_4_GHZ) {
1793 capa.legacyMode = (wpa_s->connection_11b_only) ? LegacyMode::B_MODE
1794 : LegacyMode::G_MODE;
1795 } else {
1796 capa.legacyMode = LegacyMode::A_MODE;
1797 }
1798 }
1799 switch (wpa_s->connection_channel_bandwidth) {
1800 case CHAN_WIDTH_20:
1801 capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1802 break;
1803 case CHAN_WIDTH_40:
1804 capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_40;
1805 break;
1806 case CHAN_WIDTH_80:
1807 capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80;
1808 break;
1809 case CHAN_WIDTH_160:
1810 capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_160;
1811 break;
1812 case CHAN_WIDTH_80P80:
1813 capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
1814 break;
1815 default:
1816 capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1817 break;
1818 }
1819 capa.maxNumberRxSpatialStreams = wpa_s->connection_max_nss_rx;
1820 capa.maxNumberTxSpatialStreams = wpa_s->connection_max_nss_tx;
1821 } else {
1822 capa.technology = WifiTechnology::UNKNOWN;
1823 capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
1824 capa.maxNumberTxSpatialStreams = 1;
1825 capa.maxNumberRxSpatialStreams = 1;
1826 capa.legacyMode = LegacyMode::UNKNOWN;
1827 }
1828 return {capa, ndk::ScopedAStatus::ok()};
1829 }
1830
1831 std::pair<WpaDriverCapabilitiesMask, ndk::ScopedAStatus>
getWpaDriverCapabilitiesInternal()1832 StaIface::getWpaDriverCapabilitiesInternal()
1833 {
1834 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1835 uint32_t mask = 0;
1836
1837 #ifdef CONFIG_MBO
1838 /* MBO has no capability flags. It's mainly legacy 802.11v BSS
1839 * transition + Cellular steering. 11v is a default feature in
1840 * supplicant. And cellular steering is handled in framework.
1841 */
1842 mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::MBO);
1843 if (wpa_s->enable_oce & OCE_STA) {
1844 mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::OCE);
1845 }
1846 #endif
1847 #ifdef CONFIG_SAE_PK
1848 mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SAE_PK);
1849 #endif
1850 mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::WFD_R2);
1851
1852 mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
1853
1854 wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
1855
1856 return {static_cast<WpaDriverCapabilitiesMask>(mask),
1857 ndk::ScopedAStatus::ok()};
1858 }
1859
setMboCellularDataStatusInternal(bool available)1860 ndk::ScopedAStatus StaIface::setMboCellularDataStatusInternal(bool available)
1861 {
1862 #ifdef CONFIG_MBO
1863 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1864 enum mbo_cellular_capa mbo_cell_capa;
1865
1866 if (available) {
1867 mbo_cell_capa = MBO_CELL_CAPA_AVAILABLE;
1868 } else {
1869 mbo_cell_capa = MBO_CELL_CAPA_NOT_AVAILABLE;
1870 }
1871
1872 #ifdef ENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
1873 char mbo_cmd[32];
1874 char buf[32];
1875
1876 os_snprintf(mbo_cmd, sizeof(mbo_cmd), "%s %d", "MBO CELL_DATA_CAP", mbo_cell_capa);
1877 if (wpa_drv_driver_cmd(wpa_s, mbo_cmd, buf, sizeof(buf)) < 0) {
1878 wpa_printf(MSG_ERROR, "MBO CELL_DATA_CAP cmd failed CAP:%d", mbo_cell_capa);
1879 }
1880 #else
1881 wpas_mbo_update_cell_capa(wpa_s, mbo_cell_capa);
1882 #endif
1883
1884 return ndk::ScopedAStatus::ok();
1885 #else
1886 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1887 #endif
1888 }
1889
1890 std::pair<KeyMgmtMask, ndk::ScopedAStatus>
getKeyMgmtCapabilitiesInternal()1891 StaIface::getKeyMgmtCapabilitiesInternal()
1892 {
1893 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1894 struct wpa_driver_capa capa;
1895
1896 /* Get capabilities from driver and populate the key management mask */
1897 if (wpa_drv_get_capa(wpa_s, &capa) < 0) {
1898 return {static_cast<KeyMgmtMask>(0),
1899 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
1900 }
1901
1902 return {convertWpaKeyMgmtCapabilitiesToAidl(wpa_s, &capa),
1903 ndk::ScopedAStatus::ok()};
1904 }
1905
setQosPolicyFeatureEnabledInternal(bool enable)1906 ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabledInternal(bool enable)
1907 {
1908 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1909 wpa_s->enable_dscp_policy_capa = enable ? 1 : 0;
1910 return ndk::ScopedAStatus::ok();
1911 }
1912
sendQosPolicyResponseInternal(int32_t qos_policy_request_id,bool more_policies,const std::vector<QosPolicyStatus> & qos_policy_status_list)1913 ndk::ScopedAStatus StaIface::sendQosPolicyResponseInternal(
1914 int32_t qos_policy_request_id, bool more_policies,
1915 const std::vector<QosPolicyStatus>& qos_policy_status_list)
1916 {
1917 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1918 struct dscp_resp_data resp_data;
1919 int num_policies = qos_policy_status_list.size();
1920
1921 memset(&resp_data, 0, sizeof(resp_data));
1922
1923 resp_data.more = more_policies ? 1 : 0;
1924 resp_data.policy = (struct dscp_policy_status *) malloc(
1925 sizeof(struct dscp_policy_status) * num_policies);
1926 if (num_policies && !resp_data.policy){
1927 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1928 }
1929
1930 resp_data.solicited = true;
1931 wpa_s->dscp_req_dialog_token = qos_policy_request_id;
1932
1933 for (int i = 0; i < num_policies; i++) {
1934 resp_data.policy[i].id = qos_policy_status_list.at(i).policyId;
1935 resp_data.policy[i].status =
1936 static_cast<uint8_t>(qos_policy_status_list.at(i).status);
1937 }
1938 resp_data.num_policies = num_policies;
1939
1940 if (wpas_send_dscp_response(wpa_s, &resp_data)) {
1941 free(resp_data.policy);
1942 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1943 }
1944
1945 free(resp_data.policy);
1946 return ndk::ScopedAStatus::ok();
1947 }
1948
removeAllQosPoliciesInternal()1949 ndk::ScopedAStatus StaIface::removeAllQosPoliciesInternal()
1950 {
1951 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1952 struct dscp_resp_data resp_data;
1953
1954 memset(&resp_data, 0, sizeof(resp_data));
1955 resp_data.reset = true;
1956 resp_data.solicited = false;
1957 wpa_s->dscp_req_dialog_token = 0;
1958
1959 if (wpas_send_dscp_response(wpa_s, &resp_data)) {
1960 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1961 }
1962 return ndk::ScopedAStatus::ok();
1963 }
1964
getConnectionMloLinksInfoInternal()1965 std::pair<MloLinksInfo, ndk::ScopedAStatus> StaIface::getConnectionMloLinksInfoInternal()
1966 {
1967 MloLinksInfo linksInfo;
1968 return {linksInfo, ndk::ScopedAStatus::ok()};
1969 }
1970
1971 /**
1972 * Retrieve the underlying |wpa_supplicant| struct
1973 * pointer for this iface.
1974 * If the underlying iface is removed, then all RPC method calls on this object
1975 * will return failure.
1976 */
retrieveIfacePtr()1977 wpa_supplicant *StaIface::retrieveIfacePtr()
1978 {
1979 return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
1980 }
1981 } // namespace supplicant
1982 } // namespace wifi
1983 } // namespace hardware
1984 } // namespace android
1985 } // namespace aidl
1986