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