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_UTILS_H_
18 #define WIFICOND_NET_NETLINK_UTILS_H_
19 
20 #include <array>
21 #include <functional>
22 #include <string>
23 #include <vector>
24 
25 #include <linux/if_ether.h>
26 
27 #include <android-base/macros.h>
28 
29 #include "wificond/net/kernel-header-latest/nl80211.h"
30 #include "wificond/net/netlink_manager.h"
31 
32 namespace android {
33 namespace wificond {
34 
35 struct InterfaceInfo {
36   InterfaceInfo() = default;
InterfaceInfoInterfaceInfo37   InterfaceInfo(uint32_t index,
38                 const std::string& name,
39                 const std::array<uint8_t, ETH_ALEN>& mac_address)
40       : index(index),
41         name(name),
42         mac_address(mac_address) {}
43   // Index of this interface.
44   uint32_t index;
45   // Name of this interface.
46   std::string name;
47   // MAC address of this interface.
48   std::array<uint8_t, ETH_ALEN> mac_address;
49 };
50 
51 struct BandInfo {
52   BandInfo() = default;
BandInfoBandInfo53   BandInfo(std::vector<uint32_t>& band_2g_,
54            std::vector<uint32_t>& band_5g_,
55            std::vector<uint32_t>& band_dfs_)
56       : band_2g(band_2g_),
57         band_5g(band_5g_),
58         band_dfs(band_dfs_) {}
59   // Frequencies for 2.4 GHz band.
60   std::vector<uint32_t> band_2g;
61   // Frequencies for 5 GHz band without DFS.
62   std::vector<uint32_t> band_5g;
63   // Frequencies for DFS.
64   std::vector<uint32_t> band_dfs;
65 };
66 
67 struct ScanCapabilities {
68   ScanCapabilities() = default;
ScanCapabilitiesScanCapabilities69   ScanCapabilities(uint8_t max_num_scan_ssids_,
70                    uint8_t max_num_sched_scan_ssids_,
71                    uint8_t max_match_sets_,
72                    uint32_t max_num_scan_plans_,
73                    uint32_t max_scan_plan_interval_,
74                    uint32_t max_scan_plan_iterations_)
75       : max_num_scan_ssids(max_num_scan_ssids_),
76         max_num_sched_scan_ssids(max_num_sched_scan_ssids_),
77         max_match_sets(max_match_sets_),
78         max_num_scan_plans(max_num_scan_plans_),
79         max_scan_plan_interval(max_scan_plan_interval_),
80         max_scan_plan_iterations(max_scan_plan_iterations_) {}
81   // Number of SSIDs you can scan with a single scan request.
82   uint8_t max_num_scan_ssids;
83   // Number of SSIDs you can scan with a single scheduled scan request.
84   uint8_t max_num_sched_scan_ssids;
85   // Maximum number of sets that can be used with NL80211_ATTR_SCHED_SCAN_MATCH.
86   uint8_t max_match_sets;
87   // Maximum number of scan plans that can be specified.
88   uint32_t max_num_scan_plans;
89   // Maximum interval in seconds for a particular scan plan that can be
90   // specified.
91   uint32_t max_scan_plan_interval;
92   // Maximum number of iterations for a particular scan plan that can be
93   // specified.
94   uint32_t max_scan_plan_iterations;
95 };
96 
97 struct WiphyFeatures {
WiphyFeaturesWiphyFeatures98   WiphyFeatures()
99       : supports_random_mac_oneshot_scan(false),
100         supports_random_mac_sched_scan(false),
101         supports_low_span_oneshot_scan(false),
102         supports_low_power_oneshot_scan(false),
103         supports_high_accuracy_oneshot_scan(false),
104         supports_tx_mgmt_frame_mcs(false) {}
105   WiphyFeatures(uint32_t feature_flags,
106                 const std::vector<uint8_t>& ext_feature_flags_bytes);
107   // This device/driver supports using a random MAC address during scan
108   // (while not associated).
109   bool supports_random_mac_oneshot_scan;
110   // This device/driver supports using a random MAC address for every
111   // scan iteration during scheduled scan (while not associated).
112   bool supports_random_mac_sched_scan;
113   // This device/driver supports performing low-span/low-latency one-shot scans.
114   bool supports_low_span_oneshot_scan;
115   // This device/driver supports performing low-power one-shot scans.
116   bool supports_low_power_oneshot_scan;
117   // This device/driver supports performing high-accuracy one-shot scans.
118   bool supports_high_accuracy_oneshot_scan;
119   // This device/driver supports sending a management frame at a specified MCS.
120   bool supports_tx_mgmt_frame_mcs;
121   // This device/driver supports sched_scan for reporting BSSs
122   // with better RSSI than the current connected BSS
123   bool supports_ext_sched_scan_relative_rssi;
124   // There are other flags included in NL80211_ATTR_FEATURE_FLAGS.
125   // We will add them once we find them useful.
126 };
127 
128 struct StationInfo {
129   StationInfo() = default;
StationInfoStationInfo130   StationInfo(uint32_t station_tx_packets_,
131               uint32_t station_tx_failed_,
132               uint32_t station_tx_bitrate_,
133               int8_t current_rssi_,
134               uint32_t station_rx_bitrate_)
135       : station_tx_packets(station_tx_packets_),
136         station_tx_failed(station_tx_failed_),
137         station_tx_bitrate(station_tx_bitrate_),
138         current_rssi(current_rssi_),
139         station_rx_bitrate(station_rx_bitrate_) {}
140   // Number of successfully transmitted packets.
141   int32_t station_tx_packets;
142   // Number of tramsmission failures.
143   int32_t station_tx_failed;
144   // Transimission bit rate in 100kbit/s.
145   uint32_t station_tx_bitrate;
146   // Current signal strength.
147   int8_t current_rssi;
148   // Last Received unicast packet bit rate in 100kbit/s.
149   uint32_t station_rx_bitrate;
150   // There are many other counters/parameters included in station info.
151   // We will add them once we find them useful.
152 };
153 
154 class MlmeEventHandler;
155 class NetlinkManager;
156 class NL80211Packet;
157 
158 // Provides NL80211 helper functions.
159 class NetlinkUtils {
160  public:
161   // Currently we only support setting the interface to STATION mode.
162   // This is used for cleaning up interface after KILLING hostapd.
163   enum InterfaceMode{
164       STATION_MODE
165   };
166 
167   explicit NetlinkUtils(NetlinkManager* netlink_manager);
168   virtual ~NetlinkUtils();
169 
170   // Get the wiphy index from kernel.
171   // |*out_wiphy_index| returns the wiphy index from kernel.
172   // Returns true on success.
173   virtual bool GetWiphyIndex(uint32_t* out_wiphy_index);
174   virtual bool GetWiphyIndex(uint32_t* out_wiphy_index,
175                              const std::string& iface_name);
176 
177   // Get wifi interfaces info from kernel.
178   // |wiphy_index| is the wiphy index we get using GetWiphyIndex().
179   // |interface_info| returns a vector of InterfaceInfo structs with
180   // information about all existing interfaces.
181   // Returns true on success.
182   virtual bool GetInterfaces(uint32_t wiphy_index,
183                              std::vector<InterfaceInfo>* interface_info);
184 
185   // Set the mode of interface.
186   // |interface_index| is the interface index.
187   // |mode| is one of the values in |enum InterfaceMode|.
188   // Returns true on success.
189   virtual bool SetInterfaceMode(uint32_t interface_index,
190                                 InterfaceMode mode);
191 
192   // Get wiphy capability information from kernel.
193   // Returns true on success.
194   virtual bool GetWiphyInfo(uint32_t wiphy_index,
195                             BandInfo* out_band_info,
196                             ScanCapabilities* out_scan_capabilities,
197                             WiphyFeatures* out_wiphy_features);
198 
199   // Get station info from kernel.
200   // |*out_station_info]| is the struct of available station information.
201   // Returns true on success.
202   virtual bool GetStationInfo(uint32_t interface_index,
203                               const std::array<uint8_t, ETH_ALEN>& mac_address,
204                               StationInfo* out_station_info);
205 
206   // Get a bitmap for nl80211 protocol features,
207   // i.e. features for the nl80211 protocol rather than device features.
208   // See enum nl80211_protocol_features in nl80211.h for decoding the bitmap.
209   // Returns true on success.
210   virtual bool GetProtocolFeatures(uint32_t* features);
211 
212   // Get current alpha2 country code from kernel.
213   // Returns true on success.
214   virtual bool GetCountryCode(std::string* out_country_code);
215 
216   // Sign up to be notified when there is MLME event.
217   // Only one handler can be registered per interface index.
218   // New handler will replace the registered handler if they are for the
219   // same interface index.
220   // NetlinkUtils is not going to take ownership of this pointer, and that it
221   // is the caller's responsibility to make sure that the object exists for the
222   // duration of the subscription.
223   virtual void SubscribeMlmeEvent(uint32_t interface_index,
224                                   MlmeEventHandler* handler);
225 
226   // Cancel the sign-up of receiving MLME event notification
227   // from interface with index |interface_index|.
228   virtual void UnsubscribeMlmeEvent(uint32_t interface_index);
229 
230   // Sign up to be notified when there is an regulatory domain change.
231   // Only one handler can be registered per wiphy index.
232   // New handler will replace the registered handler if they are for the
233   // same wiphy index.
234   virtual void SubscribeRegDomainChange(uint32_t wiphy_index,
235                                         OnRegDomainChangedHandler handler);
236 
237   // Cancel the sign-up of receiving regulatory domain change notification
238   // from wiphy with index |wiphy_index|.
239   virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index);
240 
241   // Sign up to be notified when there is a station event.
242   // Only one handler can be registered per interface index.
243   // New handler will replace the registered handler if they are for the
244   // same interface index.
245   virtual void SubscribeStationEvent(uint32_t interface_index,
246                                      OnStationEventHandler handler);
247 
248   // Cancel the sign-up of receiving station events.
249   virtual void UnsubscribeStationEvent(uint32_t interface_index);
250 
251   // Sign up to be notified when there is a channel switch event.
252   // Only one handler can be registered per interface index.
253   // New handler will replace the registered handler if they are for the
254   // same interface index.
255   virtual void SubscribeChannelSwitchEvent(uint32_t interface_index,
256                                            OnChannelSwitchEventHandler handler);
257 
258   // Cancel the sign-up of receiving channel switch events.
259   virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index);
260 
261   // Sign up to be notified of frame tx status events.
262   virtual void SubscribeFrameTxStatusEvent(
263       uint32_t interface_index, OnFrameTxStatusEventHandler handler);
264 
265   // Cancel the sign-up of receiving frame tx status events.
266   virtual void UnsubscribeFrameTxStatusEvent(uint32_t interface_index);
267 
268   virtual bool SendMgmtFrame(uint32_t interface_index,
269     const std::vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie);
270 
271   // Visible for testing.
272   bool supports_split_wiphy_dump_;
273 
274  private:
275   bool ParseWiphyInfoFromPacket(
276       const NL80211Packet& packet,
277       BandInfo* out_band_info,
278       ScanCapabilities* out_scan_capabilities,
279       WiphyFeatures* out_wiphy_features);
280   bool ParseBandInfo(const NL80211Packet* const packet,
281                      BandInfo* out_band_info);
282   bool ParseScanCapabilities(const NL80211Packet* const packet,
283                              ScanCapabilities* out_scan_capabilities);
284 
285   bool MergePacketsForSplitWiphyDump(
286       const std::vector<std::unique_ptr<const NL80211Packet>>& split_dump_info,
287       std::vector<NL80211Packet>* packet_per_wiphy);
288 
289   NetlinkManager* netlink_manager_;
290 
291   DISALLOW_COPY_AND_ASSIGN(NetlinkUtils);
292 };
293 
294 }  // namespace wificond
295 }  // namespace android
296 
297 #endif  // WIFICOND_NET_NETLINK_UTILS_H_
298