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