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 <algorithm> 11 #include <regex> 12 13 #include "hidl_manager.h" 14 #include "misc_utils.h" 15 16 extern "C" { 17 #include "src/eap_common/eap_sim_common.h" 18 } 19 20 namespace { 21 using android::hardware::hidl_array; 22 23 constexpr uint8_t kWfdDeviceInfoLen = 6; 24 // GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>] 25 constexpr char kGsmAuthRegex2[] = "GSM-AUTH:([0-9a-f]+):([0-9a-f]+)"; 26 constexpr char kGsmAuthRegex3[] = 27 "GSM-AUTH:([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)"; 28 // UMTS-AUTH:<RAND>:<AUTN> 29 constexpr char kUmtsAuthRegex[] = "UMTS-AUTH:([0-9a-f]+):([0-9a-f]+)"; 30 constexpr size_t kGsmRandLenBytes = GSM_RAND_LEN; 31 constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN; 32 constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN; 33 constexpr u8 kZeroBssid[6] = {0, 0, 0, 0, 0, 0}; 34 /** 35 * Check if the provided |wpa_supplicant| structure represents a P2P iface or 36 * not. 37 */ 38 constexpr bool isP2pIface(const struct wpa_supplicant *wpa_s) 39 { 40 return (wpa_s->global->p2p_init_wpa_s == wpa_s); 41 } 42 43 /** 44 * Creates a unique key for the network using the provided |ifname| and 45 * |network_id| to be used in the internal map of |ISupplicantNetwork| objects. 46 * This is of the form |ifname|_|network_id|. For ex: "wlan0_1". 47 * 48 * @param ifname Name of the corresponding interface. 49 * @param network_id ID of the corresponding network. 50 */ 51 const std::string getNetworkObjectMapKey( 52 const std::string &ifname, int network_id) 53 { 54 return ifname + "_" + std::to_string(network_id); 55 } 56 57 /** 58 * Add callback to the corresponding list after linking to death on the 59 * corresponding hidl object reference. 60 */ 61 template <class CallbackType> 62 int registerForDeathAndAddCallbackHidlObjectToList( 63 const android::sp<CallbackType> &callback, 64 const std::function<void(const android::sp<CallbackType> &)> 65 &on_hidl_died_fctor, 66 std::vector<android::sp<CallbackType>> &callback_list) 67 { 68 #if 0 // TODO(b/31632518): HIDL object death notifications. 69 auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>( 70 callback, on_hidl_died_fctor); 71 // Use the |callback.get()| as cookie so that we don't need to 72 // store a reference to this |CallbackObjectDeathNotifier| instance 73 // to use in |unlinkToDeath| later. 74 // NOTE: This may cause an immediate callback if the object is already 75 // dead, so add it to the list before we register for callback! 76 if (android::hardware::IInterface::asBinder(callback)->linkToDeath( 77 death_notifier, callback.get()) != android::OK) { 78 wpa_printf( 79 MSG_ERROR, 80 "Error registering for death notification for " 81 "supplicant callback object"); 82 callback_list.erase( 83 std::remove( 84 callback_list.begin(), callback_list.end(), callback), 85 callback_list.end()); 86 return 1; 87 } 88 #endif // TODO(b/31632518): HIDL object death notifications. 89 callback_list.push_back(callback); 90 return 0; 91 } 92 93 template <class ObjectType> 94 int addHidlObjectToMap( 95 const std::string &key, const android::sp<ObjectType> object, 96 std::map<const std::string, android::sp<ObjectType>> &object_map) 97 { 98 // Return failure if we already have an object for that |key|. 99 if (object_map.find(key) != object_map.end()) 100 return 1; 101 object_map[key] = object; 102 if (!object_map[key].get()) 103 return 1; 104 return 0; 105 } 106 107 template <class ObjectType> 108 int removeHidlObjectFromMap( 109 const std::string &key, 110 std::map<const std::string, android::sp<ObjectType>> &object_map) 111 { 112 // Return failure if we dont have an object for that |key|. 113 const auto &object_iter = object_map.find(key); 114 if (object_iter == object_map.end()) 115 return 1; 116 object_iter->second->invalidate(); 117 object_map.erase(object_iter); 118 return 0; 119 } 120 121 template <class CallbackType> 122 int addIfaceCallbackHidlObjectToMap( 123 const std::string &ifname, const android::sp<CallbackType> &callback, 124 const std::function<void(const android::sp<CallbackType> &)> 125 &on_hidl_died_fctor, 126 std::map<const std::string, std::vector<android::sp<CallbackType>>> 127 &callbacks_map) 128 { 129 if (ifname.empty()) 130 return 1; 131 132 auto iface_callback_map_iter = callbacks_map.find(ifname); 133 if (iface_callback_map_iter == callbacks_map.end()) 134 return 1; 135 auto &iface_callback_list = iface_callback_map_iter->second; 136 137 // Register for death notification before we add it to our list. 138 return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>( 139 callback, on_hidl_died_fctor, iface_callback_list); 140 } 141 142 template <class CallbackType> 143 int addNetworkCallbackHidlObjectToMap( 144 const std::string &ifname, int network_id, 145 const android::sp<CallbackType> &callback, 146 const std::function<void(const android::sp<CallbackType> &)> 147 &on_hidl_died_fctor, 148 std::map<const std::string, std::vector<android::sp<CallbackType>>> 149 &callbacks_map) 150 { 151 if (ifname.empty() || network_id < 0) 152 return 1; 153 154 // Generate the key to be used to lookup the network. 155 const std::string network_key = 156 getNetworkObjectMapKey(ifname, network_id); 157 auto network_callback_map_iter = callbacks_map.find(network_key); 158 if (network_callback_map_iter == callbacks_map.end()) 159 return 1; 160 auto &network_callback_list = network_callback_map_iter->second; 161 162 // Register for death notification before we add it to our list. 163 return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>( 164 callback, on_hidl_died_fctor, network_callback_list); 165 } 166 167 template <class CallbackType> 168 int removeAllIfaceCallbackHidlObjectsFromMap( 169 const std::string &ifname, 170 std::map<const std::string, std::vector<android::sp<CallbackType>>> 171 &callbacks_map) 172 { 173 auto iface_callback_map_iter = callbacks_map.find(ifname); 174 if (iface_callback_map_iter == callbacks_map.end()) 175 return 1; 176 #if 0 // TODO(b/31632518): HIDL object death notifications. 177 const auto &iface_callback_list = iface_callback_map_iter->second; 178 for (const auto &callback : iface_callback_list) { 179 if (android::hardware::IInterface::asBinder(callback) 180 ->unlinkToDeath(nullptr, callback.get()) != 181 android::OK) { 182 wpa_printf( 183 MSG_ERROR, 184 "Error deregistering for death notification for " 185 "iface callback object"); 186 } 187 } 188 #endif // TODO(b/31632518): HIDL object death notifications. 189 callbacks_map.erase(iface_callback_map_iter); 190 return 0; 191 } 192 193 template <class CallbackType> 194 int removeAllNetworkCallbackHidlObjectsFromMap( 195 const std::string &network_key, 196 std::map<const std::string, std::vector<android::sp<CallbackType>>> 197 &callbacks_map) 198 { 199 auto network_callback_map_iter = callbacks_map.find(network_key); 200 if (network_callback_map_iter == callbacks_map.end()) 201 return 1; 202 #if 0 // TODO(b/31632518): HIDL object death notifications. 203 const auto &network_callback_list = network_callback_map_iter->second; 204 for (const auto &callback : network_callback_list) { 205 if (android::hardware::IInterface::asBinder(callback) 206 ->unlinkToDeath(nullptr, callback.get()) != 207 android::OK) { 208 wpa_printf( 209 MSG_ERROR, 210 "Error deregistering for death " 211 "notification for " 212 "network callback object"); 213 } 214 } 215 #endif // TODO(b/31632518): HIDL object death notifications. 216 callbacks_map.erase(network_callback_map_iter); 217 return 0; 218 } 219 220 template <class CallbackType> 221 void removeIfaceCallbackHidlObjectFromMap( 222 const std::string &ifname, const android::sp<CallbackType> &callback, 223 std::map<const std::string, std::vector<android::sp<CallbackType>>> 224 &callbacks_map) 225 { 226 if (ifname.empty()) 227 return; 228 229 auto iface_callback_map_iter = callbacks_map.find(ifname); 230 if (iface_callback_map_iter == callbacks_map.end()) 231 return; 232 233 auto &iface_callback_list = iface_callback_map_iter->second; 234 iface_callback_list.erase( 235 std::remove( 236 iface_callback_list.begin(), iface_callback_list.end(), 237 callback), 238 iface_callback_list.end()); 239 } 240 241 template <class CallbackType> 242 void removeNetworkCallbackHidlObjectFromMap( 243 const std::string &ifname, int network_id, 244 const android::sp<CallbackType> &callback, 245 std::map<const std::string, std::vector<android::sp<CallbackType>>> 246 &callbacks_map) 247 { 248 if (ifname.empty() || network_id < 0) 249 return; 250 251 // Generate the key to be used to lookup the network. 252 const std::string network_key = 253 getNetworkObjectMapKey(ifname, network_id); 254 255 auto network_callback_map_iter = callbacks_map.find(network_key); 256 if (network_callback_map_iter == callbacks_map.end()) 257 return; 258 259 auto &network_callback_list = network_callback_map_iter->second; 260 network_callback_list.erase( 261 std::remove( 262 network_callback_list.begin(), network_callback_list.end(), 263 callback), 264 network_callback_list.end()); 265 } 266 267 template <class CallbackType> 268 void callWithEachIfaceCallback( 269 const std::string &ifname, 270 const std::function< 271 android::hardware::Return<void>(android::sp<CallbackType>)> &method, 272 const std::map<const std::string, std::vector<android::sp<CallbackType>>> 273 &callbacks_map) 274 { 275 if (ifname.empty()) 276 return; 277 278 auto iface_callback_map_iter = callbacks_map.find(ifname); 279 if (iface_callback_map_iter == callbacks_map.end()) 280 return; 281 const auto &iface_callback_list = iface_callback_map_iter->second; 282 for (const auto &callback : iface_callback_list) { 283 if (!method(callback).isOk()) { 284 wpa_printf( 285 MSG_ERROR, "Failed to invoke HIDL iface callback"); 286 } 287 } 288 } 289 290 template <class CallbackType> 291 void callWithEachNetworkCallback( 292 const std::string &ifname, int network_id, 293 const std::function< 294 android::hardware::Return<void>(android::sp<CallbackType>)> &method, 295 const std::map<const std::string, std::vector<android::sp<CallbackType>>> 296 &callbacks_map) 297 { 298 if (ifname.empty() || network_id < 0) 299 return; 300 301 // Generate the key to be used to lookup the network. 302 const std::string network_key = 303 getNetworkObjectMapKey(ifname, network_id); 304 auto network_callback_map_iter = callbacks_map.find(network_key); 305 if (network_callback_map_iter == callbacks_map.end()) 306 return; 307 const auto &network_callback_list = network_callback_map_iter->second; 308 for (const auto &callback : network_callback_list) { 309 if (!method(callback).isOk()) { 310 wpa_printf( 311 MSG_ERROR, 312 "Failed to invoke HIDL network callback"); 313 } 314 } 315 } 316 317 int parseGsmAuthNetworkRequest( 318 const std::string ¶ms_str, 319 std::vector<hidl_array<uint8_t, kGsmRandLenBytes>> *out_rands) 320 { 321 std::smatch matches; 322 std::regex params_gsm_regex2(kGsmAuthRegex2); 323 std::regex params_gsm_regex3(kGsmAuthRegex3); 324 if (!std::regex_match(params_str, matches, params_gsm_regex3) && 325 !std::regex_match(params_str, matches, params_gsm_regex2)) { 326 return 1; 327 } 328 for (uint32_t i = 1; i < matches.size(); i++) { 329 hidl_array<uint8_t, kGsmRandLenBytes> rand; 330 const auto &match = matches[i]; 331 WPA_ASSERT(match.size() >= 2 * rand.size()); 332 if (hexstr2bin(match.str().c_str(), rand.data(), rand.size())) { 333 wpa_printf( 334 MSG_ERROR, "Failed to parse GSM auth params"); 335 return 1; 336 } 337 out_rands->push_back(rand); 338 } 339 return 0; 340 } 341 342 int parseUmtsAuthNetworkRequest( 343 const std::string ¶ms_str, 344 hidl_array<uint8_t, kUmtsRandLenBytes> *out_rand, 345 hidl_array<uint8_t, kUmtsAutnLenBytes> *out_autn) 346 { 347 std::smatch matches; 348 std::regex params_umts_regex(kUmtsAuthRegex); 349 if (!std::regex_match(params_str, matches, params_umts_regex)) { 350 return 1; 351 } 352 WPA_ASSERT(matches[1].size() >= 2 * out_rand->size()); 353 if (hexstr2bin( 354 matches[1].str().c_str(), out_rand->data(), out_rand->size())) { 355 wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params"); 356 return 1; 357 } 358 WPA_ASSERT(matches[2].size() >= 2 * out_autn->size()); 359 if (hexstr2bin( 360 matches[2].str().c_str(), out_autn->data(), out_autn->size())) { 361 wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params"); 362 return 1; 363 } 364 return 0; 365 } 366 } // namespace 367 368 namespace android { 369 namespace hardware { 370 namespace wifi { 371 namespace supplicant { 372 namespace V1_0 { 373 namespace implementation { 374 375 HidlManager *HidlManager::instance_ = NULL; 376 377 HidlManager *HidlManager::getInstance() 378 { 379 if (!instance_) 380 instance_ = new HidlManager(); 381 return instance_; 382 } 383 384 void HidlManager::destroyInstance() 385 { 386 if (instance_) 387 delete instance_; 388 instance_ = NULL; 389 } 390 391 int HidlManager::registerHidlService(struct wpa_global *global) 392 { 393 // Create the main hidl service object and register it. 394 supplicant_object_ = new Supplicant(global); 395 if (supplicant_object_->registerAsService() != android::NO_ERROR) { 396 return 1; 397 } 398 return 0; 399 } 400 401 /** 402 * Register an interface to hidl manager. 403 * 404 * @param wpa_s |wpa_supplicant| struct corresponding to the interface. 405 * 406 * @return 0 on success, 1 on failure. 407 */ 408 int HidlManager::registerInterface(struct wpa_supplicant *wpa_s) 409 { 410 if (!wpa_s) 411 return 1; 412 413 if (isP2pIface(wpa_s)) { 414 if (addHidlObjectToMap<P2pIface>( 415 wpa_s->ifname, 416 new P2pIface(wpa_s->global, wpa_s->ifname), 417 p2p_iface_object_map_)) { 418 wpa_printf( 419 MSG_ERROR, 420 "Failed to register P2P interface with HIDL " 421 "control: %s", 422 wpa_s->ifname); 423 return 1; 424 } 425 p2p_iface_callbacks_map_[wpa_s->ifname] = 426 std::vector<android::sp<ISupplicantP2pIfaceCallback>>(); 427 } else { 428 if (addHidlObjectToMap<StaIface>( 429 wpa_s->ifname, 430 new StaIface(wpa_s->global, wpa_s->ifname), 431 sta_iface_object_map_)) { 432 wpa_printf( 433 MSG_ERROR, 434 "Failed to register STA interface with HIDL " 435 "control: %s", 436 wpa_s->ifname); 437 return 1; 438 } 439 sta_iface_callbacks_map_[wpa_s->ifname] = 440 std::vector<android::sp<ISupplicantStaIfaceCallback>>(); 441 } 442 443 // Invoke the |onInterfaceCreated| method on all registered callbacks. 444 callWithEachSupplicantCallback(std::bind( 445 &ISupplicantCallback::onInterfaceCreated, std::placeholders::_1, 446 wpa_s->ifname)); 447 return 0; 448 } 449 450 /** 451 * Unregister an interface from hidl manager. 452 * 453 * @param wpa_s |wpa_supplicant| struct corresponding to the interface. 454 * 455 * @return 0 on success, 1 on failure. 456 */ 457 int HidlManager::unregisterInterface(struct wpa_supplicant *wpa_s) 458 { 459 if (!wpa_s) 460 return 1; 461 462 if (isP2pIface(wpa_s)) { 463 if (removeHidlObjectFromMap( 464 wpa_s->ifname, p2p_iface_object_map_)) { 465 wpa_printf( 466 MSG_ERROR, 467 "Failed to unregister P2P interface with HIDL " 468 "control: %s", 469 wpa_s->ifname); 470 return 1; 471 } 472 if (removeAllIfaceCallbackHidlObjectsFromMap( 473 wpa_s->ifname, p2p_iface_callbacks_map_)) { 474 return 1; 475 } 476 } else { 477 if (removeHidlObjectFromMap( 478 wpa_s->ifname, sta_iface_object_map_)) { 479 wpa_printf( 480 MSG_ERROR, 481 "Failed to unregister STA interface with HIDL " 482 "control: %s", 483 wpa_s->ifname); 484 return 1; 485 } 486 if (removeAllIfaceCallbackHidlObjectsFromMap( 487 wpa_s->ifname, sta_iface_callbacks_map_)) { 488 return 1; 489 } 490 } 491 492 // Invoke the |onInterfaceRemoved| method on all registered callbacks. 493 callWithEachSupplicantCallback(std::bind( 494 &ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1, 495 wpa_s->ifname)); 496 return 0; 497 } 498 499 /** 500 * Register a network to hidl manager. 501 * 502 * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which 503 * the network is added. 504 * @param ssid |wpa_ssid| struct corresponding to the network being added. 505 * 506 * @return 0 on success, 1 on failure. 507 */ 508 int HidlManager::registerNetwork( 509 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) 510 { 511 if (!wpa_s || !ssid) 512 return 1; 513 514 // Generate the key to be used to lookup the network. 515 const std::string network_key = 516 getNetworkObjectMapKey(wpa_s->ifname, ssid->id); 517 518 if (isP2pIface(wpa_s)) { 519 if (addHidlObjectToMap<P2pNetwork>( 520 network_key, 521 new P2pNetwork(wpa_s->global, wpa_s->ifname, ssid->id), 522 p2p_network_object_map_)) { 523 wpa_printf( 524 MSG_ERROR, 525 "Failed to register P2P network with HIDL " 526 "control: %d", 527 ssid->id); 528 return 1; 529 } 530 p2p_network_callbacks_map_[network_key] = 531 std::vector<android::sp<ISupplicantP2pNetworkCallback>>(); 532 // Invoke the |onNetworkAdded| method on all registered 533 // callbacks. 534 callWithEachP2pIfaceCallback( 535 wpa_s->ifname, 536 std::bind( 537 &ISupplicantP2pIfaceCallback::onNetworkAdded, 538 std::placeholders::_1, ssid->id)); 539 } else { 540 if (addHidlObjectToMap<StaNetwork>( 541 network_key, 542 new StaNetwork(wpa_s->global, wpa_s->ifname, ssid->id), 543 sta_network_object_map_)) { 544 wpa_printf( 545 MSG_ERROR, 546 "Failed to register STA network with HIDL " 547 "control: %d", 548 ssid->id); 549 return 1; 550 } 551 sta_network_callbacks_map_[network_key] = 552 std::vector<android::sp<ISupplicantStaNetworkCallback>>(); 553 // Invoke the |onNetworkAdded| method on all registered 554 // callbacks. 555 callWithEachStaIfaceCallback( 556 wpa_s->ifname, 557 std::bind( 558 &ISupplicantStaIfaceCallback::onNetworkAdded, 559 std::placeholders::_1, ssid->id)); 560 } 561 return 0; 562 } 563 564 /** 565 * Unregister a network from hidl manager. 566 * 567 * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which 568 * the network is added. 569 * @param ssid |wpa_ssid| struct corresponding to the network being added. 570 * 571 * @return 0 on success, 1 on failure. 572 */ 573 int HidlManager::unregisterNetwork( 574 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) 575 { 576 if (!wpa_s || !ssid) 577 return 1; 578 579 // Generate the key to be used to lookup the network. 580 const std::string network_key = 581 getNetworkObjectMapKey(wpa_s->ifname, ssid->id); 582 583 if (isP2pIface(wpa_s)) { 584 if (removeHidlObjectFromMap( 585 network_key, p2p_network_object_map_)) { 586 wpa_printf( 587 MSG_ERROR, 588 "Failed to unregister P2P network with HIDL " 589 "control: %d", 590 ssid->id); 591 return 1; 592 } 593 if (removeAllNetworkCallbackHidlObjectsFromMap( 594 network_key, p2p_network_callbacks_map_)) 595 return 1; 596 597 // Invoke the |onNetworkRemoved| method on all registered 598 // callbacks. 599 callWithEachP2pIfaceCallback( 600 wpa_s->ifname, 601 std::bind( 602 &ISupplicantP2pIfaceCallback::onNetworkRemoved, 603 std::placeholders::_1, ssid->id)); 604 } else { 605 if (removeHidlObjectFromMap( 606 network_key, sta_network_object_map_)) { 607 wpa_printf( 608 MSG_ERROR, 609 "Failed to unregister STA network with HIDL " 610 "control: %d", 611 ssid->id); 612 return 1; 613 } 614 if (removeAllNetworkCallbackHidlObjectsFromMap( 615 network_key, sta_network_callbacks_map_)) 616 return 1; 617 618 // Invoke the |onNetworkRemoved| method on all registered 619 // callbacks. 620 callWithEachStaIfaceCallback( 621 wpa_s->ifname, 622 std::bind( 623 &ISupplicantStaIfaceCallback::onNetworkRemoved, 624 std::placeholders::_1, ssid->id)); 625 } 626 return 0; 627 } 628 629 /** 630 * Notify all listeners about any state changes on a particular interface. 631 * 632 * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which 633 * the state change event occured. 634 */ 635 int HidlManager::notifyStateChange(struct wpa_supplicant *wpa_s) 636 { 637 if (!wpa_s) 638 return 1; 639 640 if (sta_iface_object_map_.find(wpa_s->ifname) == 641 sta_iface_object_map_.end()) 642 return 1; 643 644 // Invoke the |onStateChanged| method on all registered callbacks. 645 uint32_t hidl_network_id = UINT32_MAX; 646 std::vector<uint8_t> hidl_ssid; 647 if (wpa_s->current_ssid) { 648 hidl_network_id = wpa_s->current_ssid->id; 649 hidl_ssid.assign( 650 wpa_s->current_ssid->ssid, 651 wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len); 652 } 653 uint8_t *bssid; 654 // wpa_supplicant sets the |pending_bssid| field when it starts a 655 // connection. Only after association state does it update the |bssid| 656 // field. So, in the HIDL callback send the appropriate bssid. 657 if (wpa_s->wpa_state <= WPA_ASSOCIATED) { 658 bssid = wpa_s->pending_bssid; 659 } else { 660 bssid = wpa_s->bssid; 661 } 662 callWithEachStaIfaceCallback( 663 wpa_s->ifname, std::bind( 664 &ISupplicantStaIfaceCallback::onStateChanged, 665 std::placeholders::_1, 666 static_cast<ISupplicantStaIfaceCallback::State>( 667 wpa_s->wpa_state), 668 bssid, hidl_network_id, hidl_ssid)); 669 return 0; 670 } 671 672 /** 673 * Notify all listeners about a request on a particular network. 674 * 675 * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which 676 * the network is present. 677 * @param ssid |wpa_ssid| struct corresponding to the network. 678 * @param type type of request. 679 * @param param addition params associated with the request. 680 */ 681 int HidlManager::notifyNetworkRequest( 682 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type, 683 const char *param) 684 { 685 if (!wpa_s || !ssid) 686 return 1; 687 688 const std::string network_key = 689 getNetworkObjectMapKey(wpa_s->ifname, ssid->id); 690 if (sta_network_object_map_.find(network_key) == 691 sta_network_object_map_.end()) 692 return 1; 693 694 if (type == WPA_CTRL_REQ_EAP_IDENTITY) { 695 callWithEachStaNetworkCallback( 696 wpa_s->ifname, ssid->id, 697 std::bind( 698 &ISupplicantStaNetworkCallback:: 699 onNetworkEapIdentityRequest, 700 std::placeholders::_1)); 701 return 0; 702 } 703 if (type == WPA_CTRL_REQ_SIM) { 704 std::vector<hidl_array<uint8_t, 16>> gsm_rands; 705 hidl_array<uint8_t, 16> umts_rand; 706 hidl_array<uint8_t, 16> umts_autn; 707 if (!parseGsmAuthNetworkRequest(param, &gsm_rands)) { 708 ISupplicantStaNetworkCallback:: 709 NetworkRequestEapSimGsmAuthParams hidl_params; 710 hidl_params.rands = gsm_rands; 711 callWithEachStaNetworkCallback( 712 wpa_s->ifname, ssid->id, 713 std::bind( 714 &ISupplicantStaNetworkCallback:: 715 onNetworkEapSimGsmAuthRequest, 716 std::placeholders::_1, hidl_params)); 717 return 0; 718 } 719 if (!parseUmtsAuthNetworkRequest( 720 param, &umts_rand, &umts_autn)) { 721 ISupplicantStaNetworkCallback:: 722 NetworkRequestEapSimUmtsAuthParams hidl_params; 723 hidl_params.rand = umts_rand; 724 hidl_params.autn = umts_autn; 725 callWithEachStaNetworkCallback( 726 wpa_s->ifname, ssid->id, 727 std::bind( 728 &ISupplicantStaNetworkCallback:: 729 onNetworkEapSimUmtsAuthRequest, 730 std::placeholders::_1, hidl_params)); 731 return 0; 732 } 733 } 734 return 1; 735 } 736 737 /** 738 * Notify all listeners about the end of an ANQP query. 739 * 740 * @param wpa_s |wpa_supplicant| struct corresponding to the interface. 741 * @param bssid BSSID of the access point. 742 * @param result Result of the operation ("SUCCESS" or "FAILURE"). 743 * @param anqp |wpa_bss_anqp| ANQP data fetched. 744 */ 745 void HidlManager::notifyAnqpQueryDone( 746 struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result, 747 const struct wpa_bss_anqp *anqp) 748 { 749 if (!wpa_s || !bssid || !result || !anqp) 750 return; 751 752 if (sta_iface_object_map_.find(wpa_s->ifname) == 753 sta_iface_object_map_.end()) 754 return; 755 756 ISupplicantStaIfaceCallback::AnqpData hidl_anqp_data; 757 ISupplicantStaIfaceCallback::Hs20AnqpData hidl_hs20_anqp_data; 758 if (std::string(result) == "SUCCESS") { 759 hidl_anqp_data.venueName = 760 misc_utils::convertWpaBufToVector(anqp->venue_name); 761 hidl_anqp_data.roamingConsortium = 762 misc_utils::convertWpaBufToVector(anqp->roaming_consortium); 763 hidl_anqp_data.ipAddrTypeAvailability = 764 misc_utils::convertWpaBufToVector( 765 anqp->ip_addr_type_availability); 766 hidl_anqp_data.naiRealm = 767 misc_utils::convertWpaBufToVector(anqp->nai_realm); 768 hidl_anqp_data.anqp3gppCellularNetwork = 769 misc_utils::convertWpaBufToVector(anqp->anqp_3gpp); 770 hidl_anqp_data.domainName = 771 misc_utils::convertWpaBufToVector(anqp->domain_name); 772 773 hidl_hs20_anqp_data.operatorFriendlyName = 774 misc_utils::convertWpaBufToVector( 775 anqp->hs20_operator_friendly_name); 776 hidl_hs20_anqp_data.wanMetrics = 777 misc_utils::convertWpaBufToVector(anqp->hs20_wan_metrics); 778 hidl_hs20_anqp_data.connectionCapability = 779 misc_utils::convertWpaBufToVector( 780 anqp->hs20_connection_capability); 781 hidl_hs20_anqp_data.osuProvidersList = 782 misc_utils::convertWpaBufToVector( 783 anqp->hs20_osu_providers_list); 784 } 785 786 callWithEachStaIfaceCallback( 787 wpa_s->ifname, std::bind( 788 &ISupplicantStaIfaceCallback::onAnqpQueryDone, 789 std::placeholders::_1, bssid, hidl_anqp_data, 790 hidl_hs20_anqp_data)); 791 } 792 793 /** 794 * Notify all listeners about the end of an HS20 icon query. 795 * 796 * @param wpa_s |wpa_supplicant| struct corresponding to the interface. 797 * @param bssid BSSID of the access point. 798 * @param file_name Name of the icon file. 799 * @param image Raw bytes of the icon file. 800 * @param image_length Size of the the icon file. 801 */ 802 void HidlManager::notifyHs20IconQueryDone( 803 struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name, 804 const u8 *image, u32 image_length) 805 { 806 if (!wpa_s || !bssid || !file_name || !image) 807 return; 808 809 if (sta_iface_object_map_.find(wpa_s->ifname) == 810 sta_iface_object_map_.end()) 811 return; 812 813 callWithEachStaIfaceCallback( 814 wpa_s->ifname, 815 std::bind( 816 &ISupplicantStaIfaceCallback::onHs20IconQueryDone, 817 std::placeholders::_1, bssid, file_name, 818 std::vector<uint8_t>(image, image + image_length))); 819 } 820 821 /** 822 * Notify all listeners about the reception of HS20 subscription 823 * remediation notification from the server. 824 * 825 * @param wpa_s |wpa_supplicant| struct corresponding to the interface. 826 * @param url URL of the server. 827 * @param osu_method OSU method (OMA_DM or SOAP_XML_SPP). 828 */ 829 void HidlManager::notifyHs20RxSubscriptionRemediation( 830 struct wpa_supplicant *wpa_s, const char *url, u8 osu_method) 831 { 832 if (!wpa_s || !url) 833 return; 834 835 if (sta_iface_object_map_.find(wpa_s->ifname) == 836 sta_iface_object_map_.end()) 837 return; 838 839 ISupplicantStaIfaceCallback::OsuMethod hidl_osu_method = {}; 840 if (osu_method & 0x1) { 841 hidl_osu_method = 842 ISupplicantStaIfaceCallback::OsuMethod::OMA_DM; 843 } else if (osu_method & 0x2) { 844 hidl_osu_method = 845 ISupplicantStaIfaceCallback::OsuMethod::SOAP_XML_SPP; 846 } 847 callWithEachStaIfaceCallback( 848 wpa_s->ifname, 849 std::bind( 850 &ISupplicantStaIfaceCallback::onHs20SubscriptionRemediation, 851 std::placeholders::_1, wpa_s->bssid, hidl_osu_method, url)); 852 } 853 854 /** 855 * Notify all listeners about the reception of HS20 immient deauth 856 * notification from the server. 857 * 858 * @param wpa_s |wpa_supplicant| struct corresponding to the interface. 859 * @param code Deauth reason code sent from server. 860 * @param reauth_delay Reauthentication delay in seconds sent from server. 861 * @param url URL of the server. 862 */ 863 void HidlManager::notifyHs20RxDeauthImminentNotice( 864 struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url) 865 { 866 if (!wpa_s || !url) 867 return; 868 869 if (sta_iface_object_map_.find(wpa_s->ifname) == 870 sta_iface_object_map_.end()) 871 return; 872 873 callWithEachStaIfaceCallback( 874 wpa_s->ifname, 875 std::bind( 876 &ISupplicantStaIfaceCallback::onHs20DeauthImminentNotice, 877 std::placeholders::_1, wpa_s->bssid, code, reauth_delay, url)); 878 } 879 880 /** 881 * Notify all listeners about the reason code for disconnection from the 882 * currently connected network. 883 * 884 * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which 885 * the network is present. 886 */ 887 void HidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s) 888 { 889 if (!wpa_s) 890 return; 891 892 if (sta_iface_object_map_.find(wpa_s->ifname) == 893 sta_iface_object_map_.end()) 894 return; 895 896 const u8 *bssid = wpa_s->bssid; 897 if (is_zero_ether_addr(bssid)) { 898 bssid = wpa_s->pending_bssid; 899 } 900 901 callWithEachStaIfaceCallback( 902 wpa_s->ifname, 903 std::bind( 904 &ISupplicantStaIfaceCallback::onDisconnected, 905 std::placeholders::_1, bssid, wpa_s->disconnect_reason < 0, 906 static_cast<ISupplicantStaIfaceCallback::ReasonCode>( 907 wpa_s->disconnect_reason))); 908 } 909 910 /** 911 * Notify all listeners about association reject from the access point to which 912 * we are attempting to connect. 913 * 914 * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which 915 * the network is present. 916 */ 917 void HidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s) 918 { 919 if (!wpa_s) 920 return; 921 922 if (sta_iface_object_map_.find(wpa_s->ifname) == 923 sta_iface_object_map_.end()) 924 return; 925 926 const u8 *bssid = wpa_s->bssid; 927 if (is_zero_ether_addr(bssid)) { 928 bssid = wpa_s->pending_bssid; 929 } 930 931 callWithEachStaIfaceCallback( 932 wpa_s->ifname, 933 std::bind( 934 &ISupplicantStaIfaceCallback::onAssociationRejected, 935 std::placeholders::_1, bssid, 936 static_cast<ISupplicantStaIfaceCallback::StatusCode>( 937 wpa_s->assoc_status_code), 938 wpa_s->assoc_timed_out == 1)); 939 } 940 941 void HidlManager::notifyAuthTimeout(struct wpa_supplicant *wpa_s) 942 { 943 if (!wpa_s) 944 return; 945 946 const std::string ifname(wpa_s->ifname); 947 if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end()) 948 return; 949 950 const u8 *bssid = wpa_s->bssid; 951 if (is_zero_ether_addr(bssid)) { 952 bssid = wpa_s->pending_bssid; 953 } 954 callWithEachStaIfaceCallback( 955 wpa_s->ifname, 956 std::bind( 957 &ISupplicantStaIfaceCallback::onAuthenticationTimeout, 958 std::placeholders::_1, bssid)); 959 } 960 961 void HidlManager::notifyBssidChanged(struct wpa_supplicant *wpa_s) 962 { 963 if (!wpa_s) 964 return; 965 966 const std::string ifname(wpa_s->ifname); 967 if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end()) 968 return; 969 970 // wpa_supplicant does not explicitly give us the reason for bssid 971 // change, but we figure that out from what is set out of |wpa_s->bssid| 972 // & |wpa_s->pending_bssid|. 973 const u8 *bssid; 974 ISupplicantStaIfaceCallback::BssidChangeReason reason; 975 if (is_zero_ether_addr(wpa_s->bssid) && 976 !is_zero_ether_addr(wpa_s->pending_bssid)) { 977 bssid = wpa_s->pending_bssid; 978 reason = 979 ISupplicantStaIfaceCallback::BssidChangeReason::ASSOC_START; 980 } else if ( 981 !is_zero_ether_addr(wpa_s->bssid) && 982 is_zero_ether_addr(wpa_s->pending_bssid)) { 983 bssid = wpa_s->bssid; 984 reason = ISupplicantStaIfaceCallback::BssidChangeReason:: 985 ASSOC_COMPLETE; 986 } else if ( 987 is_zero_ether_addr(wpa_s->bssid) && 988 is_zero_ether_addr(wpa_s->pending_bssid)) { 989 bssid = wpa_s->pending_bssid; 990 reason = 991 ISupplicantStaIfaceCallback::BssidChangeReason::DISASSOC; 992 } else { 993 wpa_printf(MSG_ERROR, "Unknown bssid change reason"); 994 return; 995 } 996 997 callWithEachStaIfaceCallback( 998 wpa_s->ifname, std::bind( 999 &ISupplicantStaIfaceCallback::onBssidChanged, 1000 std::placeholders::_1, reason, bssid)); 1001 } 1002 1003 void HidlManager::notifyWpsEventFail( 1004 struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error, 1005 uint16_t error_indication) 1006 { 1007 if (!wpa_s || !peer_macaddr) 1008 return; 1009 1010 if (sta_iface_object_map_.find(wpa_s->ifname) == 1011 sta_iface_object_map_.end()) 1012 return; 1013 1014 callWithEachStaIfaceCallback( 1015 wpa_s->ifname, 1016 std::bind( 1017 &ISupplicantStaIfaceCallback::onWpsEventFail, 1018 std::placeholders::_1, peer_macaddr, 1019 static_cast<ISupplicantStaIfaceCallback::WpsConfigError>( 1020 config_error), 1021 static_cast<ISupplicantStaIfaceCallback::WpsErrorIndication>( 1022 error_indication))); 1023 } 1024 1025 void HidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s) 1026 { 1027 if (!wpa_s) 1028 return; 1029 1030 if (sta_iface_object_map_.find(wpa_s->ifname) == 1031 sta_iface_object_map_.end()) 1032 return; 1033 1034 callWithEachStaIfaceCallback( 1035 wpa_s->ifname, std::bind( 1036 &ISupplicantStaIfaceCallback::onWpsEventSuccess, 1037 std::placeholders::_1)); 1038 } 1039 1040 void HidlManager::notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s) 1041 { 1042 if (!wpa_s) 1043 return; 1044 1045 if (sta_iface_object_map_.find(wpa_s->ifname) == 1046 sta_iface_object_map_.end()) 1047 return; 1048 1049 callWithEachStaIfaceCallback( 1050 wpa_s->ifname, 1051 std::bind( 1052 &ISupplicantStaIfaceCallback::onWpsEventPbcOverlap, 1053 std::placeholders::_1)); 1054 } 1055 1056 void HidlManager::notifyP2pDeviceFound( 1057 struct wpa_supplicant *wpa_s, const u8 *addr, 1058 const struct p2p_peer_info *info, const u8 *peer_wfd_device_info, 1059 u8 peer_wfd_device_info_len) 1060 { 1061 if (!wpa_s || !addr || !info) 1062 return; 1063 1064 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1065 p2p_iface_object_map_.end()) 1066 return; 1067 1068 std::array<uint8_t, kWfdDeviceInfoLen> hidl_peer_wfd_device_info{}; 1069 if (peer_wfd_device_info) { 1070 if (peer_wfd_device_info_len != kWfdDeviceInfoLen) { 1071 wpa_printf( 1072 MSG_ERROR, "Unexpected WFD device info len: %d", 1073 peer_wfd_device_info_len); 1074 } else { 1075 os_memcpy( 1076 hidl_peer_wfd_device_info.data(), 1077 peer_wfd_device_info, kWfdDeviceInfoLen); 1078 } 1079 } 1080 1081 callWithEachP2pIfaceCallback( 1082 wpa_s->ifname, 1083 std::bind( 1084 &ISupplicantP2pIfaceCallback::onDeviceFound, 1085 std::placeholders::_1, addr, info->p2p_device_addr, 1086 info->pri_dev_type, info->device_name, info->config_methods, 1087 info->dev_capab, info->group_capab, hidl_peer_wfd_device_info)); 1088 } 1089 1090 void HidlManager::notifyP2pDeviceLost( 1091 struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr) 1092 { 1093 if (!wpa_s || !p2p_device_addr) 1094 return; 1095 1096 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1097 p2p_iface_object_map_.end()) 1098 return; 1099 1100 callWithEachP2pIfaceCallback( 1101 wpa_s->ifname, std::bind( 1102 &ISupplicantP2pIfaceCallback::onDeviceLost, 1103 std::placeholders::_1, p2p_device_addr)); 1104 } 1105 1106 void HidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s) 1107 { 1108 if (!wpa_s) 1109 return; 1110 1111 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1112 p2p_iface_object_map_.end()) 1113 return; 1114 1115 callWithEachP2pIfaceCallback( 1116 wpa_s->ifname, std::bind( 1117 &ISupplicantP2pIfaceCallback::onFindStopped, 1118 std::placeholders::_1)); 1119 } 1120 1121 void HidlManager::notifyP2pGoNegReq( 1122 struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id, 1123 u8 /* go_intent */) 1124 { 1125 if (!wpa_s || !src_addr) 1126 return; 1127 1128 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1129 p2p_iface_object_map_.end()) 1130 return; 1131 1132 callWithEachP2pIfaceCallback( 1133 wpa_s->ifname, 1134 std::bind( 1135 &ISupplicantP2pIfaceCallback::onGoNegotiationRequest, 1136 std::placeholders::_1, src_addr, 1137 static_cast<ISupplicantP2pIfaceCallback::WpsDevPasswordId>( 1138 dev_passwd_id))); 1139 } 1140 1141 void HidlManager::notifyP2pGoNegCompleted( 1142 struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res) 1143 { 1144 if (!wpa_s || !res) 1145 return; 1146 1147 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1148 p2p_iface_object_map_.end()) 1149 return; 1150 1151 callWithEachP2pIfaceCallback( 1152 wpa_s->ifname, 1153 std::bind( 1154 &ISupplicantP2pIfaceCallback::onGoNegotiationCompleted, 1155 std::placeholders::_1, 1156 static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>( 1157 res->status))); 1158 } 1159 1160 void HidlManager::notifyP2pGroupFormationFailure( 1161 struct wpa_supplicant *wpa_s, const char *reason) 1162 { 1163 if (!wpa_s || !reason) 1164 return; 1165 1166 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1167 p2p_iface_object_map_.end()) 1168 return; 1169 1170 callWithEachP2pIfaceCallback( 1171 wpa_s->ifname, 1172 std::bind( 1173 &ISupplicantP2pIfaceCallback::onGroupFormationFailure, 1174 std::placeholders::_1, reason)); 1175 } 1176 1177 void HidlManager::notifyP2pGroupStarted( 1178 struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid, int persistent, int client) 1179 { 1180 if (!wpa_group_s || !wpa_group_s->parent || !ssid) 1181 return; 1182 1183 // For group notifications, need to use the parent iface for callbacks. 1184 struct wpa_supplicant *wpa_s = wpa_group_s->parent; 1185 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1186 p2p_iface_object_map_.end()) 1187 return; 1188 1189 uint32_t hidl_freq = wpa_group_s->current_bss 1190 ? wpa_group_s->current_bss->freq 1191 : wpa_group_s->assoc_freq; 1192 std::array<uint8_t, 32> hidl_psk; 1193 if (ssid->psk_set) { 1194 os_memcpy(hidl_psk.data(), ssid->psk, 32); 1195 } 1196 bool hidl_is_go = (client == 0 ? true : false); 1197 bool hidl_is_persistent = (persistent == 1 ? true : false); 1198 1199 callWithEachP2pIfaceCallback( 1200 wpa_s->ifname, 1201 std::bind( 1202 &ISupplicantP2pIfaceCallback::onGroupStarted, 1203 std::placeholders::_1, wpa_group_s->ifname, hidl_is_go, 1204 std::vector<uint8_t>{ssid->ssid, ssid->ssid + ssid->ssid_len}, 1205 hidl_freq, hidl_psk, ssid->passphrase, wpa_group_s->go_dev_addr, 1206 hidl_is_persistent)); 1207 } 1208 1209 void HidlManager::notifyP2pGroupRemoved( 1210 struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid, 1211 const char *role) 1212 { 1213 if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role) 1214 return; 1215 1216 // For group notifications, need to use the parent iface for callbacks. 1217 struct wpa_supplicant *wpa_s = wpa_group_s->parent; 1218 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1219 p2p_iface_object_map_.end()) 1220 return; 1221 1222 bool hidl_is_go = (std::string(role) == "GO"); 1223 1224 callWithEachP2pIfaceCallback( 1225 wpa_s->ifname, 1226 std::bind( 1227 &ISupplicantP2pIfaceCallback::onGroupRemoved, 1228 std::placeholders::_1, wpa_group_s->ifname, hidl_is_go)); 1229 } 1230 1231 void HidlManager::notifyP2pInvitationReceived( 1232 struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr, 1233 const u8 *bssid, int id, int op_freq) 1234 { 1235 if (!wpa_s || !sa || !go_dev_addr || !bssid) 1236 return; 1237 1238 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1239 p2p_iface_object_map_.end()) 1240 return; 1241 1242 SupplicantNetworkId hidl_network_id; 1243 if (id < 0) { 1244 hidl_network_id = UINT32_MAX; 1245 } 1246 hidl_network_id = id; 1247 1248 callWithEachP2pIfaceCallback( 1249 wpa_s->ifname, 1250 std::bind( 1251 &ISupplicantP2pIfaceCallback::onInvitationReceived, 1252 std::placeholders::_1, sa, go_dev_addr, bssid, hidl_network_id, 1253 op_freq)); 1254 } 1255 1256 void HidlManager::notifyP2pInvitationResult( 1257 struct wpa_supplicant *wpa_s, int status, const u8 *bssid) 1258 { 1259 if (!wpa_s || !bssid) 1260 return; 1261 1262 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1263 p2p_iface_object_map_.end()) 1264 return; 1265 1266 callWithEachP2pIfaceCallback( 1267 wpa_s->ifname, 1268 std::bind( 1269 &ISupplicantP2pIfaceCallback::onInvitationResult, 1270 std::placeholders::_1, bssid, 1271 static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>( 1272 status))); 1273 } 1274 1275 void HidlManager::notifyP2pProvisionDiscovery( 1276 struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request, 1277 enum p2p_prov_disc_status status, u16 config_methods, 1278 unsigned int generated_pin) 1279 { 1280 if (!wpa_s || !dev_addr) 1281 return; 1282 1283 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1284 p2p_iface_object_map_.end()) 1285 return; 1286 1287 std::string hidl_generated_pin; 1288 if (generated_pin > 0) { 1289 hidl_generated_pin = 1290 misc_utils::convertWpsPinToString(generated_pin); 1291 } 1292 bool hidl_is_request = (request == 1 ? true : false); 1293 1294 callWithEachP2pIfaceCallback( 1295 wpa_s->ifname, 1296 std::bind( 1297 &ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted, 1298 std::placeholders::_1, dev_addr, hidl_is_request, 1299 static_cast<ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode>( 1300 status), 1301 config_methods, hidl_generated_pin)); 1302 } 1303 1304 void HidlManager::notifyP2pSdResponse( 1305 struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic, 1306 const u8 *tlvs, size_t tlvs_len) 1307 { 1308 if (!wpa_s || !sa || !tlvs) 1309 return; 1310 1311 if (p2p_iface_object_map_.find(wpa_s->ifname) == 1312 p2p_iface_object_map_.end()) 1313 return; 1314 1315 callWithEachP2pIfaceCallback( 1316 wpa_s->ifname, 1317 std::bind( 1318 &ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse, 1319 std::placeholders::_1, sa, update_indic, 1320 std::vector<uint8_t>{tlvs, tlvs + tlvs_len})); 1321 } 1322 1323 void HidlManager::notifyApStaAuthorized( 1324 struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr) 1325 { 1326 if (!wpa_s || !wpa_s->parent || !sta) 1327 return; 1328 if (p2p_iface_object_map_.find(wpa_s->parent->ifname) == 1329 p2p_iface_object_map_.end()) 1330 return; 1331 callWithEachP2pIfaceCallback( 1332 wpa_s->parent->ifname, std::bind( 1333 &ISupplicantP2pIfaceCallback::onStaAuthorized, 1334 std::placeholders::_1, sta, p2p_dev_addr ? p2p_dev_addr : kZeroBssid)); 1335 } 1336 1337 void HidlManager::notifyApStaDeauthorized( 1338 struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr) 1339 { 1340 if (!wpa_s || !wpa_s->parent || !sta) 1341 return; 1342 if (p2p_iface_object_map_.find(wpa_s->parent->ifname) == 1343 p2p_iface_object_map_.end()) 1344 return; 1345 1346 callWithEachP2pIfaceCallback( 1347 wpa_s->parent->ifname, std::bind( 1348 &ISupplicantP2pIfaceCallback::onStaDeauthorized, 1349 std::placeholders::_1, sta, p2p_dev_addr ? p2p_dev_addr : kZeroBssid)); 1350 } 1351 1352 void HidlManager::notifyExtRadioWorkStart( 1353 struct wpa_supplicant *wpa_s, uint32_t id) 1354 { 1355 if (!wpa_s) 1356 return; 1357 1358 if (sta_iface_object_map_.find(wpa_s->ifname) == 1359 sta_iface_object_map_.end()) 1360 return; 1361 1362 callWithEachStaIfaceCallback( 1363 wpa_s->ifname, 1364 std::bind( 1365 &ISupplicantStaIfaceCallback::onExtRadioWorkStart, 1366 std::placeholders::_1, id)); 1367 } 1368 1369 void HidlManager::notifyExtRadioWorkTimeout( 1370 struct wpa_supplicant *wpa_s, uint32_t id) 1371 { 1372 if (!wpa_s) 1373 return; 1374 1375 if (sta_iface_object_map_.find(wpa_s->ifname) == 1376 sta_iface_object_map_.end()) 1377 return; 1378 1379 callWithEachStaIfaceCallback( 1380 wpa_s->ifname, 1381 std::bind( 1382 &ISupplicantStaIfaceCallback::onExtRadioWorkTimeout, 1383 std::placeholders::_1, id)); 1384 } 1385 1386 /** 1387 * Retrieve the |ISupplicantP2pIface| hidl object reference using the provided 1388 * ifname. 1389 * 1390 * @param ifname Name of the corresponding interface. 1391 * @param iface_object Hidl reference corresponding to the iface. 1392 * 1393 * @return 0 on success, 1 on failure. 1394 */ 1395 int HidlManager::getP2pIfaceHidlObjectByIfname( 1396 const std::string &ifname, android::sp<ISupplicantP2pIface> *iface_object) 1397 { 1398 if (ifname.empty() || !iface_object) 1399 return 1; 1400 1401 auto iface_object_iter = p2p_iface_object_map_.find(ifname); 1402 if (iface_object_iter == p2p_iface_object_map_.end()) 1403 return 1; 1404 1405 *iface_object = iface_object_iter->second; 1406 return 0; 1407 } 1408 1409 /** 1410 * Retrieve the |ISupplicantStaIface| hidl object reference using the provided 1411 * ifname. 1412 * 1413 * @param ifname Name of the corresponding interface. 1414 * @param iface_object Hidl reference corresponding to the iface. 1415 * 1416 * @return 0 on success, 1 on failure. 1417 */ 1418 int HidlManager::getStaIfaceHidlObjectByIfname( 1419 const std::string &ifname, android::sp<ISupplicantStaIface> *iface_object) 1420 { 1421 if (ifname.empty() || !iface_object) 1422 return 1; 1423 1424 auto iface_object_iter = sta_iface_object_map_.find(ifname); 1425 if (iface_object_iter == sta_iface_object_map_.end()) 1426 return 1; 1427 1428 *iface_object = iface_object_iter->second; 1429 return 0; 1430 } 1431 1432 /** 1433 * Retrieve the |ISupplicantP2pNetwork| hidl object reference using the provided 1434 * ifname and network_id. 1435 * 1436 * @param ifname Name of the corresponding interface. 1437 * @param network_id ID of the corresponding network. 1438 * @param network_object Hidl reference corresponding to the network. 1439 * 1440 * @return 0 on success, 1 on failure. 1441 */ 1442 int HidlManager::getP2pNetworkHidlObjectByIfnameAndNetworkId( 1443 const std::string &ifname, int network_id, 1444 android::sp<ISupplicantP2pNetwork> *network_object) 1445 { 1446 if (ifname.empty() || network_id < 0 || !network_object) 1447 return 1; 1448 1449 // Generate the key to be used to lookup the network. 1450 const std::string network_key = 1451 getNetworkObjectMapKey(ifname, network_id); 1452 1453 auto network_object_iter = p2p_network_object_map_.find(network_key); 1454 if (network_object_iter == p2p_network_object_map_.end()) 1455 return 1; 1456 1457 *network_object = network_object_iter->second; 1458 return 0; 1459 } 1460 1461 /** 1462 * Retrieve the |ISupplicantStaNetwork| hidl object reference using the provided 1463 * ifname and network_id. 1464 * 1465 * @param ifname Name of the corresponding interface. 1466 * @param network_id ID of the corresponding network. 1467 * @param network_object Hidl reference corresponding to the network. 1468 * 1469 * @return 0 on success, 1 on failure. 1470 */ 1471 int HidlManager::getStaNetworkHidlObjectByIfnameAndNetworkId( 1472 const std::string &ifname, int network_id, 1473 android::sp<ISupplicantStaNetwork> *network_object) 1474 { 1475 if (ifname.empty() || network_id < 0 || !network_object) 1476 return 1; 1477 1478 // Generate the key to be used to lookup the network. 1479 const std::string network_key = 1480 getNetworkObjectMapKey(ifname, network_id); 1481 1482 auto network_object_iter = sta_network_object_map_.find(network_key); 1483 if (network_object_iter == sta_network_object_map_.end()) 1484 return 1; 1485 1486 *network_object = network_object_iter->second; 1487 return 0; 1488 } 1489 1490 /** 1491 * Add a new |ISupplicantCallback| hidl object reference to our 1492 * global callback list. 1493 * 1494 * @param callback Hidl reference of the |ISupplicantCallback| object. 1495 * 1496 * @return 0 on success, 1 on failure. 1497 */ 1498 int HidlManager::addSupplicantCallbackHidlObject( 1499 const android::sp<ISupplicantCallback> &callback) 1500 { 1501 // Register for death notification before we add it to our list. 1502 auto on_hidl_died_fctor = std::bind( 1503 &HidlManager::removeSupplicantCallbackHidlObject, this, 1504 std::placeholders::_1); 1505 return registerForDeathAndAddCallbackHidlObjectToList< 1506 ISupplicantCallback>( 1507 callback, on_hidl_died_fctor, supplicant_callbacks_); 1508 } 1509 1510 /** 1511 * Add a new iface callback hidl object reference to our 1512 * interface callback list. 1513 * 1514 * @param ifname Name of the corresponding interface. 1515 * @param callback Hidl reference of the callback object. 1516 * 1517 * @return 0 on success, 1 on failure. 1518 */ 1519 int HidlManager::addP2pIfaceCallbackHidlObject( 1520 const std::string &ifname, 1521 const android::sp<ISupplicantP2pIfaceCallback> &callback) 1522 { 1523 const std::function<void( 1524 const android::sp<ISupplicantP2pIfaceCallback> &)> 1525 on_hidl_died_fctor = std::bind( 1526 &HidlManager::removeP2pIfaceCallbackHidlObject, this, ifname, 1527 std::placeholders::_1); 1528 return addIfaceCallbackHidlObjectToMap( 1529 ifname, callback, on_hidl_died_fctor, p2p_iface_callbacks_map_); 1530 } 1531 1532 /** 1533 * Add a new iface callback hidl object reference to our 1534 * interface callback list. 1535 * 1536 * @param ifname Name of the corresponding interface. 1537 * @param callback Hidl reference of the callback object. 1538 * 1539 * @return 0 on success, 1 on failure. 1540 */ 1541 int HidlManager::addStaIfaceCallbackHidlObject( 1542 const std::string &ifname, 1543 const android::sp<ISupplicantStaIfaceCallback> &callback) 1544 { 1545 const std::function<void( 1546 const android::sp<ISupplicantStaIfaceCallback> &)> 1547 on_hidl_died_fctor = std::bind( 1548 &HidlManager::removeStaIfaceCallbackHidlObject, this, ifname, 1549 std::placeholders::_1); 1550 return addIfaceCallbackHidlObjectToMap( 1551 ifname, callback, on_hidl_died_fctor, sta_iface_callbacks_map_); 1552 } 1553 1554 /** 1555 * Add a new network callback hidl object reference to our network callback 1556 * list. 1557 * 1558 * @param ifname Name of the corresponding interface. 1559 * @param network_id ID of the corresponding network. 1560 * @param callback Hidl reference of the callback object. 1561 * 1562 * @return 0 on success, 1 on failure. 1563 */ 1564 int HidlManager::addP2pNetworkCallbackHidlObject( 1565 const std::string &ifname, int network_id, 1566 const android::sp<ISupplicantP2pNetworkCallback> &callback) 1567 { 1568 const std::function<void( 1569 const android::sp<ISupplicantP2pNetworkCallback> &)> 1570 on_hidl_died_fctor = std::bind( 1571 &HidlManager::removeP2pNetworkCallbackHidlObject, this, ifname, 1572 network_id, std::placeholders::_1); 1573 return addNetworkCallbackHidlObjectToMap( 1574 ifname, network_id, callback, on_hidl_died_fctor, 1575 p2p_network_callbacks_map_); 1576 } 1577 1578 /** 1579 * Add a new network callback hidl object reference to our network callback 1580 * list. 1581 * 1582 * @param ifname Name of the corresponding interface. 1583 * @param network_id ID of the corresponding network. 1584 * @param callback Hidl reference of the callback object. 1585 * 1586 * @return 0 on success, 1 on failure. 1587 */ 1588 int HidlManager::addStaNetworkCallbackHidlObject( 1589 const std::string &ifname, int network_id, 1590 const android::sp<ISupplicantStaNetworkCallback> &callback) 1591 { 1592 const std::function<void( 1593 const android::sp<ISupplicantStaNetworkCallback> &)> 1594 on_hidl_died_fctor = std::bind( 1595 &HidlManager::removeStaNetworkCallbackHidlObject, this, ifname, 1596 network_id, std::placeholders::_1); 1597 return addNetworkCallbackHidlObjectToMap( 1598 ifname, network_id, callback, on_hidl_died_fctor, 1599 sta_network_callbacks_map_); 1600 } 1601 1602 /** 1603 * Removes the provided |ISupplicantCallback| hidl object reference 1604 * from our global callback list. 1605 * 1606 * @param callback Hidl reference of the |ISupplicantCallback| object. 1607 */ 1608 void HidlManager::removeSupplicantCallbackHidlObject( 1609 const android::sp<ISupplicantCallback> &callback) 1610 { 1611 supplicant_callbacks_.erase( 1612 std::remove( 1613 supplicant_callbacks_.begin(), supplicant_callbacks_.end(), 1614 callback), 1615 supplicant_callbacks_.end()); 1616 } 1617 1618 /** 1619 * Removes the provided iface callback hidl object reference from 1620 * our interface callback list. 1621 * 1622 * @param ifname Name of the corresponding interface. 1623 * @param callback Hidl reference of the callback object. 1624 */ 1625 void HidlManager::removeP2pIfaceCallbackHidlObject( 1626 const std::string &ifname, 1627 const android::sp<ISupplicantP2pIfaceCallback> &callback) 1628 { 1629 return removeIfaceCallbackHidlObjectFromMap( 1630 ifname, callback, p2p_iface_callbacks_map_); 1631 } 1632 1633 /** 1634 * Removes the provided iface callback hidl object reference from 1635 * our interface callback list. 1636 * 1637 * @param ifname Name of the corresponding interface. 1638 * @param callback Hidl reference of the callback object. 1639 */ 1640 void HidlManager::removeStaIfaceCallbackHidlObject( 1641 const std::string &ifname, 1642 const android::sp<ISupplicantStaIfaceCallback> &callback) 1643 { 1644 return removeIfaceCallbackHidlObjectFromMap( 1645 ifname, callback, sta_iface_callbacks_map_); 1646 } 1647 1648 /** 1649 * Removes the provided network callback hidl object reference from 1650 * our network callback list. 1651 * 1652 * @param ifname Name of the corresponding interface. 1653 * @param network_id ID of the corresponding network. 1654 * @param callback Hidl reference of the callback object. 1655 */ 1656 void HidlManager::removeP2pNetworkCallbackHidlObject( 1657 const std::string &ifname, int network_id, 1658 const android::sp<ISupplicantP2pNetworkCallback> &callback) 1659 { 1660 return removeNetworkCallbackHidlObjectFromMap( 1661 ifname, network_id, callback, p2p_network_callbacks_map_); 1662 } 1663 1664 /** 1665 * Removes the provided network callback hidl object reference from 1666 * our network callback list. 1667 * 1668 * @param ifname Name of the corresponding interface. 1669 * @param network_id ID of the corresponding network. 1670 * @param callback Hidl reference of the callback object. 1671 */ 1672 void HidlManager::removeStaNetworkCallbackHidlObject( 1673 const std::string &ifname, int network_id, 1674 const android::sp<ISupplicantStaNetworkCallback> &callback) 1675 { 1676 return removeNetworkCallbackHidlObjectFromMap( 1677 ifname, network_id, callback, sta_network_callbacks_map_); 1678 } 1679 1680 /** 1681 * Helper function to invoke the provided callback method on all the 1682 * registered |ISupplicantCallback| callback hidl objects. 1683 * 1684 * @param method Pointer to the required hidl method from 1685 * |ISupplicantCallback|. 1686 */ 1687 void HidlManager::callWithEachSupplicantCallback( 1688 const std::function<Return<void>(android::sp<ISupplicantCallback>)> &method) 1689 { 1690 for (const auto &callback : supplicant_callbacks_) { 1691 if (!method(callback).isOk()) { 1692 wpa_printf(MSG_ERROR, "Failed to invoke HIDL callback"); 1693 } 1694 } 1695 } 1696 1697 /** 1698 * Helper fucntion to invoke the provided callback method on all the 1699 * registered iface callback hidl objects for the specified 1700 * |ifname|. 1701 * 1702 * @param ifname Name of the corresponding interface. 1703 * @param method Pointer to the required hidl method from 1704 * |ISupplicantIfaceCallback|. 1705 */ 1706 void HidlManager::callWithEachP2pIfaceCallback( 1707 const std::string &ifname, 1708 const std::function<Return<void>(android::sp<ISupplicantP2pIfaceCallback>)> 1709 &method) 1710 { 1711 callWithEachIfaceCallback(ifname, method, p2p_iface_callbacks_map_); 1712 } 1713 1714 /** 1715 * Helper fucntion to invoke the provided callback method on all the 1716 * registered iface callback hidl objects for the specified 1717 * |ifname|. 1718 * 1719 * @param ifname Name of the corresponding interface. 1720 * @param method Pointer to the required hidl method from 1721 * |ISupplicantIfaceCallback|. 1722 */ 1723 void HidlManager::callWithEachStaIfaceCallback( 1724 const std::string &ifname, 1725 const std::function<Return<void>(android::sp<ISupplicantStaIfaceCallback>)> 1726 &method) 1727 { 1728 callWithEachIfaceCallback(ifname, method, sta_iface_callbacks_map_); 1729 } 1730 1731 /** 1732 * Helper function to invoke the provided callback method on all the 1733 * registered network callback hidl objects for the specified 1734 * |ifname| & |network_id|. 1735 * 1736 * @param ifname Name of the corresponding interface. 1737 * @param network_id ID of the corresponding network. 1738 * @param method Pointer to the required hidl method from 1739 * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| . 1740 */ 1741 void HidlManager::callWithEachP2pNetworkCallback( 1742 const std::string &ifname, int network_id, 1743 const std::function< 1744 Return<void>(android::sp<ISupplicantP2pNetworkCallback>)> &method) 1745 { 1746 callWithEachNetworkCallback( 1747 ifname, network_id, method, p2p_network_callbacks_map_); 1748 } 1749 1750 /** 1751 * Helper function to invoke the provided callback method on all the 1752 * registered network callback hidl objects for the specified 1753 * |ifname| & |network_id|. 1754 * 1755 * @param ifname Name of the corresponding interface. 1756 * @param network_id ID of the corresponding network. 1757 * @param method Pointer to the required hidl method from 1758 * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| . 1759 */ 1760 void HidlManager::callWithEachStaNetworkCallback( 1761 const std::string &ifname, int network_id, 1762 const std::function< 1763 Return<void>(android::sp<ISupplicantStaNetworkCallback>)> &method) 1764 { 1765 callWithEachNetworkCallback( 1766 ifname, network_id, method, sta_network_callbacks_map_); 1767 } 1768 } // namespace implementation 1769 } // namespace V1_0 1770 } // namespace wifi 1771 } // namespace supplicant 1772 } // namespace hardware 1773 } // namespace android 1774