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