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 #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 24 namespace { 25 using android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface; 26 using android::hardware::wifi::supplicant::V1_0::SupplicantStatus; 27 using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; 28 using android::hardware::wifi::supplicant::V1_0::implementation::HidlManager; 29 30 constexpr uint32_t kMaxAnqpElems = 100; 31 constexpr char kGetMacAddress[] = "MACADDR"; 32 constexpr char kStartRxFilter[] = "RXFILTER-START"; 33 constexpr char kStopRxFilter[] = "RXFILTER-STOP"; 34 constexpr char kAddRxFilter[] = "RXFILTER-ADD"; 35 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE"; 36 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE"; 37 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START"; 38 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP"; 39 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1"; 40 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0"; 41 constexpr char kSetCountryCode[] = "COUNTRY"; 42 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec = static_cast<uint32_t>( 43 ISupplicantStaIface::ExtRadioWorkDefaults::TIMEOUT_IN_SECS); 44 constexpr char kExtRadioWorkNamePrefix[] = "ext:"; 45 46 uint8_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 58 uint8_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 72 SupplicantStatus 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 85 SupplicantStatus 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 92 SupplicantStatus 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 99 void 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 107 void 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 122 void 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 133 void 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 154 namespace android { 155 namespace hardware { 156 namespace wifi { 157 namespace supplicant { 158 namespace V1_0 { 159 namespace implementation { 160 using hidl_return_util::validateAndCall; 161 162 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[]) 163 : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true) 164 { 165 } 166 167 void StaIface::invalidate() { is_valid_ = false; } 168 bool StaIface::isValid() 169 { 170 return (is_valid_ && (retrieveIfacePtr() != nullptr)); 171 } 172 173 Return<void> StaIface::getName(getName_cb _hidl_cb) 174 { 175 return validateAndCall( 176 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 177 &StaIface::getNameInternal, _hidl_cb); 178 } 179 180 Return<void> StaIface::getType(getType_cb _hidl_cb) 181 { 182 return validateAndCall( 183 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 184 &StaIface::getTypeInternal, _hidl_cb); 185 } 186 187 Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb) 188 { 189 return validateAndCall( 190 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 191 &StaIface::addNetworkInternal, _hidl_cb); 192 } 193 194 Return<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 202 Return<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 210 Return<void> StaIface::listNetworks(listNetworks_cb _hidl_cb) 211 { 212 return validateAndCall( 213 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 214 &StaIface::listNetworksInternal, _hidl_cb); 215 } 216 217 Return<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 226 Return<void> StaIface::reassociate(reassociate_cb _hidl_cb) 227 { 228 return validateAndCall( 229 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 230 &StaIface::reassociateInternal, _hidl_cb); 231 } 232 233 Return<void> StaIface::reconnect(reconnect_cb _hidl_cb) 234 { 235 return validateAndCall( 236 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 237 &StaIface::reconnectInternal, _hidl_cb); 238 } 239 240 Return<void> StaIface::disconnect(disconnect_cb _hidl_cb) 241 { 242 return validateAndCall( 243 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 244 &StaIface::disconnectInternal, _hidl_cb); 245 } 246 247 Return<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 254 Return<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 262 Return<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 270 Return<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 } 277 Return<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 289 Return<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 299 Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb) 300 { 301 return validateAndCall( 302 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 303 &StaIface::getMacAddressInternal, _hidl_cb); 304 } 305 306 Return<void> StaIface::startRxFilter(startRxFilter_cb _hidl_cb) 307 { 308 return validateAndCall( 309 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 310 &StaIface::startRxFilterInternal, _hidl_cb); 311 } 312 313 Return<void> StaIface::stopRxFilter(stopRxFilter_cb _hidl_cb) 314 { 315 return validateAndCall( 316 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 317 &StaIface::stopRxFilterInternal, _hidl_cb); 318 } 319 320 Return<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 328 Return<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 336 Return<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 345 Return<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 354 Return<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 362 Return<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 370 Return<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 379 Return<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 387 Return<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 395 Return<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 403 Return<void> StaIface::cancelWps(cancelWps_cb _hidl_cb) 404 { 405 return validateAndCall( 406 this, SupplicantStatusCode::FAILURE_IFACE_INVALID, 407 &StaIface::cancelWpsInternal, _hidl_cb); 408 } 409 410 Return<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 418 Return<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 426 Return<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 434 Return<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 442 Return<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 450 Return<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 458 Return<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 466 Return<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 474 Return<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 484 Return<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 492 Return<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 500 std::pair<SupplicantStatus, std::string> StaIface::getNameInternal() 501 { 502 return {{SupplicantStatusCode::SUCCESS, ""}, ifname_}; 503 } 504 505 std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal() 506 { 507 return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA}; 508 } 509 510 std::pair<SupplicantStatus, sp<ISupplicantNetwork>> 511 StaIface::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 528 SupplicantStatus 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 541 std::pair<SupplicantStatus, sp<ISupplicantNetwork>> 542 StaIface::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 560 std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>> 561 StaIface::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 572 SupplicantStatus 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 583 SupplicantStatus 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 593 SupplicantStatus 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 607 SupplicantStatus 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 617 SupplicantStatus 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 629 SupplicantStatus 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 646 SupplicantStatus 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 665 SupplicantStatus 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 684 SupplicantStatus 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 714 SupplicantStatus 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 728 std::pair<SupplicantStatus, std::array<uint8_t, 6>> 729 StaIface::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 757 SupplicantStatus StaIface::startRxFilterInternal() 758 { 759 return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter); 760 } 761 762 SupplicantStatus StaIface::stopRxFilterInternal() 763 { 764 return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter); 765 } 766 767 SupplicantStatus StaIface::addRxFilterInternal( 768 ISupplicantStaIface::RxFilterType type) 769 { 770 return doOneArgDriverCommand( 771 retrieveIfacePtr(), kAddRxFilter, 772 convertHidlRxFilterTypeToInternal(type)); 773 } 774 775 SupplicantStatus StaIface::removeRxFilterInternal( 776 ISupplicantStaIface::RxFilterType type) 777 { 778 return doOneArgDriverCommand( 779 retrieveIfacePtr(), kRemoveRxFilter, 780 convertHidlRxFilterTypeToInternal(type)); 781 } 782 783 SupplicantStatus StaIface::setBtCoexistenceModeInternal( 784 ISupplicantStaIface::BtCoexistenceMode mode) 785 { 786 return doOneArgDriverCommand( 787 retrieveIfacePtr(), kSetBtCoexistenceMode, 788 convertHidlBtCoexModeToInternal(mode)); 789 } 790 791 SupplicantStatus 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 802 SupplicantStatus 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 813 SupplicantStatus 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 834 SupplicantStatus 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 844 SupplicantStatus 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 856 SupplicantStatus 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 866 std::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 881 SupplicantStatus 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 890 SupplicantStatus StaIface::setWpsDeviceNameInternal(const std::string &name) 891 { 892 return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name); 893 } 894 895 SupplicantStatus StaIface::setWpsDeviceTypeInternal( 896 const std::array<uint8_t, 8> &type) 897 { 898 return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type); 899 } 900 901 SupplicantStatus StaIface::setWpsManufacturerInternal( 902 const std::string &manufacturer) 903 { 904 return iface_config_utils::setWpsManufacturer( 905 retrieveIfacePtr(), manufacturer); 906 } 907 908 SupplicantStatus StaIface::setWpsModelNameInternal( 909 const std::string &model_name) 910 { 911 return iface_config_utils::setWpsModelName( 912 retrieveIfacePtr(), model_name); 913 } 914 915 SupplicantStatus StaIface::setWpsModelNumberInternal( 916 const std::string &model_number) 917 { 918 return iface_config_utils::setWpsModelNumber( 919 retrieveIfacePtr(), model_number); 920 } 921 922 SupplicantStatus StaIface::setWpsSerialNumberInternal( 923 const std::string &serial_number) 924 { 925 return iface_config_utils::setWpsSerialNumber( 926 retrieveIfacePtr(), serial_number); 927 } 928 929 SupplicantStatus StaIface::setWpsConfigMethodsInternal(uint16_t config_methods) 930 { 931 return iface_config_utils::setWpsConfigMethods( 932 retrieveIfacePtr(), config_methods); 933 } 934 935 SupplicantStatus StaIface::setExternalSimInternal(bool useExternalSim) 936 { 937 return iface_config_utils::setExternalSim( 938 retrieveIfacePtr(), useExternalSim); 939 } 940 941 std::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 971 SupplicantStatus 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 998 SupplicantStatus 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 */ 1011 wpa_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