• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef WIFICOND_NET_NETLINK_MANAGER_H_
18 #define WIFICOND_NET_NETLINK_MANAGER_H_
19 
20 #include <array>
21 #include <functional>
22 #include <map>
23 #include <memory>
24 
25 #include <linux/if_ether.h>
26 
27 #include <android-base/macros.h>
28 #include <android-base/unique_fd.h>
29 #include <libnlinterceptor/libnlinterceptor.h>
30 
31 #include "event_loop.h"
32 
33 namespace android {
34 namespace wificond {
35 
36 class MlmeEventHandler;
37 class NL80211Packet;
38 
39 // Encapsulates all the different things we know about a specific message
40 // type like its name, and its id.
41 struct MessageType {
42    // This constructor is needed by map[key] operation.
MessageTypeMessageType43    MessageType() {};
MessageTypeMessageType44    explicit MessageType(uint16_t id) {
45      family_id = id;
46    };
47    uint16_t family_id;
48    // Multicast groups supported by the family.  The string and mapping to
49    // a group id are extracted from the CTRL_CMD_NEWFAMILY message.
50    std::map<std::string, uint32_t> groups;
51 };
52 
53 // This describes a type of function handling scan results ready notification.
54 // |interface_index| is the index of interface which the scan results
55 // are from.
56 // |aborted| is a boolean indicating if this scan was aborted or not.
57 // According to nl80211.h document, part of the scan result might still be
58 // available even when the scan was aborted.
59 // |ssids| is a vector of scan ssids associated with the corresponding
60 // scan request.
61 // |frequencies| is a vector of scan frequencies associated with the
62 // corresponding scan request.
63 typedef std::function<void(
64     uint32_t interface_index,
65     bool aborted,
66     std::vector<std::vector<uint8_t>>& ssids,
67     std::vector<uint32_t>& frequencies)> OnScanResultsReadyHandler;
68 
69 // This describes a type of function handling scheduled scan results ready
70 // notification. This can also be used for notificating the stopping of a
71 // scheduled scan.
72 // |interface_index| is the index of interface which the scan results
73 // are from.
74 // |scan_stopped| is a boolean indicating if this scheduled scan was stopped
75 // or not.
76 typedef std::function<void(
77     uint32_t interface_index,
78     bool scan_stopped)> OnSchedScanResultsReadyHandler;
79 
80 // This describes a type of function handling regulatory domain change
81 // notification.
82 // If the regulatory domain set is one that pertains to a specific country,
83 // |country_code| will be set accordingly.
84 // If the regulatory domain set does not pertain to a specific country,
85 // |country_code| will be an empty string. This could be a world regulatory
86 // domain or a intersection regulatory domain.
87 // See details in defination of |nl80211_reg_type| from nl80211.h.
88 typedef std::function<void(
89     uint32_t wiphy_index, std::string& country_code)> OnRegDomainChangedHandler;
90 
91 // Enum used for identifying channel bandwidth.
92 // This is used by function |OnChannelSwitchEventHandler|.
93 enum ChannelBandwidth {
94     BW_INVALID,
95     BW_20_NOHT,
96     BW_20,
97     BW_40,
98     BW_80,
99     BW_80P80,
100     BW_160,
101     BW_320,
102 };
103 
104 // This describes a type of function handling channel switch notification.
105 // |frequency| represents the frequence of the channel in MHz.
106 typedef std::function<void(
107     uint32_t frequency, ChannelBandwidth bandwidth)> OnChannelSwitchEventHandler;
108 
109 // Enum used for identifying the type of a station event.
110 // This is used by function |OnStationEventHandler|.
111 enum StationEvent {
112     NEW_STATION,
113     DEL_STATION
114 };
115 
116 // This describes a type of function handling station events.
117 // |event| specifies the type of this event.
118 // |mac_address| is the station mac address associated with this event.
119 typedef std::function<void(
120     StationEvent event,
121     const std::array<uint8_t, ETH_ALEN>& mac_address)> OnStationEventHandler;
122 
123 // This describes a type of function handling frame tx status events.
124 // |cookie| specifies the cookie of the transmitted frame that this status
125 // event corresponds to.
126 // |was_acked| reports whether the transmitted frame was ACKed.
127 typedef std::function<void(
128     uint64_t cookie, bool was_acked)> OnFrameTxStatusEventHandler;
129 
130 class NetlinkManager {
131  public:
132   explicit NetlinkManager(EventLoop* event_loop);
133   virtual ~NetlinkManager();
134   // Initialize netlink manager.
135   // This includes setting up socket and requesting nl80211 family id from kernel.
136   // Returns true on success.
137   virtual bool Start();
138   // Returns true if this netlink manager object is started.
139   virtual bool IsStarted() const;
140   // Returns a sequence number available for use.
141   virtual uint32_t GetSequenceNumber();
142   // Get NL80211 netlink family id,
143   virtual uint16_t GetFamilyId();
144 
145   // Send |packet| to kernel.
146   // This works in an asynchronous way.
147   // |handler| will be run when we receive a valid reply from kernel.
148   // Do not use this asynchronous interface to send a dump request.
149   // Returns true on success.
150   virtual bool RegisterHandlerAndSendMessage(const NL80211Packet& packet,
151       std::function<void(std::unique_ptr<const NL80211Packet>)> handler);
152   // Synchronous version of |RegisterHandlerAndSendMessage|.
153   // Returns true on successfully receiving an valid reply.
154   // Reply packets will be stored in |*response|.
155   virtual bool SendMessageAndGetResponses(
156       const NL80211Packet& packet,
157       std::vector<std::unique_ptr<const NL80211Packet>>* response);
158   // Wrapper of |SendMessageAndGetResponses| for messages with a single
159   // response.
160   // Returns true on successfully receiving an valid reply.
161   // This will returns false if a NLMSG_ERROR is received.
162   // Reply packet will be stored in |*response|.
163   virtual bool SendMessageAndGetSingleResponse(
164       const NL80211Packet& packet,
165       std::unique_ptr<const NL80211Packet>* response);
166 
167   // Wrapper of |SendMessageAndGetResponses| for messages with a single
168   // response.
169   // Returns true on successfully receiving an valid reply.
170   // This will returns true if a NLMSG_ERROR is received.
171   // This is useful when the caller needs the error code from kernel.
172   // Reply packet will be stored in |*response|.
173   virtual bool SendMessageAndGetSingleResponseOrError(
174       const NL80211Packet& packet,
175       std::unique_ptr<const NL80211Packet>* response);
176 
177   // Wrapper of |SendMessageAndGetResponses| for messages that trigger
178   // only a NLMSG_ERROR response
179   // Returns true if the message is successfully sent and a NLMSG_ERROR response
180   // comes back, regardless of the error code.
181   // Error code will be stored in |*error_code|
182   virtual bool SendMessageAndGetAckOrError(const NL80211Packet& packet,
183                                            int* error_code);
184   // Wrapper of |SendMessageAndGetResponses| that returns true iff the response
185   // is an ACK.
186   virtual bool SendMessageAndGetAck(const NL80211Packet& packet);
187 
188   // Sign up to receive and log multicast events of a specific type.
189   // |group| is one of the string NL80211_MULTICAST_GROUP_* in nl80211.h.
190   virtual bool SubscribeToEvents(const std::string& group);
191 
192   // Sign up to be notified when new scan results are available.
193   // |handler| will be called when the kernel signals to wificond that a scan
194   // has been completed on the given |interface_index|.  See the declaration of
195   // OnScanResultsReadyHandler for documentation on the semantics of this
196   // callback.
197   // Only one handler can be registered per interface index.
198   // New handler will replace the registered handler if they are for the
199   // same interface index.
200   virtual void SubscribeScanResultNotification(
201       uint32_t interface_index,
202       OnScanResultsReadyHandler handler);
203 
204   // Cancel the sign-up of receiving new scan result notification from
205   // interface with index |interface_index|.
206   virtual void UnsubscribeScanResultNotification(uint32_t interface_index);
207 
208   // Sign up to be notified when there is MLME event.
209   // Only one handler can be registered per interface index.
210   // New handler will replace the registered handler if they are for the
211   // same interface index.
212   // NetlinkManager is not going to take ownership of this pointer, and that it
213   // is the caller's responsibility to make sure that the object exists for the
214   // duration of the subscription.
215   virtual void SubscribeMlmeEvent(uint32_t interface_index,
216                                   MlmeEventHandler* handler);
217 
218   // Cancel the sign-up of receiving MLME event notification
219   // from interface with index |interface_index|.
220   virtual void UnsubscribeMlmeEvent(uint32_t interface_index);
221 
222   // Sign up to be notified when new scan results are available.
223   // |handler| will be called when the kernel signals to wificond that a
224   // scheduled scan has been completed on the given |interface_index|.
225   // See the declaration of OnSchedScanResultsReadyHandler for documentation
226   // on the semantics of this callback.
227   // Only one handler can be registered per interface index.
228   // New handler will replace the registered handler if they are for the
229   // same interface index.
230   virtual void SubscribeSchedScanResultNotification(
231       uint32_t interface_index,
232       OnSchedScanResultsReadyHandler handler);
233 
234   // Cancel the sign-up of receiving new scheduled scan result notification from
235   // interface with index |interface_index|.
236   virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index);
237 
238   // Sign up to be notified when there is an regulatory domain change.
239   // Only one handler can be registered per wiphy index.
240   // New handler will replace the registered handler if they are for the
241   // same wiphy index.
242   virtual void SubscribeRegDomainChange(uint32_t wiphy_index,
243                                         OnRegDomainChangedHandler handler);
244 
245   // Cancel the sign-up of receiving regulatory domain change notification
246   // from wiphy with index |wiphy_index|.
247   virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index);
248 
249   // Sign up to be notified when there is a station event.
250   // Only one handler can be registered per interface index.
251   // New handler will replace the registered handler if they are for the
252   // same interface index.
253   virtual void SubscribeStationEvent(uint32_t interface_index,
254                                      OnStationEventHandler handler);
255 
256   // Cancel the sign-up of receiving station events.
257   virtual void UnsubscribeStationEvent(uint32_t interface_index);
258 
259   // Sign up to be notified when there is a channel switch event.
260   // Only one handler can be registered per interface index.
261   // New handler will replace the registered handler if they are for the
262   // same interface index.
263   virtual void SubscribeChannelSwitchEvent(
264       uint32_t interface_index,
265       OnChannelSwitchEventHandler handler);
266 
267   // Cancel the sign-up of receiving channel events.
268   virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index);
269 
270   // Sign up to be notified of frame tx status events.
271   virtual void SubscribeFrameTxStatusEvent(
272       uint32_t interface_index, OnFrameTxStatusEventHandler handler);
273 
274   // Cancel the sign-up of receiving frame tx status events.
275   virtual void UnsubscribeFrameTxStatusEvent(uint32_t interface_index);
276 
277  private:
278   bool SetupSocket(android::base::unique_fd* netlink_fd,
279                    android::nlinterceptor::InterceptedSocket* nl_destination);
280   bool WatchSocket(android::base::unique_fd* netlink_fd);
281   void ReceivePacketAndRunHandler(int fd);
282   bool DiscoverFamilyId();
283   bool SendMessageInternal(const NL80211Packet& packet, int fd,
284                            android::nlinterceptor::InterceptedSocket nl_destination);
285   void BroadcastHandler(std::unique_ptr<const NL80211Packet> packet);
286   void OnRegChangeEvent(std::unique_ptr<const NL80211Packet> packet);
287   void OnMlmeEvent(std::unique_ptr<const NL80211Packet> packet);
288   void OnScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
289   void OnSchedScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
290   void OnChannelSwitchEvent(std::unique_ptr<const NL80211Packet> packet);
291   void OnFrameTxStatusEvent(std::unique_ptr<const NL80211Packet> packet);
292 
293   // This handler revceives mapping from NL80211 family name to family id,
294   // as well as mapping from group name to group id.
295   // These mappings are allocated by kernel.
296   void OnNewFamily(std::unique_ptr<const NL80211Packet> packet);
297 
298   bool started_;
299   // We use different sockets for synchronous and asynchronous interfaces.
300   // Kernel will reply error message when we start a new request in the
301   // middle of a dump request.
302   // Using different sockets help us avoid the complexity of message
303   // rescheduling.
304   android::base::unique_fd sync_netlink_fd_;
305   android::base::unique_fd async_netlink_fd_;
306 
307   // Each netlink socket will either communicate directly with the kernel (pid = 0), or will be
308   // assigned a Netlink Interceptor socket, and will have a non-zero pid to which messages should be
309   // sent.
310   android::nlinterceptor::InterceptedSocket sync_netlink_destination_ = {NETLINK_GENERIC, 0};
311   android::nlinterceptor::InterceptedSocket async_netlink_destination_ = {NETLINK_GENERIC, 0};
312   EventLoop* event_loop_;
313 
314   // This is a collection of message handlers, for each sequence number.
315   std::map<uint32_t,
316       std::function<void(std::unique_ptr<const NL80211Packet>)>> message_handlers_;
317 
318   // A mapping from interface index to the handler registered to receive
319   // scan results notifications.
320   std::map<uint32_t, OnScanResultsReadyHandler> on_scan_result_ready_handler_;
321   // A mapping from interface index to the handler registered to receive
322   // scheduled scan results notifications.
323   std::map<uint32_t, OnSchedScanResultsReadyHandler>
324       on_sched_scan_result_ready_handler_;
325 
326   std::map<uint32_t, MlmeEventHandler*> on_mlme_event_handler_;
327 
328   // A mapping from wiphy index to the handler registered to receive
329   // regulatory domain change notifications.
330   std::map<uint32_t, OnRegDomainChangedHandler> on_reg_domain_changed_handler_;
331   std::map<uint32_t, OnStationEventHandler> on_station_event_handler_;
332   std::map<uint32_t, OnChannelSwitchEventHandler> on_channel_switch_event_handler_;
333 
334   // mapping from interface_index to frame tx status event handler
335   std::map<uint32_t, OnFrameTxStatusEventHandler>
336       on_frame_tx_status_event_handler_;
337 
338   // Mapping from family name to family id, and group name to group id.
339   std::map<std::string, MessageType> message_types_;
340 
341   uint32_t sequence_number_;
342 
343   DISALLOW_COPY_AND_ASSIGN(NetlinkManager);
344 };
345 
346 }  // namespace wificond
347 }  // namespace android
348 
349 #endif  // WIFICOND_NET_NETLINK_MANAGER_H_
350