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