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