1 /* 2 * hidl interface for wpa_supplicant daemon 3 * Copyright (c) 2004-2016, Jouni Malinen <j (at) w1.fi> 4 * Copyright (c) 2004-2016, Roshan Pius <rpius (at) google.com> 5 * 6 * This software may be distributed under the terms of the BSD license. 7 * See README for more details. 8 */ 9 10 #include "hidl_manager.h" 11 #include "hidl_return_util.h" 12 #include "iface_config_utils.h" 13 #include "misc_utils.h" 14 #include "sta_iface.h" 15 16 extern "C" 17 { 18 #include "utils/eloop.h" 19 #include "gas_query.h" 20 #include "interworking.h" 21 #include "hs20_supplicant.h" 22 #include "wps_supplicant.h" 23 #include "dpp_supplicant.h" 24 #include "dpp.h" 25 } 26 27 namespace { 28 using android::hardware::wifi::supplicant::V1_0::SupplicantStatus; 29 using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; 30 using android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface; 31 using android::hardware::wifi::supplicant::V1_2::implementation::HidlManager; 32 33 constexpr uint32_t kMaxAnqpElems = 100; 34 constexpr char kGetMacAddress[] = "MACADDR"; 35 constexpr char kStartRxFilter[] = "RXFILTER-START"; 36 constexpr char kStopRxFilter[] = "RXFILTER-STOP"; 37 constexpr char kAddRxFilter[] = "RXFILTER-ADD"; 38 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE"; 39 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE"; 40 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START"; 41 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP"; 42 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1"; 43 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0"; 44 constexpr char kSetCountryCode[] = "COUNTRY"; 45 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec = static_cast<uint32_t>( 46 ISupplicantStaIface::ExtRadioWorkDefaults::TIMEOUT_IN_SECS); 47 constexpr char kExtRadioWorkNamePrefix[] = "ext:"; 48 49 uint8_t convertHidlRxFilterTypeToInternal( 50 ISupplicantStaIface::RxFilterType type) 51 { 52 switch (type) { 53 case ISupplicantStaIface::RxFilterType::V4_MULTICAST: 54 return 2; 55 case ISupplicantStaIface::RxFilterType::V6_MULTICAST: 56 return 3; 57 }; 58 WPA_ASSERT(false); 59 } 60 61 uint8_t convertHidlBtCoexModeToInternal( 62 ISupplicantStaIface::BtCoexistenceMode mode) 63 { 64 switch (mode) { 65 case ISupplicantStaIface::BtCoexistenceMode::ENABLED: 66 return 0; 67 case ISupplicantStaIface::BtCoexistenceMode::DISABLED: 68 return 1; 69 case ISupplicantStaIface::BtCoexistenceMode::SENSE: 70 return 2; 71 }; 72 WPA_ASSERT(false); 73 } 74 75 SupplicantStatus doZeroArgDriverCommand( 76 struct wpa_supplicant *wpa_s, const char *cmd) 77 { 78 std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1); 79 char driver_cmd_reply_buf[4096] = {}; 80 if (wpa_drv_driver_cmd( 81 wpa_s, cmd_vec.data(), driver_cmd_reply_buf, 82 sizeof(driver_cmd_reply_buf))) { 83 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 84 } 85 return {SupplicantStatusCode::SUCCESS, ""}; 86 } 87 88 SupplicantStatus doOneArgDriverCommand( 89 struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg) 90 { 91 std::string cmd_str = std::string(cmd) + " " + std::to_string(arg); 92 return doZeroArgDriverCommand(wpa_s, cmd_str.c_str()); 93 } 94 95 SupplicantStatus doOneArgDriverCommand( 96 struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg) 97 { 98 std::string cmd_str = std::string(cmd) + " " + arg; 99 return doZeroArgDriverCommand(wpa_s, cmd_str.c_str()); 100 } 101 102 void endExtRadioWork(struct wpa_radio_work *work) 103 { 104 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 105 work->wpa_s->ext_work_in_progress = 0; 106 radio_work_done(work); 107 os_free(ework); 108 } 109 110 void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx) 111 { 112 auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx); 113 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 114 wpa_dbg( 115 work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)", 116 ework->id, work->type); 117 118 HidlManager *hidl_manager = HidlManager::getInstance(); 119 WPA_ASSERT(hidl_manager); 120 hidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id); 121 122 endExtRadioWork(work); 123 } 124 125 void startExtRadioWork(struct wpa_radio_work *work) 126 { 127 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 128 work->wpa_s->ext_work_in_progress = 1; 129 if (!ework->timeout) { 130 ework->timeout = kExtRadioWorkDefaultTimeoutInSec; 131 } 132 eloop_register_timeout( 133 ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr); 134 } 135 136 void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit) 137 { 138 // deinit==1 is invoked during interface removal. Since the HIDL 139 // interface does not support interface addition/removal, we don't 140 // need to handle this scenario. 141 WPA_ASSERT(!deinit); 142 143 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 144 wpa_dbg( 145 work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)", 146 ework->id, ework->type); 147 148 HidlManager *hidl_manager = HidlManager::getInstance(); 149 WPA_ASSERT(hidl_manager); 150 hidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id); 151 152 startExtRadioWork(work); 153 } 154 155 } // namespace 156 157 namespace android { 158 namespace hardware { 159 namespace wifi { 160 namespace supplicant { 161 namespace V1_2 { 162 namespace implementation { 163 using hidl_return_util::validateAndCall; 164 165 using namespace android::hardware::wifi::supplicant::V1_0; 166 using namespace android::hardware::wifi::supplicant::V1_1; 167 using V1_0::ISupplicantStaIfaceCallback; 168 169 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[]) 170 : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true) 171 {} 172 173 void StaIface::invalidate() { is_valid_ = false; } 174 bool StaIface::isValid() 175 { 176 return (is_valid_ && (retrieveIfacePtr() != nullptr)); 177 } 178 179 Return<void> StaIface::getName(getName_cb _hidl_cb) 180 { 181 return validateAndCall( 182 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 183 &StaIface::getNameInternal, _hidl_cb); 184 } 185 186 Return<void> StaIface::getType(getType_cb _hidl_cb) 187 { 188 return validateAndCall( 189 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 190 &StaIface::getTypeInternal, _hidl_cb); 191 } 192 193 Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb) 194 { 195 return validateAndCall( 196 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 197 &StaIface::addNetworkInternal, _hidl_cb); 198 } 199 200 Return<void> StaIface::removeNetwork( 201 SupplicantNetworkId id, removeNetwork_cb _hidl_cb) 202 { 203 return validateAndCall( 204 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 205 &StaIface::removeNetworkInternal, _hidl_cb, id); 206 } 207 208 Return<void> StaIface::getNetwork( 209 SupplicantNetworkId id, getNetwork_cb _hidl_cb) 210 { 211 return validateAndCall( 212 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 213 &StaIface::getNetworkInternal, _hidl_cb, id); 214 } 215 216 Return<void> StaIface::listNetworks(listNetworks_cb _hidl_cb) 217 { 218 return validateAndCall( 219 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 220 &StaIface::listNetworksInternal, _hidl_cb); 221 } 222 223 Return<void> StaIface::registerCallback( 224 const sp<ISupplicantStaIfaceCallback> &callback, 225 registerCallback_cb _hidl_cb) 226 { 227 return validateAndCall( 228 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 229 &StaIface::registerCallbackInternal, _hidl_cb, callback); 230 } 231 232 Return<void> StaIface::registerCallback_1_1( 233 const sp<V1_1::ISupplicantStaIfaceCallback> &callback, 234 registerCallback_cb _hidl_cb) 235 { 236 sp<V1_0::ISupplicantStaIfaceCallback> callback_1_0 = callback; 237 return validateAndCall( 238 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 239 &StaIface::registerCallbackInternal, _hidl_cb, callback_1_0); 240 } 241 242 Return<void> StaIface::registerCallback_1_2( 243 const sp<V1_2::ISupplicantStaIfaceCallback> &callback, 244 registerCallback_cb _hidl_cb) 245 { 246 sp<V1_1::ISupplicantStaIfaceCallback> callback_1_1 = callback; 247 return validateAndCall( 248 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 249 &StaIface::registerCallbackInternal, _hidl_cb, callback_1_1); 250 } 251 252 Return<void> StaIface::reassociate(reassociate_cb _hidl_cb) 253 { 254 return validateAndCall( 255 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 256 &StaIface::reassociateInternal, _hidl_cb); 257 } 258 259 Return<void> StaIface::reconnect(reconnect_cb _hidl_cb) 260 { 261 return validateAndCall( 262 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 263 &StaIface::reconnectInternal, _hidl_cb); 264 } 265 266 Return<void> StaIface::disconnect(disconnect_cb _hidl_cb) 267 { 268 return validateAndCall( 269 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 270 &StaIface::disconnectInternal, _hidl_cb); 271 } 272 273 Return<void> StaIface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb) 274 { 275 return validateAndCall( 276 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 277 &StaIface::setPowerSaveInternal, _hidl_cb, enable); 278 } 279 280 Return<void> StaIface::initiateTdlsDiscover( 281 const hidl_array<uint8_t, 6> &mac_address, initiateTdlsDiscover_cb _hidl_cb) 282 { 283 return validateAndCall( 284 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 285 &StaIface::initiateTdlsDiscoverInternal, _hidl_cb, mac_address); 286 } 287 288 Return<void> StaIface::initiateTdlsSetup( 289 const hidl_array<uint8_t, 6> &mac_address, initiateTdlsSetup_cb _hidl_cb) 290 { 291 return validateAndCall( 292 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 293 &StaIface::initiateTdlsSetupInternal, _hidl_cb, mac_address); 294 } 295 296 Return<void> StaIface::initiateTdlsTeardown( 297 const hidl_array<uint8_t, 6> &mac_address, initiateTdlsTeardown_cb _hidl_cb) 298 { 299 return validateAndCall( 300 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 301 &StaIface::initiateTdlsTeardownInternal, _hidl_cb, mac_address); 302 } 303 Return<void> StaIface::initiateAnqpQuery( 304 const hidl_array<uint8_t, 6> &mac_address, 305 const hidl_vec<ISupplicantStaIface::AnqpInfoId> &info_elements, 306 const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types, 307 initiateAnqpQuery_cb _hidl_cb) 308 { 309 return validateAndCall( 310 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 311 &StaIface::initiateAnqpQueryInternal, _hidl_cb, mac_address, 312 info_elements, sub_types); 313 } 314 315 Return<void> StaIface::initiateHs20IconQuery( 316 const hidl_array<uint8_t, 6> &mac_address, const hidl_string &file_name, 317 initiateHs20IconQuery_cb _hidl_cb) 318 { 319 return validateAndCall( 320 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 321 &StaIface::initiateHs20IconQueryInternal, _hidl_cb, mac_address, 322 file_name); 323 } 324 325 Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb) 326 { 327 return validateAndCall( 328 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 329 &StaIface::getMacAddressInternal, _hidl_cb); 330 } 331 332 Return<void> StaIface::startRxFilter(startRxFilter_cb _hidl_cb) 333 { 334 return validateAndCall( 335 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 336 &StaIface::startRxFilterInternal, _hidl_cb); 337 } 338 339 Return<void> StaIface::stopRxFilter(stopRxFilter_cb _hidl_cb) 340 { 341 return validateAndCall( 342 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 343 &StaIface::stopRxFilterInternal, _hidl_cb); 344 } 345 346 Return<void> StaIface::addRxFilter( 347 ISupplicantStaIface::RxFilterType type, addRxFilter_cb _hidl_cb) 348 { 349 return validateAndCall( 350 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 351 &StaIface::addRxFilterInternal, _hidl_cb, type); 352 } 353 354 Return<void> StaIface::removeRxFilter( 355 ISupplicantStaIface::RxFilterType type, removeRxFilter_cb _hidl_cb) 356 { 357 return validateAndCall( 358 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 359 &StaIface::removeRxFilterInternal, _hidl_cb, type); 360 } 361 362 Return<void> StaIface::setBtCoexistenceMode( 363 ISupplicantStaIface::BtCoexistenceMode mode, 364 setBtCoexistenceMode_cb _hidl_cb) 365 { 366 return validateAndCall( 367 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 368 &StaIface::setBtCoexistenceModeInternal, _hidl_cb, mode); 369 } 370 371 Return<void> StaIface::setBtCoexistenceScanModeEnabled( 372 bool enable, setBtCoexistenceScanModeEnabled_cb _hidl_cb) 373 { 374 return validateAndCall( 375 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 376 &StaIface::setBtCoexistenceScanModeEnabledInternal, _hidl_cb, 377 enable); 378 } 379 380 Return<void> StaIface::setSuspendModeEnabled( 381 bool enable, setSuspendModeEnabled_cb _hidl_cb) 382 { 383 return validateAndCall( 384 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 385 &StaIface::setSuspendModeEnabledInternal, _hidl_cb, enable); 386 } 387 388 Return<void> StaIface::setCountryCode( 389 const hidl_array<int8_t, 2> &code, setCountryCode_cb _hidl_cb) 390 { 391 return validateAndCall( 392 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 393 &StaIface::setCountryCodeInternal, _hidl_cb, code); 394 } 395 396 Return<void> StaIface::startWpsRegistrar( 397 const hidl_array<uint8_t, 6> &bssid, const hidl_string &pin, 398 startWpsRegistrar_cb _hidl_cb) 399 { 400 return validateAndCall( 401 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 402 &StaIface::startWpsRegistrarInternal, _hidl_cb, bssid, pin); 403 } 404 405 Return<void> StaIface::startWpsPbc( 406 const hidl_array<uint8_t, 6> &bssid, startWpsPbc_cb _hidl_cb) 407 { 408 return validateAndCall( 409 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 410 &StaIface::startWpsPbcInternal, _hidl_cb, bssid); 411 } 412 413 Return<void> StaIface::startWpsPinKeypad( 414 const hidl_string &pin, startWpsPinKeypad_cb _hidl_cb) 415 { 416 return validateAndCall( 417 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 418 &StaIface::startWpsPinKeypadInternal, _hidl_cb, pin); 419 } 420 421 Return<void> StaIface::startWpsPinDisplay( 422 const hidl_array<uint8_t, 6> &bssid, startWpsPinDisplay_cb _hidl_cb) 423 { 424 return validateAndCall( 425 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 426 &StaIface::startWpsPinDisplayInternal, _hidl_cb, bssid); 427 } 428 429 Return<void> StaIface::cancelWps(cancelWps_cb _hidl_cb) 430 { 431 return validateAndCall( 432 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 433 &StaIface::cancelWpsInternal, _hidl_cb); 434 } 435 436 Return<void> StaIface::setWpsDeviceName( 437 const hidl_string &name, setWpsDeviceName_cb _hidl_cb) 438 { 439 return validateAndCall( 440 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 441 &StaIface::setWpsDeviceNameInternal, _hidl_cb, name); 442 } 443 444 Return<void> StaIface::setWpsDeviceType( 445 const hidl_array<uint8_t, 8> &type, setWpsDeviceType_cb _hidl_cb) 446 { 447 return validateAndCall( 448 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 449 &StaIface::setWpsDeviceTypeInternal, _hidl_cb, type); 450 } 451 452 Return<void> StaIface::setWpsManufacturer( 453 const hidl_string &manufacturer, setWpsManufacturer_cb _hidl_cb) 454 { 455 return validateAndCall( 456 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 457 &StaIface::setWpsManufacturerInternal, _hidl_cb, manufacturer); 458 } 459 460 Return<void> StaIface::setWpsModelName( 461 const hidl_string &model_name, setWpsModelName_cb _hidl_cb) 462 { 463 return validateAndCall( 464 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 465 &StaIface::setWpsModelNameInternal, _hidl_cb, model_name); 466 } 467 468 Return<void> StaIface::setWpsModelNumber( 469 const hidl_string &model_number, setWpsModelNumber_cb _hidl_cb) 470 { 471 return validateAndCall( 472 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 473 &StaIface::setWpsModelNumberInternal, _hidl_cb, model_number); 474 } 475 476 Return<void> StaIface::setWpsSerialNumber( 477 const hidl_string &serial_number, setWpsSerialNumber_cb _hidl_cb) 478 { 479 return validateAndCall( 480 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 481 &StaIface::setWpsSerialNumberInternal, _hidl_cb, serial_number); 482 } 483 484 Return<void> StaIface::setWpsConfigMethods( 485 uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb) 486 { 487 return validateAndCall( 488 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 489 &StaIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods); 490 } 491 492 Return<void> StaIface::setExternalSim( 493 bool useExternalSim, setExternalSim_cb _hidl_cb) 494 { 495 return validateAndCall( 496 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 497 &StaIface::setExternalSimInternal, _hidl_cb, useExternalSim); 498 } 499 500 Return<void> StaIface::addExtRadioWork( 501 const hidl_string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec, 502 addExtRadioWork_cb _hidl_cb) 503 { 504 return validateAndCall( 505 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 506 &StaIface::addExtRadioWorkInternal, _hidl_cb, name, freq_in_mhz, 507 timeout_in_sec); 508 } 509 510 Return<void> StaIface::removeExtRadioWork( 511 uint32_t id, removeExtRadioWork_cb _hidl_cb) 512 { 513 return validateAndCall( 514 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 515 &StaIface::removeExtRadioWorkInternal, _hidl_cb, id); 516 } 517 518 Return<void> StaIface::enableAutoReconnect( 519 bool enable, enableAutoReconnect_cb _hidl_cb) 520 { 521 return validateAndCall( 522 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 523 &StaIface::enableAutoReconnectInternal, _hidl_cb, enable); 524 } 525 526 Return<void> StaIface::getKeyMgmtCapabilities( 527 getKeyMgmtCapabilities_cb _hidl_cb) 528 { 529 return validateAndCall( 530 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID, 531 &StaIface::getKeyMgmtCapabilitiesInternal, _hidl_cb); 532 } 533 534 Return<void> StaIface::addDppPeerUri(const hidl_string& uri, 535 addDppPeerUri_cb _hidl_cb) 536 { 537 return validateAndCall( 538 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID, 539 &StaIface::addDppPeerUriInternal, _hidl_cb, uri); 540 } 541 542 Return<void> StaIface::removeDppUri(uint32_t bootstrap_id, 543 removeDppUri_cb _hidl_cb) 544 { 545 return validateAndCall( 546 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID, 547 &StaIface::removeDppUriInternal, _hidl_cb, bootstrap_id); 548 } 549 550 Return<void> StaIface::startDppConfiguratorInitiator(uint32_t peer_bootstrap_id, 551 uint32_t own_bootstrap_id, const hidl_string& ssid, 552 const hidl_string& password, const hidl_string& psk, 553 DppNetRole net_role, DppAkm security_akm, 554 startDppConfiguratorInitiator_cb _hidl_cb) 555 { 556 return validateAndCall( 557 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID, 558 &StaIface::startDppConfiguratorInitiatorInternal, _hidl_cb, peer_bootstrap_id, 559 own_bootstrap_id, ssid, password, psk, net_role, security_akm); 560 } 561 562 Return<void> StaIface::startDppEnrolleeInitiator(uint32_t peer_bootstrap_id, 563 uint32_t own_bootstrap_id, startDppConfiguratorInitiator_cb _hidl_cb) 564 { 565 return validateAndCall( 566 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID, 567 &StaIface::startDppEnrolleeInitiatorInternal, _hidl_cb, peer_bootstrap_id, 568 own_bootstrap_id); 569 } 570 571 Return<void> StaIface::stopDppInitiator(stopDppInitiator_cb _hidl_cb) 572 { 573 return validateAndCall( 574 this, SupplicantStatusCode::FAILURE_NETWORK_INVALID, 575 &StaIface::stopDppInitiatorInternal, _hidl_cb); 576 } 577 578 std::pair<SupplicantStatus, std::string> StaIface::getNameInternal() 579 { 580 return {{SupplicantStatusCode::SUCCESS, ""}, ifname_}; 581 } 582 583 std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal() 584 { 585 return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA}; 586 } 587 588 std::pair<SupplicantStatus, sp<ISupplicantNetwork>> 589 StaIface::addNetworkInternal() 590 { 591 android::sp<ISupplicantStaNetwork> network; 592 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 593 struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s); 594 if (!ssid) { 595 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network}; 596 } 597 HidlManager *hidl_manager = HidlManager::getInstance(); 598 if (!hidl_manager || 599 hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId( 600 wpa_s->ifname, ssid->id, &network)) { 601 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network}; 602 } 603 return {{SupplicantStatusCode::SUCCESS, ""}, network}; 604 } 605 606 SupplicantStatus StaIface::removeNetworkInternal(SupplicantNetworkId id) 607 { 608 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 609 int result = wpa_supplicant_remove_network(wpa_s, id); 610 if (result == -1) { 611 return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""}; 612 } 613 if (result != 0) { 614 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 615 } 616 return {SupplicantStatusCode::SUCCESS, ""}; 617 } 618 619 std::pair<SupplicantStatus, sp<ISupplicantNetwork>> 620 StaIface::getNetworkInternal(SupplicantNetworkId id) 621 { 622 android::sp<ISupplicantStaNetwork> network; 623 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 624 struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id); 625 if (!ssid) { 626 return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""}, 627 network}; 628 } 629 HidlManager *hidl_manager = HidlManager::getInstance(); 630 if (!hidl_manager || 631 hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId( 632 wpa_s->ifname, ssid->id, &network)) { 633 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network}; 634 } 635 return {{SupplicantStatusCode::SUCCESS, ""}, network}; 636 } 637 638 std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>> 639 StaIface::listNetworksInternal() 640 { 641 std::vector<SupplicantNetworkId> network_ids; 642 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 643 for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid; 644 wpa_ssid = wpa_ssid->next) { 645 network_ids.emplace_back(wpa_ssid->id); 646 } 647 return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)}; 648 } 649 650 SupplicantStatus StaIface::registerCallbackInternal( 651 const sp<ISupplicantStaIfaceCallback> &callback) 652 { 653 HidlManager *hidl_manager = HidlManager::getInstance(); 654 if (!hidl_manager || 655 hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) { 656 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 657 } 658 return {SupplicantStatusCode::SUCCESS, ""}; 659 } 660 661 SupplicantStatus StaIface::reassociateInternal() 662 { 663 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 664 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 665 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 666 } 667 wpas_request_connection(wpa_s); 668 return {SupplicantStatusCode::SUCCESS, ""}; 669 } 670 671 SupplicantStatus StaIface::reconnectInternal() 672 { 673 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 674 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 675 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 676 } 677 if (!wpa_s->disconnected) { 678 return {SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED, 679 ""}; 680 } 681 wpas_request_connection(wpa_s); 682 return {SupplicantStatusCode::SUCCESS, ""}; 683 } 684 685 SupplicantStatus StaIface::disconnectInternal() 686 { 687 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 688 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 689 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 690 } 691 wpas_request_disconnection(wpa_s); 692 return {SupplicantStatusCode::SUCCESS, ""}; 693 } 694 695 SupplicantStatus StaIface::setPowerSaveInternal(bool enable) 696 { 697 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 698 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 699 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 700 } 701 if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) { 702 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 703 } 704 return {SupplicantStatusCode::SUCCESS, ""}; 705 } 706 707 SupplicantStatus StaIface::initiateTdlsDiscoverInternal( 708 const std::array<uint8_t, 6> &mac_address) 709 { 710 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 711 int ret; 712 const u8 *peer = mac_address.data(); 713 if (wpa_tdls_is_external_setup(wpa_s->wpa)) { 714 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer); 715 } else { 716 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer); 717 } 718 if (ret) { 719 wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret); 720 } 721 return {SupplicantStatusCode::SUCCESS, ""}; 722 } 723 724 SupplicantStatus StaIface::initiateTdlsSetupInternal( 725 const std::array<uint8_t, 6> &mac_address) 726 { 727 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 728 int ret; 729 const u8 *peer = mac_address.data(); 730 if (wpa_tdls_is_external_setup(wpa_s->wpa) && 731 !(wpa_s->conf->tdls_external_control)) { 732 wpa_tdls_remove(wpa_s->wpa, peer); 733 ret = wpa_tdls_start(wpa_s->wpa, peer); 734 } else { 735 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 736 } 737 if (ret) { 738 wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret); 739 } 740 return {SupplicantStatusCode::SUCCESS, ""}; 741 } 742 743 SupplicantStatus StaIface::initiateTdlsTeardownInternal( 744 const std::array<uint8_t, 6> &mac_address) 745 { 746 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 747 int ret; 748 const u8 *peer = mac_address.data(); 749 if (wpa_tdls_is_external_setup(wpa_s->wpa) && 750 !(wpa_s->conf->tdls_external_control)) { 751 ret = wpa_tdls_teardown_link( 752 wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED); 753 } else { 754 ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer); 755 } 756 if (ret) { 757 wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret); 758 } 759 return {SupplicantStatusCode::SUCCESS, ""}; 760 } 761 762 SupplicantStatus StaIface::initiateAnqpQueryInternal( 763 const std::array<uint8_t, 6> &mac_address, 764 const std::vector<ISupplicantStaIface::AnqpInfoId> &info_elements, 765 const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types) 766 { 767 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 768 if (info_elements.size() > kMaxAnqpElems) { 769 return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}; 770 } 771 uint16_t info_elems_buf[kMaxAnqpElems]; 772 uint32_t num_info_elems = 0; 773 for (const auto &info_element : info_elements) { 774 info_elems_buf[num_info_elems++] = 775 static_cast<std::underlying_type< 776 ISupplicantStaIface::AnqpInfoId>::type>(info_element); 777 } 778 uint32_t sub_types_bitmask = 0; 779 for (const auto &type : sub_types) { 780 sub_types_bitmask |= BIT( 781 static_cast<std::underlying_type< 782 ISupplicantStaIface::Hs20AnqpSubtypes>::type>(type)); 783 } 784 if (anqp_send_req( 785 wpa_s, mac_address.data(), info_elems_buf, num_info_elems, 786 sub_types_bitmask, false)) { 787 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 788 } 789 return {SupplicantStatusCode::SUCCESS, ""}; 790 } 791 792 SupplicantStatus StaIface::initiateHs20IconQueryInternal( 793 const std::array<uint8_t, 6> &mac_address, const std::string &file_name) 794 { 795 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 796 wpa_s->fetch_osu_icon_in_progress = 0; 797 if (hs20_anqp_send_req( 798 wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST), 799 reinterpret_cast<const uint8_t *>(file_name.c_str()), 800 file_name.size(), true)) { 801 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 802 } 803 return {SupplicantStatusCode::SUCCESS, ""}; 804 } 805 806 std::pair<SupplicantStatus, std::array<uint8_t, 6>> 807 StaIface::getMacAddressInternal() 808 { 809 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 810 std::vector<char> cmd( 811 kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress)); 812 char driver_cmd_reply_buf[4096] = {}; 813 int ret = wpa_drv_driver_cmd( 814 wpa_s, cmd.data(), driver_cmd_reply_buf, 815 sizeof(driver_cmd_reply_buf)); 816 // Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX" 817 std::string reply_str = driver_cmd_reply_buf; 818 if (ret < 0 || reply_str.empty() || 819 reply_str.find("=") == std::string::npos) { 820 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}}; 821 } 822 // Remove all whitespace first and then split using the delimiter "=". 823 reply_str.erase( 824 remove_if(reply_str.begin(), reply_str.end(), isspace), 825 reply_str.end()); 826 std::string mac_addr_str = 827 reply_str.substr(reply_str.find("=") + 1, reply_str.size()); 828 std::array<uint8_t, 6> mac_addr; 829 if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) { 830 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}}; 831 } 832 return {{SupplicantStatusCode::SUCCESS, ""}, mac_addr}; 833 } 834 835 SupplicantStatus StaIface::startRxFilterInternal() 836 { 837 return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter); 838 } 839 840 SupplicantStatus StaIface::stopRxFilterInternal() 841 { 842 return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter); 843 } 844 845 SupplicantStatus StaIface::addRxFilterInternal( 846 ISupplicantStaIface::RxFilterType type) 847 { 848 return doOneArgDriverCommand( 849 retrieveIfacePtr(), kAddRxFilter, 850 convertHidlRxFilterTypeToInternal(type)); 851 } 852 853 SupplicantStatus StaIface::removeRxFilterInternal( 854 ISupplicantStaIface::RxFilterType type) 855 { 856 return doOneArgDriverCommand( 857 retrieveIfacePtr(), kRemoveRxFilter, 858 convertHidlRxFilterTypeToInternal(type)); 859 } 860 861 SupplicantStatus StaIface::setBtCoexistenceModeInternal( 862 ISupplicantStaIface::BtCoexistenceMode mode) 863 { 864 return doOneArgDriverCommand( 865 retrieveIfacePtr(), kSetBtCoexistenceMode, 866 convertHidlBtCoexModeToInternal(mode)); 867 } 868 869 SupplicantStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable) 870 { 871 const char *cmd; 872 if (enable) { 873 cmd = kSetBtCoexistenceScanStart; 874 } else { 875 cmd = kSetBtCoexistenceScanStop; 876 } 877 return doZeroArgDriverCommand(retrieveIfacePtr(), cmd); 878 } 879 880 SupplicantStatus StaIface::setSuspendModeEnabledInternal(bool enable) 881 { 882 const char *cmd; 883 if (enable) { 884 cmd = kSetSupendModeEnabled; 885 } else { 886 cmd = kSetSupendModeDisabled; 887 } 888 return doZeroArgDriverCommand(retrieveIfacePtr(), cmd); 889 } 890 891 SupplicantStatus StaIface::setCountryCodeInternal( 892 const std::array<int8_t, 2> &code) 893 { 894 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 895 SupplicantStatus status = doOneArgDriverCommand( 896 wpa_s, kSetCountryCode, 897 std::string(std::begin(code), std::end(code))); 898 if (status.code != SupplicantStatusCode::SUCCESS) { 899 return status; 900 } 901 struct p2p_data *p2p = wpa_s->global->p2p; 902 if (p2p) { 903 char country[3]; 904 country[0] = code[0]; 905 country[1] = code[1]; 906 country[2] = 0x04; 907 p2p_set_country(p2p, country); 908 } 909 return {SupplicantStatusCode::SUCCESS, ""}; 910 } 911 912 SupplicantStatus StaIface::startWpsRegistrarInternal( 913 const std::array<uint8_t, 6> &bssid, const std::string &pin) 914 { 915 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 916 if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) { 917 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 918 } 919 return {SupplicantStatusCode::SUCCESS, ""}; 920 } 921 922 SupplicantStatus StaIface::startWpsPbcInternal( 923 const std::array<uint8_t, 6> &bssid) 924 { 925 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 926 const uint8_t *bssid_addr = 927 is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data(); 928 if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) { 929 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 930 } 931 return {SupplicantStatusCode::SUCCESS, ""}; 932 } 933 934 SupplicantStatus StaIface::startWpsPinKeypadInternal(const std::string &pin) 935 { 936 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 937 if (wpas_wps_start_pin( 938 wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) { 939 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 940 } 941 return {SupplicantStatusCode::SUCCESS, ""}; 942 } 943 944 std::pair<SupplicantStatus, std::string> StaIface::startWpsPinDisplayInternal( 945 const std::array<uint8_t, 6> &bssid) 946 { 947 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 948 const uint8_t *bssid_addr = 949 is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data(); 950 int pin = 951 wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT); 952 if (pin < 0) { 953 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""}; 954 } 955 return {{SupplicantStatusCode::SUCCESS, ""}, 956 misc_utils::convertWpsPinToString(pin)}; 957 } 958 959 SupplicantStatus StaIface::cancelWpsInternal() 960 { 961 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 962 if (wpas_wps_cancel(wpa_s)) { 963 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 964 } 965 return {SupplicantStatusCode::SUCCESS, ""}; 966 } 967 968 SupplicantStatus StaIface::setWpsDeviceNameInternal(const std::string &name) 969 { 970 return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name); 971 } 972 973 SupplicantStatus StaIface::setWpsDeviceTypeInternal( 974 const std::array<uint8_t, 8> &type) 975 { 976 return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type); 977 } 978 979 SupplicantStatus StaIface::setWpsManufacturerInternal( 980 const std::string &manufacturer) 981 { 982 return iface_config_utils::setWpsManufacturer( 983 retrieveIfacePtr(), manufacturer); 984 } 985 986 SupplicantStatus StaIface::setWpsModelNameInternal( 987 const std::string &model_name) 988 { 989 return iface_config_utils::setWpsModelName( 990 retrieveIfacePtr(), model_name); 991 } 992 993 SupplicantStatus StaIface::setWpsModelNumberInternal( 994 const std::string &model_number) 995 { 996 return iface_config_utils::setWpsModelNumber( 997 retrieveIfacePtr(), model_number); 998 } 999 1000 SupplicantStatus StaIface::setWpsSerialNumberInternal( 1001 const std::string &serial_number) 1002 { 1003 return iface_config_utils::setWpsSerialNumber( 1004 retrieveIfacePtr(), serial_number); 1005 } 1006 1007 SupplicantStatus StaIface::setWpsConfigMethodsInternal(uint16_t config_methods) 1008 { 1009 return iface_config_utils::setWpsConfigMethods( 1010 retrieveIfacePtr(), config_methods); 1011 } 1012 1013 SupplicantStatus StaIface::setExternalSimInternal(bool useExternalSim) 1014 { 1015 return iface_config_utils::setExternalSim( 1016 retrieveIfacePtr(), useExternalSim); 1017 } 1018 1019 std::pair<SupplicantStatus, uint32_t> StaIface::addExtRadioWorkInternal( 1020 const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec) 1021 { 1022 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1023 auto *ework = static_cast<struct wpa_external_work *>( 1024 os_zalloc(sizeof(struct wpa_external_work))); 1025 if (!ework) { 1026 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, 1027 UINT32_MAX}; 1028 } 1029 1030 std::string radio_work_name = kExtRadioWorkNamePrefix + name; 1031 os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type)); 1032 ework->timeout = timeout_in_sec; 1033 wpa_s->ext_work_id++; 1034 if (wpa_s->ext_work_id == 0) { 1035 wpa_s->ext_work_id++; 1036 } 1037 ework->id = wpa_s->ext_work_id; 1038 1039 if (radio_add_work( 1040 wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb, 1041 ework)) { 1042 os_free(ework); 1043 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, 1044 UINT32_MAX}; 1045 } 1046 return {SupplicantStatus{SupplicantStatusCode::SUCCESS, ""}, ework->id}; 1047 } 1048 1049 SupplicantStatus StaIface::removeExtRadioWorkInternal(uint32_t id) 1050 { 1051 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1052 struct wpa_radio_work *work; 1053 dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list) 1054 { 1055 if (os_strncmp( 1056 work->type, kExtRadioWorkNamePrefix, 1057 sizeof(kExtRadioWorkNamePrefix)) != 0) 1058 continue; 1059 1060 auto *ework = 1061 static_cast<struct wpa_external_work *>(work->ctx); 1062 if (ework->id != id) 1063 continue; 1064 1065 wpa_dbg( 1066 wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)", 1067 ework->id, ework->type); 1068 eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL); 1069 endExtRadioWork(work); 1070 1071 return {SupplicantStatusCode::SUCCESS, ""}; 1072 } 1073 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1074 } 1075 1076 SupplicantStatus StaIface::enableAutoReconnectInternal(bool enable) 1077 { 1078 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1079 wpa_s->auto_reconnect_disabled = enable ? 0 : 1; 1080 return {SupplicantStatusCode::SUCCESS, ""}; 1081 } 1082 1083 std::pair<SupplicantStatus, uint32_t> 1084 StaIface::getKeyMgmtCapabilitiesInternal() 1085 { 1086 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1087 struct wpa_driver_capa capa; 1088 uint32_t mask = 0; 1089 1090 /* Get capabilities from driver and populate the key management mask */ 1091 if (wpa_drv_get_capa(wpa_s, &capa) < 0) { 1092 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, mask}; 1093 } 1094 1095 /* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability 1096 * flags and always enabled. 1097 */ 1098 mask |= 1099 (ISupplicantStaNetwork::KeyMgmtMask::NONE | 1100 ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X); 1101 1102 if (capa.key_mgmt & 1103 (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 1104 mask |= ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP; 1105 } 1106 1107 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 1108 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 1109 mask |= ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK; 1110 } 1111 #ifdef CONFIG_SUITEB192 1112 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) { 1113 mask |= ISupplicantStaNetwork::KeyMgmtMask::SUITE_B_192; 1114 } 1115 #endif /* CONFIG_SUITEB192 */ 1116 #ifdef CONFIG_OWE 1117 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) { 1118 mask |= ISupplicantStaNetwork::KeyMgmtMask::OWE; 1119 } 1120 #endif /* CONFIG_OWE */ 1121 #ifdef CONFIG_SAE 1122 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) { 1123 mask |= ISupplicantStaNetwork::KeyMgmtMask::SAE; 1124 } 1125 #endif /* CONFIG_SAE */ 1126 #ifdef CONFIG_DPP 1127 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) { 1128 mask |= ISupplicantStaNetwork::KeyMgmtMask::DPP; 1129 } 1130 #endif 1131 return {{SupplicantStatusCode::SUCCESS, ""}, mask}; 1132 } 1133 1134 std::pair<SupplicantStatus, uint32_t> 1135 StaIface::addDppPeerUriInternal(const std::string& uri) 1136 { 1137 #ifdef CONFIG_DPP 1138 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1139 int32_t id; 1140 1141 id = wpas_dpp_qr_code(wpa_s, uri.c_str()); 1142 1143 if (id > 0) { 1144 return {{SupplicantStatusCode::SUCCESS, ""}, id}; 1145 } 1146 #endif 1147 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, -1}; 1148 } 1149 1150 SupplicantStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id) 1151 { 1152 #ifdef CONFIG_DPP 1153 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1154 std::string bootstrap_id_str; 1155 1156 if (bootstrap_id == 0) { 1157 bootstrap_id_str = "*"; 1158 } 1159 else { 1160 bootstrap_id_str = std::to_string(bootstrap_id); 1161 } 1162 1163 if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) { 1164 return {SupplicantStatusCode::SUCCESS, ""}; 1165 } 1166 #endif 1167 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1168 } 1169 1170 SupplicantStatus StaIface::startDppConfiguratorInitiatorInternal( 1171 uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id, 1172 const std::string& ssid, const std::string& password, 1173 const std::string& psk, DppNetRole net_role, DppAkm security_akm) 1174 { 1175 #ifdef CONFIG_DPP 1176 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1177 std::string cmd = ""; 1178 1179 if (net_role != DppNetRole::AP && 1180 net_role != DppNetRole::STA) { 1181 wpa_printf(MSG_ERROR, 1182 "DPP: Error: Invalid network role specified: %d", net_role); 1183 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1184 } 1185 1186 cmd += " peer=" + std::to_string(peer_bootstrap_id); 1187 cmd += (own_bootstrap_id > 0) ? 1188 " own=" + std::to_string(own_bootstrap_id) : ""; 1189 1190 /* Check for supported AKMs */ 1191 if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE && 1192 security_akm != DppAkm::PSK_SAE) { 1193 wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d", 1194 security_akm); 1195 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1196 } 1197 1198 /* SAE AKM requires SSID and password to be initialized */ 1199 if ((security_akm == DppAkm::SAE || 1200 security_akm == DppAkm::PSK_SAE) && 1201 (ssid.empty() || password.empty())) { 1202 wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified"); 1203 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1204 } else if (security_akm == DppAkm::PSK || 1205 security_akm == DppAkm::PSK_SAE) { 1206 /* PSK AKM requires SSID and password/psk to be initialized */ 1207 if (ssid.empty()) { 1208 wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified"); 1209 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1210 } 1211 if (password.empty() && psk.empty()) { 1212 wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified"); 1213 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1214 } 1215 } 1216 1217 cmd += " role=configurator"; 1218 cmd += (ssid.empty()) ? "" : " ssid=" + ssid; 1219 1220 if (!psk.empty()) { 1221 cmd += " psk=" + psk; 1222 } else { 1223 cmd += (password.empty()) ? "" : " pass=" + password; 1224 } 1225 1226 std::string role = ""; 1227 if (net_role == DppNetRole::AP) { 1228 role = "ap-"; 1229 } 1230 else { 1231 role = "sta-"; 1232 } 1233 1234 switch (security_akm) { 1235 case DppAkm::PSK: 1236 role += "psk"; 1237 break; 1238 1239 case DppAkm::SAE: 1240 role += "sae"; 1241 break; 1242 1243 case DppAkm::PSK_SAE: 1244 role += "psk-sae"; 1245 break; 1246 1247 default: 1248 wpa_printf(MSG_ERROR, 1249 "DPP: Invalid or unsupported security AKM specified: %d", security_akm); 1250 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1251 } 1252 1253 cmd += " conf="; 1254 cmd += role; 1255 1256 wpa_printf(MSG_DEBUG, 1257 "DPP initiator command: %s", cmd.c_str()); 1258 1259 if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) { 1260 return {SupplicantStatusCode::SUCCESS, ""}; 1261 } 1262 #endif 1263 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1264 } 1265 1266 SupplicantStatus StaIface::startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id, 1267 uint32_t own_bootstrap_id) { 1268 #ifdef CONFIG_DPP 1269 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1270 std::string cmd = ""; 1271 1272 /* Report received configuration to HIDL and create an internal profile */ 1273 wpa_s->conf->dpp_config_processing = 1; 1274 1275 cmd += " peer=" + std::to_string(peer_bootstrap_id); 1276 cmd += (own_bootstrap_id > 0) ? 1277 " own=" + std::to_string(own_bootstrap_id) : ""; 1278 1279 cmd += " role=enrollee"; 1280 1281 wpa_printf(MSG_DEBUG, 1282 "DPP initiator command: %s", cmd.c_str()); 1283 1284 if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) { 1285 return {SupplicantStatusCode::SUCCESS, ""}; 1286 } 1287 #endif 1288 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1289 } 1290 SupplicantStatus StaIface::stopDppInitiatorInternal() 1291 { 1292 #ifdef CONFIG_DPP 1293 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1294 1295 wpas_dpp_stop(wpa_s); 1296 return {SupplicantStatusCode::SUCCESS, ""}; 1297 #else 1298 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 1299 #endif 1300 } 1301 1302 /** 1303 * Retrieve the underlying |wpa_supplicant| struct 1304 * pointer for this iface. 1305 * If the underlying iface is removed, then all RPC method calls on this object 1306 * will return failure. 1307 */ 1308 wpa_supplicant *StaIface::retrieveIfacePtr() 1309 { 1310 return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str()); 1311 } 1312 } // namespace implementation 1313 } // namespace V1_2 1314 } // namespace supplicant 1315 } // namespace wifi 1316 } // namespace hardware 1317 } // namespace android 1318