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