Home | History | Annotate | Download | only in net
      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, &reg_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