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, ®_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