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