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