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