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
29namespace android {
30namespace wificond {
31
32class MlmeEventHandler;
33class NL80211Packet;
34
35// Encapsulates all the different things we know about a specific message
36// type like its name, and its id.
37struct MessageType {
38   // This constructor is needed by map[key] operation.
39   MessageType() {};
40   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.
59typedef 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.
72typedef 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.
84typedef std::function<void(
85    std::string& country_code)> OnRegDomainChangedHandler;
86
87// Enum used for identifying the type of a station event.
88// This is used by function |OnStationEventHandler|.
89enum StationEvent {
90    NEW_STATION,
91    DEL_STATION
92};
93
94// This describes a type of function handling station events.
95// |event| specifies the type of this event.
96// |mac_address| is the station mac address associated with this event.
97typedef std::function<void(
98    StationEvent event,
99    const std::vector<uint8_t>& mac_address)> OnStationEventHandler;
100
101class NetlinkManager {
102 public:
103  explicit NetlinkManager(EventLoop* event_loop);
104  virtual ~NetlinkManager();
105  // Initialize netlink manager.
106  // This includes setting up socket and requesting nl80211 family id from kernel.
107  // Returns true on success.
108  virtual bool Start();
109  // Returns true if this netlink manager object is started.
110  virtual bool IsStarted() const;
111  // Returns a sequence number available for use.
112  virtual uint32_t GetSequenceNumber();
113  // Get NL80211 netlink family id,
114  virtual uint16_t GetFamilyId();
115
116  // Send |packet| to kernel.
117  // This works in an asynchronous way.
118  // |handler| will be run when we receive a valid reply from kernel.
119  // Do not use this asynchronous interface to send a dump request.
120  // Returns true on success.
121  virtual bool RegisterHandlerAndSendMessage(const NL80211Packet& packet,
122      std::function<void(std::unique_ptr<const NL80211Packet>)> handler);
123  // Synchronous version of |RegisterHandlerAndSendMessage|.
124  // Returns true on successfully receiving an valid reply.
125  // Reply packets will be stored in |*response|.
126  virtual bool SendMessageAndGetResponses(
127      const NL80211Packet& packet,
128      std::vector<std::unique_ptr<const NL80211Packet>>* response);
129  // Wrapper of |SendMessageAndGetResponses| for messages with a single
130  // response.
131  // Returns true on successfully receiving an valid reply.
132  // This will returns false if a NLMSG_ERROR is received.
133  // Reply packet will be stored in |*response|.
134  virtual bool SendMessageAndGetSingleResponse(
135      const NL80211Packet& packet,
136      std::unique_ptr<const NL80211Packet>* response);
137
138  // Wrapper of |SendMessageAndGetResponses| for messages with a single
139  // response.
140  // Returns true on successfully receiving an valid reply.
141  // This will returns true if a NLMSG_ERROR is received.
142  // This is useful when the caller needs the error code from kernel.
143  // Reply packet will be stored in |*response|.
144  virtual bool SendMessageAndGetSingleResponseOrError(
145      const NL80211Packet& packet,
146      std::unique_ptr<const NL80211Packet>* response);
147
148  // Wrapper of |SendMessageAndGetResponses| for messages that trigger
149  // only a NLMSG_ERROR response
150  // Returns true if the message is successfully sent and a NLMSG_ERROR response
151  // comes back, regardless of the error code.
152  // Error code will be stored in |*error_code|
153  virtual bool SendMessageAndGetAckOrError(const NL80211Packet& packet,
154                                           int* error_code);
155  // Wrapper of |SendMessageAndGetResponses| that returns true iff the response
156  // is an ACK.
157  virtual bool SendMessageAndGetAck(const NL80211Packet& packet);
158
159  // Sign up to receive and log multicast events of a specific type.
160  // |group| is one of the string NL80211_MULTICAST_GROUP_* in nl80211.h.
161  virtual bool SubscribeToEvents(const std::string& group);
162
163  // Sign up to be notified when new scan results are available.
164  // |handler| will be called when the kernel signals to wificond that a scan
165  // has been completed on the given |interface_index|.  See the declaration of
166  // OnScanResultsReadyHandler for documentation on the semantics of this
167  // callback.
168  // Only one handler can be registered per interface index.
169  // New handler will replace the registered handler if they are for the
170  // same interface index.
171  virtual void SubscribeScanResultNotification(
172      uint32_t interface_index,
173      OnScanResultsReadyHandler handler);
174
175  // Cancel the sign-up of receiving new scan result notification from
176  // interface with index |interface_index|.
177  virtual void UnsubscribeScanResultNotification(uint32_t interface_index);
178
179  // Sign up to be notified when there is MLME event.
180  // Only one handler can be registered per interface index.
181  // New handler will replace the registered handler if they are for the
182  // same interface index.
183  // NetlinkManager is not going to take ownership of this pointer, and that it
184  // is the caller's responsibility to make sure that the object exists for the
185  // duration of the subscription.
186  virtual void SubscribeMlmeEvent(uint32_t interface_index,
187                                  MlmeEventHandler* handler);
188
189  // Cancel the sign-up of receiving MLME event notification
190  // from interface with index |interface_index|.
191  virtual void UnsubscribeMlmeEvent(uint32_t interface_index);
192
193  // Sign up to be notified when new scan results are available.
194  // |handler| will be called when the kernel signals to wificond that a
195  // scheduled scan has been completed on the given |interface_index|.
196  // See the declaration of OnSchedScanResultsReadyHandler for documentation
197  // on the semantics of this callback.
198  // Only one handler can be registered per interface index.
199  // New handler will replace the registered handler if they are for the
200  // same interface index.
201  virtual void SubscribeSchedScanResultNotification(
202      uint32_t interface_index,
203      OnSchedScanResultsReadyHandler handler);
204
205  // Cancel the sign-up of receiving new scheduled scan result notification from
206  // interface with index |interface_index|.
207  virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index);
208
209  // Sign up to be notified when there is an regulatory domain change.
210  // Only one handler can be registered per wiphy index.
211  // New handler will replace the registered handler if they are for the
212  // same wiphy index.
213  virtual void SubscribeRegDomainChange(uint32_t wiphy_index,
214                                        OnRegDomainChangedHandler handler);
215
216  // Cancel the sign-up of receiving regulatory domain change notification
217  // from wiphy with index |wiphy_index|.
218  virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index);
219
220  // Sign up to be notified when there is an station event.
221  // Only one handler can be registered per interface index.
222  // New handler will replace the registered handler if they are for the
223  // same interface index.
224  virtual void SubscribeStationEvent(uint32_t interface_index,
225                                     OnStationEventHandler handler);
226
227  // Cancel the sign-up of receiving station events.
228  virtual void UnsubscribeStationEvent(uint32_t interface_index);
229
230 private:
231  bool SetupSocket(android::base::unique_fd* netlink_fd);
232  bool WatchSocket(android::base::unique_fd* netlink_fd);
233  void ReceivePacketAndRunHandler(int fd);
234  bool DiscoverFamilyId();
235  bool SendMessageInternal(const NL80211Packet& packet, int fd);
236  void BroadcastHandler(std::unique_ptr<const NL80211Packet> packet);
237  void OnRegChangeEvent(std::unique_ptr<const NL80211Packet> packet);
238  void OnMlmeEvent(std::unique_ptr<const NL80211Packet> packet);
239  void OnScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
240  void OnSchedScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
241
242  // This handler revceives mapping from NL80211 family name to family id,
243  // as well as mapping from group name to group id.
244  // These mappings are allocated by kernel.
245  void OnNewFamily(std::unique_ptr<const NL80211Packet> packet);
246
247  bool started_;
248  // We use different sockets for synchronous and asynchronous interfaces.
249  // Kernel will reply error message when we start a new request in the
250  // middle of a dump request.
251  // Using different sockets help us avoid the complexity of message
252  // rescheduling.
253  android::base::unique_fd sync_netlink_fd_;
254  android::base::unique_fd async_netlink_fd_;
255  EventLoop* event_loop_;
256
257  // This is a collection of message handlers, for each sequence number.
258  std::map<uint32_t,
259      std::function<void(std::unique_ptr<const NL80211Packet>)>> message_handlers_;
260
261  // A mapping from interface index to the handler registered to receive
262  // scan results notifications.
263  std::map<uint32_t, OnScanResultsReadyHandler> on_scan_result_ready_handler_;
264  // A mapping from interface index to the handler registered to receive
265  // scheduled scan results notifications.
266  std::map<uint32_t, OnSchedScanResultsReadyHandler>
267      on_sched_scan_result_ready_handler_;
268
269  std::map<uint32_t, MlmeEventHandler*> on_mlme_event_handler_;
270
271  // A mapping from wiphy index to the handler registered to receive
272  // regulatory domain change notifications.
273  std::map<uint32_t, OnRegDomainChangedHandler> on_reg_domain_changed_handler_;
274
275  std::map<uint32_t, OnStationEventHandler> on_station_event_handler_;
276
277  // Mapping from family name to family id, and group name to group id.
278  std::map<std::string, MessageType> message_types_;
279
280  uint32_t sequence_number_;
281
282  DISALLOW_COPY_AND_ASSIGN(NetlinkManager);
283};
284
285}  // namespace wificond
286}  // namespace android
287
288#endif  // WIFICOND_NET_NETLINK_MANAGER_H_
289