1/* 2 * hidl interface for wpa_supplicant daemon 3 * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> 4 * Copyright (c) 2004-2016, Roshan Pius <rpius@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 16extern "C" { 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} 23 24namespace { 25using android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface; 26using android::hardware::wifi::supplicant::V1_0::SupplicantStatus; 27using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; 28using android::hardware::wifi::supplicant::V1_0::implementation::HidlManager; 29 30constexpr uint32_t kMaxAnqpElems = 100; 31constexpr char kGetMacAddress[] = "MACADDR"; 32constexpr char kStartRxFilter[] = "RXFILTER-START"; 33constexpr char kStopRxFilter[] = "RXFILTER-STOP"; 34constexpr char kAddRxFilter[] = "RXFILTER-ADD"; 35constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE"; 36constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE"; 37constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START"; 38constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP"; 39constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1"; 40constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0"; 41constexpr char kSetCountryCode[] = "COUNTRY"; 42constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec = static_cast<uint32_t>( 43 ISupplicantStaIface::ExtRadioWorkDefaults::TIMEOUT_IN_SECS); 44constexpr char kExtRadioWorkNamePrefix[] = "ext:"; 45 46uint8_t convertHidlRxFilterTypeToInternal( 47 ISupplicantStaIface::RxFilterType type) 48{ 49 switch (type) { 50 case ISupplicantStaIface::RxFilterType::V4_MULTICAST: 51 return 2; 52 case ISupplicantStaIface::RxFilterType::V6_MULTICAST: 53 return 3; 54 }; 55 WPA_ASSERT(false); 56} 57 58uint8_t convertHidlBtCoexModeToInternal( 59 ISupplicantStaIface::BtCoexistenceMode mode) 60{ 61 switch (mode) { 62 case ISupplicantStaIface::BtCoexistenceMode::ENABLED: 63 return 0; 64 case ISupplicantStaIface::BtCoexistenceMode::DISABLED: 65 return 1; 66 case ISupplicantStaIface::BtCoexistenceMode::SENSE: 67 return 2; 68 }; 69 WPA_ASSERT(false); 70} 71 72SupplicantStatus doZeroArgDriverCommand( 73 struct wpa_supplicant *wpa_s, const char *cmd) 74{ 75 std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1); 76 char driver_cmd_reply_buf[4096] = {}; 77 if (wpa_drv_driver_cmd( 78 wpa_s, cmd_vec.data(), driver_cmd_reply_buf, 79 sizeof(driver_cmd_reply_buf))) { 80 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 81 } 82 return {SupplicantStatusCode::SUCCESS, ""}; 83} 84 85SupplicantStatus doOneArgDriverCommand( 86 struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg) 87{ 88 std::string cmd_str = std::string(cmd) + " " + std::to_string(arg); 89 return doZeroArgDriverCommand(wpa_s, cmd_str.c_str()); 90} 91 92SupplicantStatus doOneArgDriverCommand( 93 struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg) 94{ 95 std::string cmd_str = std::string(cmd) + " " + arg; 96 return doZeroArgDriverCommand(wpa_s, cmd_str.c_str()); 97} 98 99void endExtRadioWork(struct wpa_radio_work *work) 100{ 101 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 102 work->wpa_s->ext_work_in_progress = 0; 103 radio_work_done(work); 104 os_free(ework); 105} 106 107void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx) 108{ 109 auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx); 110 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 111 wpa_dbg( 112 work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)", 113 ework->id, work->type); 114 115 HidlManager *hidl_manager = HidlManager::getInstance(); 116 WPA_ASSERT(hidl_manager); 117 hidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id); 118 119 endExtRadioWork(work); 120} 121 122void startExtRadioWork(struct wpa_radio_work *work) 123{ 124 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 125 work->wpa_s->ext_work_in_progress = 1; 126 if (!ework->timeout) { 127 ework->timeout = kExtRadioWorkDefaultTimeoutInSec; 128 } 129 eloop_register_timeout( 130 ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr); 131} 132 133void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit) 134{ 135 // deinit==1 is invoked during interface removal. Since the HIDL 136 // interface does not support interface addition/removal, we don't 137 // need to handle this scenario. 138 WPA_ASSERT(!deinit); 139 140 auto *ework = static_cast<struct wpa_external_work *>(work->ctx); 141 wpa_dbg( 142 work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)", 143 ework->id, ework->type); 144 145 HidlManager *hidl_manager = HidlManager::getInstance(); 146 WPA_ASSERT(hidl_manager); 147 hidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id); 148 149 startExtRadioWork(work); 150} 151 152} // namespace 153 154namespace android { 155namespace hardware { 156namespace wifi { 157namespace supplicant { 158namespace V1_0 { 159namespace implementation { 160using hidl_return_util::validateAndCall; 161 162StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[]) 163 : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true) 164{ 165} 166 167void StaIface::invalidate() { is_valid_ = false; } 168bool StaIface::isValid() 169{ 170 return (is_valid_ && (retrieveIfacePtr() != nullptr)); 171} 172 173Return<void> StaIface::getName(getName_cb _hidl_cb) 174{ 175 return validateAndCall( 176 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 177 &StaIface::getNameInternal, _hidl_cb); 178} 179 180Return<void> StaIface::getType(getType_cb _hidl_cb) 181{ 182 return validateAndCall( 183 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 184 &StaIface::getTypeInternal, _hidl_cb); 185} 186 187Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb) 188{ 189 return validateAndCall( 190 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 191 &StaIface::addNetworkInternal, _hidl_cb); 192} 193 194Return<void> StaIface::removeNetwork( 195 SupplicantNetworkId id, removeNetwork_cb _hidl_cb) 196{ 197 return validateAndCall( 198 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 199 &StaIface::removeNetworkInternal, _hidl_cb, id); 200} 201 202Return<void> StaIface::getNetwork( 203 SupplicantNetworkId id, getNetwork_cb _hidl_cb) 204{ 205 return validateAndCall( 206 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 207 &StaIface::getNetworkInternal, _hidl_cb, id); 208} 209 210Return<void> StaIface::listNetworks(listNetworks_cb _hidl_cb) 211{ 212 return validateAndCall( 213 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 214 &StaIface::listNetworksInternal, _hidl_cb); 215} 216 217Return<void> StaIface::registerCallback( 218 const sp<ISupplicantStaIfaceCallback> &callback, 219 registerCallback_cb _hidl_cb) 220{ 221 return validateAndCall( 222 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 223 &StaIface::registerCallbackInternal, _hidl_cb, callback); 224} 225 226Return<void> StaIface::reassociate(reassociate_cb _hidl_cb) 227{ 228 return validateAndCall( 229 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 230 &StaIface::reassociateInternal, _hidl_cb); 231} 232 233Return<void> StaIface::reconnect(reconnect_cb _hidl_cb) 234{ 235 return validateAndCall( 236 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 237 &StaIface::reconnectInternal, _hidl_cb); 238} 239 240Return<void> StaIface::disconnect(disconnect_cb _hidl_cb) 241{ 242 return validateAndCall( 243 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 244 &StaIface::disconnectInternal, _hidl_cb); 245} 246 247Return<void> StaIface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb) 248{ 249 return validateAndCall( 250 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 251 &StaIface::setPowerSaveInternal, _hidl_cb, enable); 252} 253 254Return<void> StaIface::initiateTdlsDiscover( 255 const hidl_array<uint8_t, 6> &mac_address, initiateTdlsDiscover_cb _hidl_cb) 256{ 257 return validateAndCall( 258 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 259 &StaIface::initiateTdlsDiscoverInternal, _hidl_cb, mac_address); 260} 261 262Return<void> StaIface::initiateTdlsSetup( 263 const hidl_array<uint8_t, 6> &mac_address, initiateTdlsSetup_cb _hidl_cb) 264{ 265 return validateAndCall( 266 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 267 &StaIface::initiateTdlsSetupInternal, _hidl_cb, mac_address); 268} 269 270Return<void> StaIface::initiateTdlsTeardown( 271 const hidl_array<uint8_t, 6> &mac_address, initiateTdlsTeardown_cb _hidl_cb) 272{ 273 return validateAndCall( 274 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 275 &StaIface::initiateTdlsTeardownInternal, _hidl_cb, mac_address); 276} 277Return<void> StaIface::initiateAnqpQuery( 278 const hidl_array<uint8_t, 6> &mac_address, 279 const hidl_vec<ISupplicantStaIface::AnqpInfoId> &info_elements, 280 const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types, 281 initiateAnqpQuery_cb _hidl_cb) 282{ 283 return validateAndCall( 284 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 285 &StaIface::initiateAnqpQueryInternal, _hidl_cb, mac_address, 286 info_elements, sub_types); 287} 288 289Return<void> StaIface::initiateHs20IconQuery( 290 const hidl_array<uint8_t, 6> &mac_address, const hidl_string &file_name, 291 initiateHs20IconQuery_cb _hidl_cb) 292{ 293 return validateAndCall( 294 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 295 &StaIface::initiateHs20IconQueryInternal, _hidl_cb, mac_address, 296 file_name); 297} 298 299Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb) 300{ 301 return validateAndCall( 302 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 303 &StaIface::getMacAddressInternal, _hidl_cb); 304} 305 306Return<void> StaIface::startRxFilter(startRxFilter_cb _hidl_cb) 307{ 308 return validateAndCall( 309 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 310 &StaIface::startRxFilterInternal, _hidl_cb); 311} 312 313Return<void> StaIface::stopRxFilter(stopRxFilter_cb _hidl_cb) 314{ 315 return validateAndCall( 316 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 317 &StaIface::stopRxFilterInternal, _hidl_cb); 318} 319 320Return<void> StaIface::addRxFilter( 321 ISupplicantStaIface::RxFilterType type, addRxFilter_cb _hidl_cb) 322{ 323 return validateAndCall( 324 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 325 &StaIface::addRxFilterInternal, _hidl_cb, type); 326} 327 328Return<void> StaIface::removeRxFilter( 329 ISupplicantStaIface::RxFilterType type, removeRxFilter_cb _hidl_cb) 330{ 331 return validateAndCall( 332 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 333 &StaIface::removeRxFilterInternal, _hidl_cb, type); 334} 335 336Return<void> StaIface::setBtCoexistenceMode( 337 ISupplicantStaIface::BtCoexistenceMode mode, 338 setBtCoexistenceMode_cb _hidl_cb) 339{ 340 return validateAndCall( 341 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 342 &StaIface::setBtCoexistenceModeInternal, _hidl_cb, mode); 343} 344 345Return<void> StaIface::setBtCoexistenceScanModeEnabled( 346 bool enable, setBtCoexistenceScanModeEnabled_cb _hidl_cb) 347{ 348 return validateAndCall( 349 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 350 &StaIface::setBtCoexistenceScanModeEnabledInternal, _hidl_cb, 351 enable); 352} 353 354Return<void> StaIface::setSuspendModeEnabled( 355 bool enable, setSuspendModeEnabled_cb _hidl_cb) 356{ 357 return validateAndCall( 358 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 359 &StaIface::setSuspendModeEnabledInternal, _hidl_cb, enable); 360} 361 362Return<void> StaIface::setCountryCode( 363 const hidl_array<int8_t, 2> &code, setCountryCode_cb _hidl_cb) 364{ 365 return validateAndCall( 366 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 367 &StaIface::setCountryCodeInternal, _hidl_cb, code); 368} 369 370Return<void> StaIface::startWpsRegistrar( 371 const hidl_array<uint8_t, 6> &bssid, const hidl_string &pin, 372 startWpsRegistrar_cb _hidl_cb) 373{ 374 return validateAndCall( 375 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 376 &StaIface::startWpsRegistrarInternal, _hidl_cb, bssid, pin); 377} 378 379Return<void> StaIface::startWpsPbc( 380 const hidl_array<uint8_t, 6> &bssid, startWpsPbc_cb _hidl_cb) 381{ 382 return validateAndCall( 383 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 384 &StaIface::startWpsPbcInternal, _hidl_cb, bssid); 385} 386 387Return<void> StaIface::startWpsPinKeypad( 388 const hidl_string &pin, startWpsPinKeypad_cb _hidl_cb) 389{ 390 return validateAndCall( 391 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 392 &StaIface::startWpsPinKeypadInternal, _hidl_cb, pin); 393} 394 395Return<void> StaIface::startWpsPinDisplay( 396 const hidl_array<uint8_t, 6> &bssid, startWpsPinDisplay_cb _hidl_cb) 397{ 398 return validateAndCall( 399 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 400 &StaIface::startWpsPinDisplayInternal, _hidl_cb, bssid); 401} 402 403Return<void> StaIface::cancelWps(cancelWps_cb _hidl_cb) 404{ 405 return validateAndCall( 406 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 407 &StaIface::cancelWpsInternal, _hidl_cb); 408} 409 410Return<void> StaIface::setWpsDeviceName( 411 const hidl_string &name, setWpsDeviceName_cb _hidl_cb) 412{ 413 return validateAndCall( 414 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 415 &StaIface::setWpsDeviceNameInternal, _hidl_cb, name); 416} 417 418Return<void> StaIface::setWpsDeviceType( 419 const hidl_array<uint8_t, 8> &type, setWpsDeviceType_cb _hidl_cb) 420{ 421 return validateAndCall( 422 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 423 &StaIface::setWpsDeviceTypeInternal, _hidl_cb, type); 424} 425 426Return<void> StaIface::setWpsManufacturer( 427 const hidl_string &manufacturer, setWpsManufacturer_cb _hidl_cb) 428{ 429 return validateAndCall( 430 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 431 &StaIface::setWpsManufacturerInternal, _hidl_cb, manufacturer); 432} 433 434Return<void> StaIface::setWpsModelName( 435 const hidl_string &model_name, setWpsModelName_cb _hidl_cb) 436{ 437 return validateAndCall( 438 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 439 &StaIface::setWpsModelNameInternal, _hidl_cb, model_name); 440} 441 442Return<void> StaIface::setWpsModelNumber( 443 const hidl_string &model_number, setWpsModelNumber_cb _hidl_cb) 444{ 445 return validateAndCall( 446 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 447 &StaIface::setWpsModelNumberInternal, _hidl_cb, model_number); 448} 449 450Return<void> StaIface::setWpsSerialNumber( 451 const hidl_string &serial_number, setWpsSerialNumber_cb _hidl_cb) 452{ 453 return validateAndCall( 454 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 455 &StaIface::setWpsSerialNumberInternal, _hidl_cb, serial_number); 456} 457 458Return<void> StaIface::setWpsConfigMethods( 459 uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb) 460{ 461 return validateAndCall( 462 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 463 &StaIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods); 464} 465 466Return<void> StaIface::setExternalSim( 467 bool useExternalSim, setExternalSim_cb _hidl_cb) 468{ 469 return validateAndCall( 470 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 471 &StaIface::setExternalSimInternal, _hidl_cb, useExternalSim); 472} 473 474Return<void> StaIface::addExtRadioWork( 475 const hidl_string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec, 476 addExtRadioWork_cb _hidl_cb) 477{ 478 return validateAndCall( 479 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 480 &StaIface::addExtRadioWorkInternal, _hidl_cb, name, freq_in_mhz, 481 timeout_in_sec); 482} 483 484Return<void> StaIface::removeExtRadioWork( 485 uint32_t id, removeExtRadioWork_cb _hidl_cb) 486{ 487 return validateAndCall( 488 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 489 &StaIface::removeExtRadioWorkInternal, _hidl_cb, id); 490} 491 492Return<void> StaIface::enableAutoReconnect( 493 bool enable, enableAutoReconnect_cb _hidl_cb) 494{ 495 return validateAndCall( 496 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 497 &StaIface::enableAutoReconnectInternal, _hidl_cb, enable); 498} 499 500std::pair<SupplicantStatus, std::string> StaIface::getNameInternal() 501{ 502 return {{SupplicantStatusCode::SUCCESS, ""}, ifname_}; 503} 504 505std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal() 506{ 507 return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA}; 508} 509 510std::pair<SupplicantStatus, sp<ISupplicantNetwork>> 511StaIface::addNetworkInternal() 512{ 513 android::sp<ISupplicantStaNetwork> network; 514 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 515 struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s); 516 if (!ssid) { 517 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network}; 518 } 519 HidlManager *hidl_manager = HidlManager::getInstance(); 520 if (!hidl_manager || 521 hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId( 522 wpa_s->ifname, ssid->id, &network)) { 523 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network}; 524 } 525 return {{SupplicantStatusCode::SUCCESS, ""}, network}; 526} 527 528SupplicantStatus StaIface::removeNetworkInternal(SupplicantNetworkId id) 529{ 530 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 531 int result = wpa_supplicant_remove_network(wpa_s, id); 532 if (result == -1) { 533 return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""}; 534 } 535 if (result != 0) { 536 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 537 } 538 return {SupplicantStatusCode::SUCCESS, ""}; 539} 540 541std::pair<SupplicantStatus, sp<ISupplicantNetwork>> 542StaIface::getNetworkInternal(SupplicantNetworkId id) 543{ 544 android::sp<ISupplicantStaNetwork> network; 545 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 546 struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id); 547 if (!ssid) { 548 return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""}, 549 network}; 550 } 551 HidlManager *hidl_manager = HidlManager::getInstance(); 552 if (!hidl_manager || 553 hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId( 554 wpa_s->ifname, ssid->id, &network)) { 555 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network}; 556 } 557 return {{SupplicantStatusCode::SUCCESS, ""}, network}; 558} 559 560std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>> 561StaIface::listNetworksInternal() 562{ 563 std::vector<SupplicantNetworkId> network_ids; 564 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 565 for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid; 566 wpa_ssid = wpa_ssid->next) { 567 network_ids.emplace_back(wpa_ssid->id); 568 } 569 return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)}; 570} 571 572SupplicantStatus StaIface::registerCallbackInternal( 573 const sp<ISupplicantStaIfaceCallback> &callback) 574{ 575 HidlManager *hidl_manager = HidlManager::getInstance(); 576 if (!hidl_manager || 577 hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) { 578 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 579 } 580 return {SupplicantStatusCode::SUCCESS, ""}; 581} 582 583SupplicantStatus StaIface::reassociateInternal() 584{ 585 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 586 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 587 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 588 } 589 wpas_request_connection(wpa_s); 590 return {SupplicantStatusCode::SUCCESS, ""}; 591} 592 593SupplicantStatus StaIface::reconnectInternal() 594{ 595 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 596 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 597 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 598 } 599 if (!wpa_s->disconnected) { 600 return {SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED, 601 ""}; 602 } 603 wpas_request_connection(wpa_s); 604 return {SupplicantStatusCode::SUCCESS, ""}; 605} 606 607SupplicantStatus StaIface::disconnectInternal() 608{ 609 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 610 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 611 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 612 } 613 wpas_request_disconnection(wpa_s); 614 return {SupplicantStatusCode::SUCCESS, ""}; 615} 616 617SupplicantStatus StaIface::setPowerSaveInternal(bool enable) 618{ 619 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 620 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 621 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""}; 622 } 623 if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) { 624 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 625 } 626 return {SupplicantStatusCode::SUCCESS, ""}; 627} 628 629SupplicantStatus StaIface::initiateTdlsDiscoverInternal( 630 const std::array<uint8_t, 6> &mac_address) 631{ 632 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 633 int ret; 634 const u8 *peer = mac_address.data(); 635 if (wpa_tdls_is_external_setup(wpa_s->wpa)) { 636 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer); 637 } else { 638 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer); 639 } 640 if (ret) { 641 wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret); 642 } 643 return {SupplicantStatusCode::SUCCESS, ""}; 644} 645 646SupplicantStatus StaIface::initiateTdlsSetupInternal( 647 const std::array<uint8_t, 6> &mac_address) 648{ 649 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 650 int ret; 651 const u8 *peer = mac_address.data(); 652 if (wpa_tdls_is_external_setup(wpa_s->wpa) && 653 !(wpa_s->conf->tdls_external_control)) { 654 wpa_tdls_remove(wpa_s->wpa, peer); 655 ret = wpa_tdls_start(wpa_s->wpa, peer); 656 } else { 657 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 658 } 659 if (ret) { 660 wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret); 661 } 662 return {SupplicantStatusCode::SUCCESS, ""}; 663} 664 665SupplicantStatus StaIface::initiateTdlsTeardownInternal( 666 const std::array<uint8_t, 6> &mac_address) 667{ 668 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 669 int ret; 670 const u8 *peer = mac_address.data(); 671 if (wpa_tdls_is_external_setup(wpa_s->wpa) && 672 !(wpa_s->conf->tdls_external_control)) { 673 ret = wpa_tdls_teardown_link( 674 wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED); 675 } else { 676 ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer); 677 } 678 if (ret) { 679 wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret); 680 } 681 return {SupplicantStatusCode::SUCCESS, ""}; 682} 683 684SupplicantStatus StaIface::initiateAnqpQueryInternal( 685 const std::array<uint8_t, 6> &mac_address, 686 const std::vector<ISupplicantStaIface::AnqpInfoId> &info_elements, 687 const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types) 688{ 689 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 690 if (info_elements.size() > kMaxAnqpElems) { 691 return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}; 692 } 693 uint16_t info_elems_buf[kMaxAnqpElems]; 694 uint32_t num_info_elems = 0; 695 for (const auto &info_element : info_elements) { 696 info_elems_buf[num_info_elems++] = 697 static_cast<std::underlying_type< 698 ISupplicantStaIface::AnqpInfoId>::type>(info_element); 699 } 700 uint32_t sub_types_bitmask = 0; 701 for (const auto &type : sub_types) { 702 sub_types_bitmask |= BIT( 703 static_cast<std::underlying_type< 704 ISupplicantStaIface::Hs20AnqpSubtypes>::type>(type)); 705 } 706 if (anqp_send_req( 707 wpa_s, mac_address.data(), info_elems_buf, num_info_elems, 708 sub_types_bitmask, false)) { 709 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 710 } 711 return {SupplicantStatusCode::SUCCESS, ""}; 712} 713 714SupplicantStatus StaIface::initiateHs20IconQueryInternal( 715 const std::array<uint8_t, 6> &mac_address, const std::string &file_name) 716{ 717 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 718 wpa_s->fetch_osu_icon_in_progress = 0; 719 if (hs20_anqp_send_req( 720 wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST), 721 reinterpret_cast<const uint8_t *>(file_name.c_str()), 722 file_name.size(), true)) { 723 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 724 } 725 return {SupplicantStatusCode::SUCCESS, ""}; 726} 727 728std::pair<SupplicantStatus, std::array<uint8_t, 6>> 729StaIface::getMacAddressInternal() 730{ 731 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 732 std::vector<char> cmd( 733 kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress)); 734 char driver_cmd_reply_buf[4096] = {}; 735 int ret = wpa_drv_driver_cmd( 736 wpa_s, cmd.data(), driver_cmd_reply_buf, 737 sizeof(driver_cmd_reply_buf)); 738 // Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX" 739 std::string reply_str = driver_cmd_reply_buf; 740 if (ret < 0 || reply_str.empty() || 741 reply_str.find("=") == std::string::npos) { 742 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}}; 743 } 744 // Remove all whitespace first and then split using the delimiter "=". 745 reply_str.erase( 746 remove_if(reply_str.begin(), reply_str.end(), isspace), 747 reply_str.end()); 748 std::string mac_addr_str = 749 reply_str.substr(reply_str.find("=") + 1, reply_str.size()); 750 std::array<uint8_t, 6> mac_addr; 751 if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) { 752 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}}; 753 } 754 return {{SupplicantStatusCode::SUCCESS, ""}, mac_addr}; 755} 756 757SupplicantStatus StaIface::startRxFilterInternal() 758{ 759 return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter); 760} 761 762SupplicantStatus StaIface::stopRxFilterInternal() 763{ 764 return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter); 765} 766 767SupplicantStatus StaIface::addRxFilterInternal( 768 ISupplicantStaIface::RxFilterType type) 769{ 770 return doOneArgDriverCommand( 771 retrieveIfacePtr(), kAddRxFilter, 772 convertHidlRxFilterTypeToInternal(type)); 773} 774 775SupplicantStatus StaIface::removeRxFilterInternal( 776 ISupplicantStaIface::RxFilterType type) 777{ 778 return doOneArgDriverCommand( 779 retrieveIfacePtr(), kRemoveRxFilter, 780 convertHidlRxFilterTypeToInternal(type)); 781} 782 783SupplicantStatus StaIface::setBtCoexistenceModeInternal( 784 ISupplicantStaIface::BtCoexistenceMode mode) 785{ 786 return doOneArgDriverCommand( 787 retrieveIfacePtr(), kSetBtCoexistenceMode, 788 convertHidlBtCoexModeToInternal(mode)); 789} 790 791SupplicantStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable) 792{ 793 const char *cmd; 794 if (enable) { 795 cmd = kSetBtCoexistenceScanStart; 796 } else { 797 cmd = kSetBtCoexistenceScanStop; 798 } 799 return doZeroArgDriverCommand(retrieveIfacePtr(), cmd); 800} 801 802SupplicantStatus StaIface::setSuspendModeEnabledInternal(bool enable) 803{ 804 const char *cmd; 805 if (enable) { 806 cmd = kSetSupendModeEnabled; 807 } else { 808 cmd = kSetSupendModeDisabled; 809 } 810 return doZeroArgDriverCommand(retrieveIfacePtr(), cmd); 811} 812 813SupplicantStatus StaIface::setCountryCodeInternal( 814 const std::array<int8_t, 2> &code) 815{ 816 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 817 SupplicantStatus status = doOneArgDriverCommand( 818 wpa_s, kSetCountryCode, 819 std::string(std::begin(code), std::end(code))); 820 if (status.code != SupplicantStatusCode::SUCCESS) { 821 return status; 822 } 823 struct p2p_data *p2p = wpa_s->global->p2p; 824 if (p2p) { 825 char country[3]; 826 country[0] = code[0]; 827 country[1] = code[1]; 828 country[2] = 0x04; 829 p2p_set_country(p2p, country); 830 } 831 return {SupplicantStatusCode::SUCCESS, ""}; 832} 833 834SupplicantStatus StaIface::startWpsRegistrarInternal( 835 const std::array<uint8_t, 6> &bssid, const std::string &pin) 836{ 837 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 838 if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) { 839 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 840 } 841 return {SupplicantStatusCode::SUCCESS, ""}; 842} 843 844SupplicantStatus StaIface::startWpsPbcInternal( 845 const std::array<uint8_t, 6> &bssid) 846{ 847 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 848 const uint8_t *bssid_addr = 849 is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data(); 850 if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0)) { 851 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 852 } 853 return {SupplicantStatusCode::SUCCESS, ""}; 854} 855 856SupplicantStatus StaIface::startWpsPinKeypadInternal(const std::string &pin) 857{ 858 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 859 if (wpas_wps_start_pin( 860 wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) { 861 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 862 } 863 return {SupplicantStatusCode::SUCCESS, ""}; 864} 865 866std::pair<SupplicantStatus, std::string> StaIface::startWpsPinDisplayInternal( 867 const std::array<uint8_t, 6> &bssid) 868{ 869 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 870 const uint8_t *bssid_addr = 871 is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data(); 872 int pin = 873 wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT); 874 if (pin < 0) { 875 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""}; 876 } 877 return {{SupplicantStatusCode::SUCCESS, ""}, 878 misc_utils::convertWpsPinToString(pin)}; 879} 880 881SupplicantStatus StaIface::cancelWpsInternal() 882{ 883 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 884 if (wpas_wps_cancel(wpa_s)) { 885 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 886 } 887 return {SupplicantStatusCode::SUCCESS, ""}; 888} 889 890SupplicantStatus StaIface::setWpsDeviceNameInternal(const std::string &name) 891{ 892 return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name); 893} 894 895SupplicantStatus StaIface::setWpsDeviceTypeInternal( 896 const std::array<uint8_t, 8> &type) 897{ 898 return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type); 899} 900 901SupplicantStatus StaIface::setWpsManufacturerInternal( 902 const std::string &manufacturer) 903{ 904 return iface_config_utils::setWpsManufacturer( 905 retrieveIfacePtr(), manufacturer); 906} 907 908SupplicantStatus StaIface::setWpsModelNameInternal( 909 const std::string &model_name) 910{ 911 return iface_config_utils::setWpsModelName( 912 retrieveIfacePtr(), model_name); 913} 914 915SupplicantStatus StaIface::setWpsModelNumberInternal( 916 const std::string &model_number) 917{ 918 return iface_config_utils::setWpsModelNumber( 919 retrieveIfacePtr(), model_number); 920} 921 922SupplicantStatus StaIface::setWpsSerialNumberInternal( 923 const std::string &serial_number) 924{ 925 return iface_config_utils::setWpsSerialNumber( 926 retrieveIfacePtr(), serial_number); 927} 928 929SupplicantStatus StaIface::setWpsConfigMethodsInternal(uint16_t config_methods) 930{ 931 return iface_config_utils::setWpsConfigMethods( 932 retrieveIfacePtr(), config_methods); 933} 934 935SupplicantStatus StaIface::setExternalSimInternal(bool useExternalSim) 936{ 937 return iface_config_utils::setExternalSim( 938 retrieveIfacePtr(), useExternalSim); 939} 940 941std::pair<SupplicantStatus, uint32_t> StaIface::addExtRadioWorkInternal( 942 const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec) 943{ 944 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 945 auto *ework = static_cast<struct wpa_external_work *>( 946 os_zalloc(sizeof(struct wpa_external_work))); 947 if (!ework) { 948 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, 949 UINT32_MAX}; 950 } 951 952 std::string radio_work_name = kExtRadioWorkNamePrefix + name; 953 os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type)); 954 ework->timeout = timeout_in_sec; 955 wpa_s->ext_work_id++; 956 if (wpa_s->ext_work_id == 0) { 957 wpa_s->ext_work_id++; 958 } 959 ework->id = wpa_s->ext_work_id; 960 961 if (radio_add_work( 962 wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb, 963 ework)) { 964 os_free(ework); 965 return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, 966 UINT32_MAX}; 967 } 968 return {SupplicantStatus{SupplicantStatusCode::SUCCESS, ""}, ework->id}; 969} 970 971SupplicantStatus StaIface::removeExtRadioWorkInternal(uint32_t id) 972{ 973 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 974 struct wpa_radio_work *work; 975 dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list) 976 { 977 if (os_strncmp( 978 work->type, kExtRadioWorkNamePrefix, 979 sizeof(kExtRadioWorkNamePrefix)) != 0) 980 continue; 981 982 auto *ework = 983 static_cast<struct wpa_external_work *>(work->ctx); 984 if (ework->id != id) 985 continue; 986 987 wpa_dbg( 988 wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)", 989 ework->id, ework->type); 990 eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL); 991 endExtRadioWork(work); 992 993 return {SupplicantStatusCode::SUCCESS, ""}; 994 } 995 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""}; 996} 997 998SupplicantStatus StaIface::enableAutoReconnectInternal(bool enable) 999{ 1000 struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1001 wpa_s->auto_reconnect_disabled = enable ? 0 : 1; 1002 return {SupplicantStatusCode::SUCCESS, ""}; 1003} 1004 1005/** 1006 * Retrieve the underlying |wpa_supplicant| struct 1007 * pointer for this iface. 1008 * If the underlying iface is removed, then all RPC method calls on this object 1009 * will return failure. 1010 */ 1011wpa_supplicant *StaIface::retrieveIfacePtr() 1012{ 1013 return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str()); 1014} 1015} // namespace implementation 1016} // namespace V1_0 1017} // namespace wifi 1018} // namespace supplicant 1019} // namespace hardware 1020} // namespace android 1021