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 #include "wificond/net/nl80211_packet.h"
32 
33 namespace android {
34 namespace wificond {
35 
36 struct InterfaceInfo {
37   InterfaceInfo() = default;
InterfaceInfoInterfaceInfo38   InterfaceInfo(uint32_t if_index,
39                 uint32_t wiphy_index,
40                 const std::string& name,
41                 const std::array<uint8_t, ETH_ALEN>& mac_address)
42       : if_index(if_index),
43         wiphy_index(wiphy_index),
44         name(name),
45         mac_address(mac_address) {}
46   // Index of this interface.
47   uint32_t if_index;
48   // Wiphy Index of this interface.
49   uint32_t wiphy_index;
50   // Name of this interface.
51   std::string name;
52   // MAC address of this interface.
53   std::array<uint8_t, ETH_ALEN> mac_address;
54 };
55 
56 struct BandInfo {
BandInfoBandInfo57   BandInfo():
58       is_80211n_supported(false),
59       is_80211ac_supported(false),
60       is_80211ax_supported(false),
61       is_80211be_supported(false),
62       is_160_mhz_supported(false),
63       is_80p80_mhz_supported(false),
64       is_320_mhz_supported(false),
65       max_tx_streams(1),
66       max_rx_streams(1) {};
67   // Frequencies for 2.4 GHz band.
68   std::vector<uint32_t> band_2g;
69   // Frequencies for 5 GHz band without DFS.
70   std::vector<uint32_t> band_5g;
71   // Frequencies for DFS.
72   std::vector<uint32_t> band_dfs;
73   // Frequencies for 6 GHz band.
74   std::vector<uint32_t> band_6g;
75   // Frequencies for 60 GHz band.
76   std::vector<uint32_t> band_60g;
77   // support for 802.11n
78   bool is_80211n_supported;
79   // support for 802.11ac
80   bool is_80211ac_supported;
81   // support for 802.11ax
82   bool is_80211ax_supported;
83   // support for 802.11be
84   bool is_80211be_supported;
85   // support for 160Mhz channel width
86   bool is_160_mhz_supported;
87   // support for 80+80Mhz channel width
88   bool is_80p80_mhz_supported;
89   // support for 320Mhz channel width
90   bool is_320_mhz_supported;
91   // Max number of transmit spatial streams
92   uint32_t max_tx_streams;
93   // Max number of receive spatial streams
94   uint32_t max_rx_streams;
95 };
96 
97 struct ScanCapabilities {
98   ScanCapabilities() = default;
ScanCapabilitiesScanCapabilities99   ScanCapabilities(uint8_t max_num_scan_ssids_,
100                    uint8_t max_num_sched_scan_ssids_,
101                    uint8_t max_match_sets_,
102                    uint32_t max_num_scan_plans_,
103                    uint32_t max_scan_plan_interval_,
104                    uint32_t max_scan_plan_iterations_)
105       : max_num_scan_ssids(max_num_scan_ssids_),
106         max_num_sched_scan_ssids(max_num_sched_scan_ssids_),
107         max_match_sets(max_match_sets_),
108         max_num_scan_plans(max_num_scan_plans_),
109         max_scan_plan_interval(max_scan_plan_interval_),
110         max_scan_plan_iterations(max_scan_plan_iterations_) {}
111   // Number of SSIDs you can scan with a single scan request.
112   uint8_t max_num_scan_ssids;
113   // Number of SSIDs you can scan with a single scheduled scan request.
114   uint8_t max_num_sched_scan_ssids;
115   // Maximum number of sets that can be used with NL80211_ATTR_SCHED_SCAN_MATCH.
116   uint8_t max_match_sets;
117   // Maximum number of scan plans that can be specified.
118   uint32_t max_num_scan_plans;
119   // Maximum interval in seconds for a particular scan plan that can be
120   // specified.
121   uint32_t max_scan_plan_interval;
122   // Maximum number of iterations for a particular scan plan that can be
123   // specified.
124   uint32_t max_scan_plan_iterations;
125 };
126 
127 struct WiphyFeatures {
WiphyFeaturesWiphyFeatures128   WiphyFeatures()
129       : supports_random_mac_oneshot_scan(false),
130         supports_random_mac_sched_scan(false),
131         supports_low_span_oneshot_scan(false),
132         supports_low_power_oneshot_scan(false),
133         supports_high_accuracy_oneshot_scan(false),
134         supports_tx_mgmt_frame_mcs(false) {}
135   WiphyFeatures(uint32_t feature_flags,
136                 const std::vector<uint8_t>& ext_feature_flags_bytes);
137   // This device/driver supports using a random MAC address during scan
138   // (while not associated).
139   bool supports_random_mac_oneshot_scan;
140   // This device/driver supports using a random MAC address for every
141   // scan iteration during scheduled scan (while not associated).
142   bool supports_random_mac_sched_scan;
143   // This device/driver supports performing low-span/low-latency one-shot scans.
144   bool supports_low_span_oneshot_scan;
145   // This device/driver supports performing low-power one-shot scans.
146   bool supports_low_power_oneshot_scan;
147   // This device/driver supports performing high-accuracy one-shot scans.
148   bool supports_high_accuracy_oneshot_scan;
149   // This device/driver supports sending a management frame at a specified MCS.
150   bool supports_tx_mgmt_frame_mcs;
151   // This device/driver supports sched_scan for reporting BSSs
152   // with better RSSI than the current connected BSS
153   bool supports_ext_sched_scan_relative_rssi;
154   // There are other flags included in NL80211_ATTR_FEATURE_FLAGS.
155   // We will add them once we find them useful.
156 };
157 
158 struct DriverCapabilities {
159   DriverCapabilities() = default;
DriverCapabilitiesDriverCapabilities160   DriverCapabilities(uint32_t max_num_akms_)
161       : max_num_akms(max_num_akms_) {}
162   // Maximum number of AKM suites allowed in the connection request to driver.
163   // The value is obtained via NL attribute NL80211_ATTR_MAX_NUM_AKM_SUITES.
164   uint32_t max_num_akms;
165 };
166 
167 struct StationInfo {
168   StationInfo() = default;
StationInfoStationInfo169   StationInfo(uint32_t station_tx_packets_,
170               uint32_t station_tx_failed_,
171               uint32_t station_tx_bitrate_,
172               int8_t current_rssi_,
173               uint32_t station_rx_bitrate_)
174       : station_tx_packets(station_tx_packets_),
175         station_tx_failed(station_tx_failed_),
176         station_tx_bitrate(station_tx_bitrate_),
177         current_rssi(current_rssi_),
178         station_rx_bitrate(station_rx_bitrate_) {}
179   // Number of successfully transmitted packets.
180   int32_t station_tx_packets;
181   // Number of tramsmission failures.
182   int32_t station_tx_failed;
183   // Transimission bit rate in 100kbit/s.
184   uint32_t station_tx_bitrate;
185   // Current signal strength.
186   int8_t current_rssi;
187   // Last Received unicast packet bit rate in 100kbit/s.
188   uint32_t station_rx_bitrate;
189   // There are many other counters/parameters included in station info.
190   // We will add them once we find them useful.
191 };
192 
193 class MlmeEventHandler;
194 class NetlinkManager;
195 class NL80211Packet;
196 
197 // Provides NL80211 helper functions.
198 class NetlinkUtils {
199  public:
200   // Currently we only support setting the interface to STATION mode.
201   // This is used for cleaning up interface after KILLING hostapd.
202   enum InterfaceMode{
203       STATION_MODE
204   };
205 
206   explicit NetlinkUtils(NetlinkManager* netlink_manager);
207   virtual ~NetlinkUtils();
208 
209   // Get the wiphy index from kernel.
210   // |*out_wiphy_index| returns the wiphy index from kernel.
211   // Returns true on success.
212   virtual bool GetWiphyIndex(uint32_t* out_wiphy_index);
213   virtual bool GetWiphyIndex(uint32_t* out_wiphy_index,
214                              const std::string& iface_name);
215 
216   // Get wifi interfaces info from kernel.
217   // |wiphy_index| is the wiphy index we get using GetWiphyIndex().
218   // |interface_info| returns a vector of InterfaceInfo structs with
219   // information about all existing interfaces.
220   // Returns true on success.
221   virtual bool GetInterfaces(uint32_t wiphy_index,
222                              std::vector<InterfaceInfo>* interface_info);
223 
224   // Set the mode of interface.
225   // |interface_index| is the interface index.
226   // |mode| is one of the values in |enum InterfaceMode|.
227   // Returns true on success.
228   virtual bool SetInterfaceMode(uint32_t interface_index,
229                                 InterfaceMode mode);
230 
231   // Get wiphy capability information from kernel.
232   // Returns true on success.
233   virtual bool GetWiphyInfo(uint32_t wiphy_index,
234                             BandInfo* out_band_info,
235                             ScanCapabilities* out_scan_capabilities,
236                             WiphyFeatures* out_wiphy_features,
237                             DriverCapabilities* out_driver_capabilities);
238 
239   // Get station info from kernel.
240   // |*out_station_info]| is the struct of available station information.
241   // Returns true on success.
242   virtual bool GetStationInfo(uint32_t interface_index,
243                               const std::array<uint8_t, ETH_ALEN>& mac_address,
244                               StationInfo* out_station_info);
245 
246   // Get a bitmap for nl80211 protocol features,
247   // i.e. features for the nl80211 protocol rather than device features.
248   // See enum nl80211_protocol_features in nl80211.h for decoding the bitmap.
249   // Returns true on success.
250   virtual bool GetProtocolFeatures(uint32_t* features);
251 
252   // Get current alpha2 country code from kernel.
253   // Returns true on success.
254   virtual bool GetCountryCode(uint32_t wiphy_index,
255                               std::string* out_country_code);
256 
257   // Sign up to be notified when there is MLME event.
258   // Only one handler can be registered per interface index.
259   // New handler will replace the registered handler if they are for the
260   // same interface index.
261   // NetlinkUtils is not going to take ownership of this pointer, and that it
262   // is the caller's responsibility to make sure that the object exists for the
263   // duration of the subscription.
264   virtual void SubscribeMlmeEvent(uint32_t interface_index,
265                                   MlmeEventHandler* handler);
266 
267   // Cancel the sign-up of receiving MLME event notification
268   // from interface with index |interface_index|.
269   virtual void UnsubscribeMlmeEvent(uint32_t interface_index);
270 
271   // Sign up to be notified when there is an regulatory domain change.
272   // Only one handler can be registered per wiphy index.
273   // New handler will replace the registered handler if they are for the
274   // same wiphy index.
275   virtual void SubscribeRegDomainChange(uint32_t wiphy_index,
276                                         OnRegDomainChangedHandler handler);
277 
278   // Cancel the sign-up of receiving regulatory domain change notification
279   // from wiphy with index |wiphy_index|.
280   virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index);
281 
282   // Sign up to be notified when there is a station event.
283   // Only one handler can be registered per interface index.
284   // New handler will replace the registered handler if they are for the
285   // same interface index.
286   virtual void SubscribeStationEvent(uint32_t interface_index,
287                                      OnStationEventHandler handler);
288 
289   // Cancel the sign-up of receiving station events.
290   virtual void UnsubscribeStationEvent(uint32_t interface_index);
291 
292   // Sign up to be notified when there is a channel switch event.
293   // Only one handler can be registered per interface index.
294   // New handler will replace the registered handler if they are for the
295   // same interface index.
296   virtual void SubscribeChannelSwitchEvent(uint32_t interface_index,
297                                            OnChannelSwitchEventHandler handler);
298 
299   // Cancel the sign-up of receiving channel switch events.
300   virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index);
301 
302   // Sign up to be notified of frame tx status events.
303   virtual void SubscribeFrameTxStatusEvent(
304       uint32_t interface_index, OnFrameTxStatusEventHandler handler);
305 
306   // Cancel the sign-up of receiving frame tx status events.
307   virtual void UnsubscribeFrameTxStatusEvent(uint32_t interface_index);
308 
309   virtual bool SendMgmtFrame(uint32_t interface_index,
310     const std::vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie);
311 
312   // Visible for testing.
313   bool supports_split_wiphy_dump_;
314 
315  private:
316   bool ParseWiphyInfoFromPacket(
317       const NL80211Packet& packet,
318       BandInfo* out_band_info,
319       ScanCapabilities* out_scan_capabilities,
320       WiphyFeatures* out_wiphy_features,
321       DriverCapabilities* out_driver_capabilities);
322   bool ParseBandInfo(const NL80211Packet* const packet,
323                      BandInfo* out_band_info);
324   void ParseIfTypeDataAttributes(const NL80211NestedAttr& iftype_data_attr,
325                                  BandInfo* out_band_info);
326   void ParseHtVhtPhyCapabilities(const NL80211NestedAttr& band,
327                                  BandInfo* out_band_info);
328   void ParseHtMcsSetAttribute(const NL80211NestedAttr& band,
329                               BandInfo* out_band_info);
330   void ParseVhtMcsSetAttribute(const NL80211NestedAttr& band,
331                                BandInfo* out_band_info);
332   void ParseHeMcsSetAttribute(const NL80211NestedAttr& attribute,
333                               BandInfo* out_band_info);
334   std::pair<uint32_t, uint32_t> ParseHtMcsSet(
335       const std::vector<uint8_t>& ht_mcs_set);
336   uint32_t ParseMcsMap(uint16_t mcs_map);
337   void ParseVhtCapAttribute(const NL80211NestedAttr& band,
338                             BandInfo* out_band_info);
339   void ParseHeCapPhyAttribute(const NL80211NestedAttr& attribute,
340                               BandInfo* out_band_info);
341   void ParseEhtCapPhyAttribute(const NL80211NestedAttr& attribute,
342                               BandInfo* out_band_info);
343 
344   bool ParseScanCapabilities(const NL80211Packet* const packet,
345                              ScanCapabilities* out_scan_capabilities);
346 
347   bool MergePacketsForSplitWiphyDump(
348       const std::vector<std::unique_ptr<const NL80211Packet>>& split_dump_info,
349       std::vector<NL80211Packet>* packet_per_wiphy);
350   void handleBandFreqAttributes(const NL80211NestedAttr& freqs_attr,
351       BandInfo* out_band_info);
352 
353   NetlinkManager* netlink_manager_;
354 
355   DISALLOW_COPY_AND_ASSIGN(NetlinkUtils);
356 };
357 
358 }  // namespace wificond
359 }  // namespace android
360 
361 #endif  // WIFICOND_NET_NETLINK_UTILS_H_
362