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