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. 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. 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