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