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