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