1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "net/netlink_manager.h" 18 19 #include <string> 20 #include <vector> 21 22 #include <linux/netlink.h> 23 #include <linux/nl80211.h> 24 #include <poll.h> 25 #include <sys/socket.h> 26 27 #include <android-base/logging.h> 28 #include <utils/Timers.h> 29 30 #include "net/mlme_event.h" 31 #include "net/mlme_event_handler.h" 32 #include "net/nl80211_attribute.h" 33 #include "net/nl80211_packet.h" 34 35 using android::base::unique_fd; 36 using std::placeholders::_1; 37 using std::string; 38 using std::unique_ptr; 39 using std::vector; 40 41 namespace android { 42 namespace wificond { 43 44 namespace { 45 46 // netlink.h suggests NLMSG_GOODSIZE to be at most 8192 bytes. 47 constexpr int kReceiveBufferSize = 8 * 1024; 48 constexpr uint32_t kBroadcastSequenceNumber = 0; 49 constexpr int kMaximumNetlinkMessageWaitMilliSeconds = 300; 50 uint8_t ReceiveBuffer[kReceiveBufferSize]; 51 52 void AppendPacket(vector<unique_ptr<const NL80211Packet>>* vec, 53 unique_ptr<const NL80211Packet> packet) { 54 vec->push_back(std::move(packet)); 55 } 56 57 } 58 59 NetlinkManager::NetlinkManager(EventLoop* event_loop) 60 : started_(false), 61 event_loop_(event_loop), 62 sequence_number_(0) { 63 } 64 65 NetlinkManager::~NetlinkManager() { 66 } 67 68 uint32_t NetlinkManager::GetSequenceNumber() { 69 if (++sequence_number_ == kBroadcastSequenceNumber) { 70 ++sequence_number_; 71 } 72 return sequence_number_; 73 } 74 75 void NetlinkManager::ReceivePacketAndRunHandler(int fd) { 76 ssize_t len = read(fd, ReceiveBuffer, kReceiveBufferSize); 77 if (len == -1) { 78 LOG(ERROR) << "Failed to read packet from buffer"; 79 return; 80 } 81 if (len == 0) { 82 return; 83 } 84 // There might be multiple message in one datagram payload. 85 uint8_t* ptr = ReceiveBuffer; 86 while (ptr < ReceiveBuffer + len) { 87 // peek at the header. 88 if (ptr + sizeof(nlmsghdr) > ReceiveBuffer + len) { 89 LOG(ERROR) << "payload is broken."; 90 return; 91 } 92 const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(ptr); 93 unique_ptr<NL80211Packet> packet( 94 new NL80211Packet(vector<uint8_t>(ptr, ptr + nl_header->nlmsg_len))); 95 ptr += nl_header->nlmsg_len; 96 if (!packet->IsValid()) { 97 LOG(ERROR) << "Receive invalid packet"; 98 return; 99 } 100 // Some document says message from kernel should have port id equal 0. 101 // However in practice this is not always true so we don't check that. 102 103 uint32_t sequence_number = packet->GetMessageSequence(); 104 105 // Handle multicasts. 106 if (sequence_number == kBroadcastSequenceNumber) { 107 BroadcastHandler(std::move(packet)); 108 continue; 109 } 110 111 auto itr = message_handlers_.find(sequence_number); 112 // There is no handler for this sequence number. 113 if (itr == message_handlers_.end()) { 114 LOG(WARNING) << "No handler for message: " << sequence_number; 115 return; 116 } 117 // A multipart message is terminated by NLMSG_DONE. 118 // In this case we don't need to run the handler. 119 // NLMSG_NOOP means no operation, message must be discarded. 120 uint32_t message_type = packet->GetMessageType(); 121 if (message_type == NLMSG_DONE || message_type == NLMSG_NOOP) { 122 message_handlers_.erase(itr); 123 return; 124 } 125 if (message_type == NLMSG_OVERRUN) { 126 LOG(ERROR) << "Get message overrun notification"; 127 message_handlers_.erase(itr); 128 return; 129 } 130 131 // In case we receive a NLMSG_ERROR message: 132 // NLMSG_ERROR could be either an error or an ACK. 133 // It is an ACK message only when error code field is set to 0. 134 // An ACK could be return when we explicitly request that with NLM_F_ACK. 135 // An ERROR could be received on NLM_F_ACK or other failure cases. 136 // We should still run handler in this case, leaving it for the caller 137 // to decide what to do with the packet. 138 139 bool is_multi = packet->IsMulti(); 140 // Run the handler. 141 itr->second(std::move(packet)); 142 // Remove handler after processing. 143 if (!is_multi) { 144 message_handlers_.erase(itr); 145 } 146 } 147 } 148 149 void NetlinkManager::OnNewFamily(unique_ptr<const NL80211Packet> packet) { 150 if (packet->GetMessageType() != GENL_ID_CTRL) { 151 LOG(ERROR) << "Wrong message type for new family message"; 152 return; 153 } 154 if (packet->GetCommand() != CTRL_CMD_NEWFAMILY) { 155 LOG(ERROR) << "Wrong command for new family message"; 156 return; 157 } 158 uint16_t family_id; 159 if (!packet->GetAttributeValue(CTRL_ATTR_FAMILY_ID, &family_id)) { 160 LOG(ERROR) << "Failed to get family id"; 161 return; 162 } 163 string family_name; 164 if (!packet->GetAttributeValue(CTRL_ATTR_FAMILY_NAME, &family_name)) { 165 LOG(ERROR) << "Failed to get family name"; 166 return; 167 } 168 if (family_name != NL80211_GENL_NAME) { 169 LOG(WARNING) << "Ignoring none nl80211 netlink families"; 170 } 171 MessageType nl80211_type(family_id); 172 message_types_[family_name] = nl80211_type; 173 // Exract multicast groups. 174 NL80211NestedAttr multicast_groups(0); 175 if (packet->GetAttribute(CTRL_ATTR_MCAST_GROUPS, &multicast_groups)) { 176 vector<NL80211NestedAttr> groups; 177 if (!multicast_groups.GetListOfNestedAttributes(&groups)) { 178 return; 179 } 180 for (auto& group : groups) { 181 string group_name; 182 uint32_t group_id; 183 if (!group.GetAttributeValue(CTRL_ATTR_MCAST_GRP_NAME, &group_name)) { 184 LOG(ERROR) << "Failed to get group name"; 185 } 186 if (!group.GetAttributeValue(CTRL_ATTR_MCAST_GRP_ID, &group_id)) { 187 LOG(ERROR) << "Failed to get group id"; 188 } 189 message_types_[family_name].groups[group_name] = group_id; 190 } 191 } 192 } 193 194 bool NetlinkManager::Start() { 195 if (started_) { 196 LOG(DEBUG) << "NetlinkManager is already started"; 197 return true; 198 } 199 bool setup_rt = SetupSocket(&sync_netlink_fd_); 200 if (!setup_rt) { 201 LOG(ERROR) << "Failed to setup synchronous netlink socket"; 202 return false; 203 } 204 205 setup_rt = SetupSocket(&async_netlink_fd_); 206 if (!setup_rt) { 207 LOG(ERROR) << "Failed to setup asynchronous netlink socket"; 208 return false; 209 } 210 211 // Request family id for nl80211 messages. 212 if (!DiscoverFamilyId()) { 213 return false; 214 } 215 // Watch socket. 216 if (!WatchSocket(&async_netlink_fd_)) { 217 return false; 218 } 219 // Subscribe kernel NL80211 broadcast of regulatory changes. 220 if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_REG)) { 221 return false; 222 } 223 // Subscribe kernel NL80211 broadcast of scanning events. 224 if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_SCAN)) { 225 return false; 226 } 227 // Subscribe kernel NL80211 broadcast of MLME events. 228 if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_MLME)) { 229 return false; 230 } 231 232 started_ = true; 233 return true; 234 } 235 236 bool NetlinkManager::IsStarted() const { 237 return started_; 238 } 239 240 bool NetlinkManager::RegisterHandlerAndSendMessage( 241 const NL80211Packet& packet, 242 std::function<void(unique_ptr<const NL80211Packet>)> handler) { 243 if (packet.IsDump()) { 244 LOG(ERROR) << "Do not use asynchronous interface for dump request !"; 245 return false; 246 } 247 if (!SendMessageInternal(packet, async_netlink_fd_.get())) { 248 return false; 249 } 250 message_handlers_[packet.GetMessageSequence()] = handler; 251 return true; 252 } 253 254 bool NetlinkManager::SendMessageAndGetResponses( 255 const NL80211Packet& packet, 256 vector<unique_ptr<const NL80211Packet>>* response) { 257 if (!SendMessageInternal(packet, sync_netlink_fd_.get())) { 258 return false; 259 } 260 // Polling netlink socket, waiting for GetFamily reply. 261 struct pollfd netlink_output; 262 memset(&netlink_output, 0, sizeof(netlink_output)); 263 netlink_output.fd = sync_netlink_fd_.get(); 264 netlink_output.events = POLLIN; 265 266 uint32_t sequence = packet.GetMessageSequence(); 267 268 int time_remaining = kMaximumNetlinkMessageWaitMilliSeconds; 269 // Multipart messages may come with seperated datagrams, ending with a 270 // NLMSG_DONE message. 271 // ReceivePacketAndRunHandler() will remove the handler after receiving a 272 // NLMSG_DONE message. 273 message_handlers_[sequence] = std::bind(AppendPacket, response, _1); 274 275 while (time_remaining > 0 && 276 message_handlers_.find(sequence) != message_handlers_.end()) { 277 nsecs_t interval = systemTime(SYSTEM_TIME_MONOTONIC); 278 int poll_return = poll(&netlink_output, 279 1, 280 time_remaining); 281 282 if (poll_return == 0) { 283 LOG(ERROR) << "Failed to poll netlink fd: time out "; 284 message_handlers_.erase(sequence); 285 return false; 286 } else if (poll_return == -1) { 287 LOG(ERROR) << "Failed to poll netlink fd: " << strerror(errno); 288 message_handlers_.erase(sequence); 289 return false; 290 } 291 ReceivePacketAndRunHandler(sync_netlink_fd_.get()); 292 interval = systemTime(SYSTEM_TIME_MONOTONIC) - interval; 293 time_remaining -= static_cast<int>(ns2ms(interval)); 294 } 295 if (time_remaining <= 0) { 296 LOG(ERROR) << "Timeout waiting for netlink reply messages"; 297 message_handlers_.erase(sequence); 298 return false; 299 } 300 return true; 301 } 302 303 bool NetlinkManager::SendMessageAndGetSingleResponse( 304 const NL80211Packet& packet, 305 unique_ptr<const NL80211Packet>* response) { 306 unique_ptr<const NL80211Packet> response_or_error; 307 if (!SendMessageAndGetSingleResponseOrError(packet, &response_or_error)) { 308 return false; 309 } 310 if (response_or_error->GetMessageType() == NLMSG_ERROR) { 311 // We use ERROR because we are not expecting to receive a ACK here. 312 // In that case the caller should use |SendMessageAndGetAckOrError|. 313 LOG(ERROR) << "Received error message: " 314 << strerror(response_or_error->GetErrorCode()); 315 return false; 316 } 317 *response = std::move(response_or_error); 318 return true; 319 } 320 321 bool NetlinkManager::SendMessageAndGetSingleResponseOrError( 322 const NL80211Packet& packet, 323 unique_ptr<const NL80211Packet>* response) { 324 vector<unique_ptr<const NL80211Packet>> response_vec; 325 if (!SendMessageAndGetResponses(packet, &response_vec)) { 326 return false; 327 } 328 if (response_vec.size() != 1) { 329 LOG(ERROR) << "Unexpected response size: " << response_vec.size(); 330 return false; 331 } 332 333 *response = std::move(response_vec[0]); 334 return true; 335 } 336 337 bool NetlinkManager::SendMessageAndGetAckOrError(const NL80211Packet& packet, 338 int* error_code) { 339 unique_ptr<const NL80211Packet> response; 340 if (!SendMessageAndGetSingleResponseOrError(packet, &response)) { 341 return false; 342 } 343 uint16_t type = response->GetMessageType(); 344 if (type != NLMSG_ERROR) { 345 LOG(ERROR) << "Receive unexpected message type :" << type; 346 return false; 347 } 348 349 *error_code = response->GetErrorCode(); 350 return true; 351 } 352 353 bool NetlinkManager::SendMessageAndGetAck(const NL80211Packet& packet) { 354 int error_code; 355 if (!SendMessageAndGetAckOrError(packet, &error_code)) { 356 return false; 357 } 358 if (error_code != 0) { 359 LOG(ERROR) << "Received error messsage: " << strerror(error_code); 360 return false; 361 } 362 363 return true; 364 } 365 366 bool NetlinkManager::SendMessageInternal(const NL80211Packet& packet, int fd) { 367 const vector<uint8_t>& data = packet.GetConstData(); 368 ssize_t bytes_sent = 369 TEMP_FAILURE_RETRY(send(fd, data.data(), data.size(), 0)); 370 if (bytes_sent == -1) { 371 LOG(ERROR) << "Failed to send netlink message: " << strerror(errno); 372 return false; 373 } 374 return true; 375 } 376 377 bool NetlinkManager::SetupSocket(unique_fd* netlink_fd) { 378 struct sockaddr_nl nladdr; 379 380 memset(&nladdr, 0, sizeof(nladdr)); 381 nladdr.nl_family = AF_NETLINK; 382 383 netlink_fd->reset( 384 socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_GENERIC)); 385 if (netlink_fd->get() < 0) { 386 LOG(ERROR) << "Failed to create netlink socket: " << strerror(errno); 387 return false; 388 } 389 // Set maximum receive buffer size. 390 // Datagram which is larger than this size will be discarded. 391 if (setsockopt(netlink_fd->get(), 392 SOL_SOCKET, 393 SO_RCVBUFFORCE, 394 &kReceiveBufferSize, 395 sizeof(kReceiveBufferSize)) < 0) { 396 LOG(ERROR) << "Failed to set uevent socket SO_RCVBUFFORCE option: " << strerror(errno); 397 return false; 398 } 399 if (bind(netlink_fd->get(), 400 reinterpret_cast<struct sockaddr*>(&nladdr), 401 sizeof(nladdr)) < 0) { 402 LOG(ERROR) << "Failed to bind netlink socket: " << strerror(errno); 403 return false; 404 } 405 return true; 406 } 407 408 bool NetlinkManager::WatchSocket(unique_fd* netlink_fd) { 409 // Watch socket 410 bool watch_fd_rt = event_loop_->WatchFileDescriptor( 411 netlink_fd->get(), 412 EventLoop::kModeInput, 413 std::bind(&NetlinkManager::ReceivePacketAndRunHandler, this, _1)); 414 if (!watch_fd_rt) { 415 LOG(ERROR) << "Failed to watch fd: " << netlink_fd->get(); 416 return false; 417 } 418 return true; 419 } 420 421 uint16_t NetlinkManager::GetFamilyId() { 422 return message_types_[NL80211_GENL_NAME].family_id; 423 } 424 425 bool NetlinkManager::DiscoverFamilyId() { 426 NL80211Packet get_family_request(GENL_ID_CTRL, 427 CTRL_CMD_GETFAMILY, 428 GetSequenceNumber(), 429 getpid()); 430 NL80211Attr<string> family_name(CTRL_ATTR_FAMILY_NAME, NL80211_GENL_NAME); 431 get_family_request.AddAttribute(family_name); 432 unique_ptr<const NL80211Packet> response; 433 if (!SendMessageAndGetSingleResponse(get_family_request, &response)) { 434 LOG(ERROR) << "Failed to get NL80211 family info"; 435 return false; 436 } 437 OnNewFamily(std::move(response)); 438 if (message_types_.find(NL80211_GENL_NAME) == message_types_.end()) { 439 LOG(ERROR) << "Failed to get NL80211 family id"; 440 return false; 441 } 442 return true; 443 } 444 445 bool NetlinkManager::SubscribeToEvents(const string& group) { 446 auto groups = message_types_[NL80211_GENL_NAME].groups; 447 if (groups.find(group) == groups.end()) { 448 LOG(ERROR) << "Failed to subscribe: group " << group << " doesn't exist"; 449 return false; 450 } 451 uint32_t group_id = groups[group]; 452 int err = setsockopt(async_netlink_fd_.get(), 453 SOL_NETLINK, 454 NETLINK_ADD_MEMBERSHIP, 455 &group_id, 456 sizeof(group_id)); 457 if (err < 0) { 458 LOG(ERROR) << "Failed to setsockopt: " << strerror(errno); 459 return false; 460 } 461 return true; 462 } 463 464 void NetlinkManager::BroadcastHandler(unique_ptr<const NL80211Packet> packet) { 465 if (packet->GetMessageType() != GetFamilyId()) { 466 LOG(ERROR) << "Wrong family id for multicast message"; 467 return; 468 } 469 uint32_t command = packet->GetCommand(); 470 471 if (command == NL80211_CMD_NEW_SCAN_RESULTS || 472 // Scan was aborted, for unspecified reasons.partial scan results may be 473 // available. 474 command == NL80211_CMD_SCAN_ABORTED) { 475 OnScanResultsReady(std::move(packet)); 476 return; 477 } 478 479 if (command == NL80211_CMD_SCHED_SCAN_RESULTS || 480 command == NL80211_CMD_SCHED_SCAN_STOPPED) { 481 OnSchedScanResultsReady(std::move(packet)); 482 return; 483 } 484 485 486 // Driver which supports SME uses both NL80211_CMD_AUTHENTICATE and 487 // NL80211_CMD_ASSOCIATE, otherwise it uses NL80211_CMD_CONNECT 488 // to notify a combination of authentication and association processses. 489 // Currently we monitor CONNECT/ASSOCIATE/ROAM event for up-to-date 490 // frequency and bssid. 491 // TODO(nywang): Handle other MLME events, which help us track the 492 // connection state better. 493 if (command == NL80211_CMD_CONNECT || 494 command == NL80211_CMD_ASSOCIATE || 495 command == NL80211_CMD_ROAM || 496 command == NL80211_CMD_DISCONNECT || 497 command == NL80211_CMD_DISASSOCIATE) { 498 OnMlmeEvent(std::move(packet)); 499 return; 500 } 501 if (command == NL80211_CMD_REG_CHANGE) { 502 OnRegChangeEvent(std::move(packet)); 503 return; 504 } 505 // Station eventsFor AP mode. 506 if (command == NL80211_CMD_NEW_STATION || 507 command == NL80211_CMD_DEL_STATION) { 508 uint32_t if_index; 509 if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) { 510 LOG(WARNING) << "Failed to get interface index from station event"; 511 return; 512 } 513 const auto handler = on_station_event_handler_.find(if_index); 514 if (handler != on_station_event_handler_.end()) { 515 vector<uint8_t> mac_address; 516 if (!packet->GetAttributeValue(NL80211_ATTR_MAC, &mac_address)) { 517 LOG(WARNING) << "Failed to get mac address from station event"; 518 return; 519 } 520 if (command == NL80211_CMD_NEW_STATION) { 521 handler->second(NEW_STATION, mac_address); 522 } else { 523 handler->second(DEL_STATION, mac_address); 524 } 525 } 526 return; 527 } 528 } 529 530 void NetlinkManager::OnRegChangeEvent(unique_ptr<const NL80211Packet> packet) { 531 uint32_t wiphy_index; 532 if (!packet->GetAttributeValue(NL80211_ATTR_WIPHY, &wiphy_index)) { 533 LOG(ERROR) << "Failed to get wiphy index from reg changed message"; 534 return; 535 } 536 537 uint8_t reg_type; 538 if (!packet->GetAttributeValue(NL80211_ATTR_REG_TYPE, ®_type)) { 539 LOG(ERROR) << "Failed to get NL80211_ATTR_REG_TYPE"; 540 } 541 542 string country_code; 543 // NL80211_REGDOM_TYPE_COUNTRY means the regulatory domain set is one that 544 // pertains to a specific country 545 if (reg_type == NL80211_REGDOM_TYPE_COUNTRY) { 546 if (!packet->GetAttributeValue(NL80211_ATTR_REG_ALPHA2, &country_code)) { 547 LOG(ERROR) << "Failed to get NL80211_ATTR_REG_ALPHA2"; 548 return; 549 } 550 } else if (reg_type == NL80211_REGDOM_TYPE_WORLD || 551 reg_type == NL80211_REGDOM_TYPE_CUSTOM_WORLD || 552 reg_type == NL80211_REGDOM_TYPE_INTERSECTION) { 553 // NL80211_REGDOM_TYPE_WORLD refers to the world regulartory domain. 554 // NL80211_REGDOM_TYPE_CUSTOM_WORLD refers to the driver specific world 555 // regulartory domain. 556 // NL80211_REGDOM_TYPE_INTERSECTION refers to an intersection between two 557 // regulatory domains: 558 // The previously set regulatory domain on the system and the last accepted 559 // regulatory domain request to be processed. 560 country_code = ""; 561 } else { 562 LOG(ERROR) << "Unknown type of regulatory domain change: " << (int)reg_type; 563 return; 564 } 565 566 const auto handler = on_reg_domain_changed_handler_.find(wiphy_index); 567 if (handler == on_reg_domain_changed_handler_.end()) { 568 LOG(DEBUG) << "No handler for country code changed event from wiphy" 569 << "with index: " << wiphy_index; 570 return; 571 } 572 handler->second(country_code); 573 } 574 575 void NetlinkManager::OnMlmeEvent(unique_ptr<const NL80211Packet> packet) { 576 uint32_t if_index; 577 578 if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) { 579 LOG(ERROR) << "Failed to get interface index from a MLME event message"; 580 return; 581 } 582 const auto handler = on_mlme_event_handler_.find(if_index); 583 if (handler == on_mlme_event_handler_.end()) { 584 LOG(DEBUG) << "No handler for mlme event from interface" 585 << " with index: " << if_index; 586 return; 587 } 588 uint32_t command = packet->GetCommand(); 589 if (command == NL80211_CMD_CONNECT) { 590 auto event = MlmeConnectEvent::InitFromPacket(packet.get()); 591 if (event != nullptr) { 592 handler->second->OnConnect(std::move(event)); 593 } 594 return; 595 } 596 if (command == NL80211_CMD_ASSOCIATE) { 597 auto event = MlmeAssociateEvent::InitFromPacket(packet.get()); 598 if (event != nullptr) { 599 handler->second->OnAssociate(std::move(event)); 600 } 601 return; 602 } 603 if (command == NL80211_CMD_ROAM) { 604 auto event = MlmeRoamEvent::InitFromPacket(packet.get()); 605 if (event != nullptr) { 606 handler->second->OnRoam(std::move(event)); 607 } 608 return; 609 } 610 if (command == NL80211_CMD_DISCONNECT) { 611 auto event = MlmeDisconnectEvent::InitFromPacket(packet.get()); 612 if (event != nullptr) { 613 handler->second->OnDisconnect(std::move(event)); 614 } 615 return; 616 } 617 if (command == NL80211_CMD_DISASSOCIATE) { 618 auto event = MlmeDisassociateEvent::InitFromPacket(packet.get()); 619 if (event != nullptr) { 620 handler->second->OnDisassociate(std::move(event)); 621 } 622 return; 623 } 624 625 } 626 627 void NetlinkManager::OnSchedScanResultsReady(unique_ptr<const NL80211Packet> packet) { 628 uint32_t if_index; 629 if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) { 630 LOG(ERROR) << "Failed to get interface index from scan result notification"; 631 return; 632 } 633 634 const auto handler = on_sched_scan_result_ready_handler_.find(if_index); 635 if (handler == on_sched_scan_result_ready_handler_.end()) { 636 LOG(DEBUG) << "No handler for scheduled scan result notification from" 637 << " interface with index: " << if_index; 638 return; 639 } 640 // Run scan result notification handler. 641 handler->second(if_index, packet->GetCommand() == NL80211_CMD_SCHED_SCAN_STOPPED); 642 } 643 644 void NetlinkManager::OnScanResultsReady(unique_ptr<const NL80211Packet> packet) { 645 uint32_t if_index; 646 if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) { 647 LOG(ERROR) << "Failed to get interface index from scan result notification"; 648 return; 649 } 650 bool aborted = false; 651 if (packet->GetCommand() == NL80211_CMD_SCAN_ABORTED) { 652 aborted = true; 653 } 654 655 const auto handler = on_scan_result_ready_handler_.find(if_index); 656 if (handler == on_scan_result_ready_handler_.end()) { 657 LOG(WARNING) << "No handler for scan result notification from interface" 658 << " with index: " << if_index; 659 return; 660 } 661 662 vector<vector<uint8_t>> ssids; 663 NL80211NestedAttr ssids_attr(0); 664 if (!packet->GetAttribute(NL80211_ATTR_SCAN_SSIDS, &ssids_attr)) { 665 if (!aborted) { 666 LOG(WARNING) << "Failed to get scan ssids from scan result notification"; 667 } 668 } else { 669 if (!ssids_attr.GetListOfAttributeValues(&ssids)) { 670 return; 671 } 672 } 673 vector<uint32_t> freqs; 674 NL80211NestedAttr freqs_attr(0); 675 if (!packet->GetAttribute(NL80211_ATTR_SCAN_FREQUENCIES, &freqs_attr)) { 676 if (!aborted) { 677 LOG(WARNING) << "Failed to get scan freqs from scan result notification"; 678 } 679 } else { 680 if (!freqs_attr.GetListOfAttributeValues(&freqs)) { 681 return; 682 } 683 } 684 // Run scan result notification handler. 685 handler->second(if_index, aborted, ssids, freqs); 686 } 687 688 void NetlinkManager::SubscribeStationEvent( 689 uint32_t interface_index, 690 OnStationEventHandler handler) { 691 on_station_event_handler_[interface_index] = handler; 692 } 693 694 void NetlinkManager::UnsubscribeStationEvent(uint32_t interface_index) { 695 on_station_event_handler_.erase(interface_index); 696 } 697 698 void NetlinkManager::SubscribeRegDomainChange( 699 uint32_t wiphy_index, 700 OnRegDomainChangedHandler handler) { 701 on_reg_domain_changed_handler_[wiphy_index] = handler; 702 } 703 704 void NetlinkManager::UnsubscribeRegDomainChange(uint32_t wiphy_index) { 705 on_reg_domain_changed_handler_.erase(wiphy_index); 706 } 707 708 void NetlinkManager::SubscribeScanResultNotification( 709 uint32_t interface_index, 710 OnScanResultsReadyHandler handler) { 711 on_scan_result_ready_handler_[interface_index] = handler; 712 } 713 714 void NetlinkManager::UnsubscribeScanResultNotification( 715 uint32_t interface_index) { 716 on_scan_result_ready_handler_.erase(interface_index); 717 } 718 719 void NetlinkManager::SubscribeMlmeEvent(uint32_t interface_index, 720 MlmeEventHandler* handler) { 721 on_mlme_event_handler_[interface_index] = handler; 722 } 723 724 void NetlinkManager::UnsubscribeMlmeEvent(uint32_t interface_index) { 725 on_mlme_event_handler_.erase(interface_index); 726 } 727 728 void NetlinkManager::SubscribeSchedScanResultNotification( 729 uint32_t interface_index, 730 OnSchedScanResultsReadyHandler handler) { 731 on_sched_scan_result_ready_handler_[interface_index] = handler; 732 } 733 734 void NetlinkManager::UnsubscribeSchedScanResultNotification( 735 uint32_t interface_index) { 736 on_sched_scan_result_ready_handler_.erase(interface_index); 737 } 738 739 } // namespace wificond 740 } // namespace android 741