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