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_SCANNING_SCAN_UTILS_H_
18 #define WIFICOND_SCANNING_SCAN_UTILS_H_
19 
20 #include <memory>
21 #include <vector>
22 
23 #include <android-base/macros.h>
24 
25 #include "wificond/net/netlink_manager.h"
26 
27 namespace android {
28 namespace net {
29 namespace wifi {
30 namespace nl80211 {
31 
32 class NativeScanResult;
33 class RadioChainInfo;
34 
35 }  // namespace nl80211
36 }  // namespace wifi
37 }  // namespace net
38 }  // namespace android
39 
40 namespace android {
41 namespace wificond {
42 
43 class NL80211NestedAttr;
44 class NL80211Packet;
45 
46 struct SchedScanIntervalSetting {
47   struct ScanPlan {
48     uint32_t interval_ms;
49     uint32_t n_iterations;
50   };
51   std::vector<ScanPlan> plans;
52   // After |plans| has been exhausted, scan at every
53   // |final_interval_ms|.
54   uint32_t final_interval_ms{0};
55 };
56 
57 struct SchedScanReqFlags {
58   bool request_random_mac;
59   bool request_low_power;
60   bool request_sched_scan_relative_rssi;
61 };
62 
63 // Provides scanning helper functions.
64 class ScanUtils {
65  public:
66   explicit ScanUtils(NetlinkManager* netlink_manager);
67   virtual ~ScanUtils();
68 
69   // Send 'get scan results' request to kernel and get the latest scan results.
70   // |interface_index| is the index of interface we want to get scan results
71   // from.
72   // A vector of ScanResult object will be returned by |*out_scan_results|.
73   // Returns true on success.
74   virtual bool GetScanResult(
75       uint32_t interface_index,
76       std::vector<android::net::wifi::nl80211::NativeScanResult>* out_scan_results);
77 
78   // Send scan request to kernel for interface with index |interface_index|.
79   // - |request_random_mac| If true, request device/driver to use a random MAC
80   // address during scan. Requires |supports_random_mac_sched_scan|
81   // address during scan.
82   // - |scan_type| Type of scan to perform. One of,
83   // |SCAN_TYPE_LOW_SPAN| (prioritize to reduce latency over other scan
84   // performance attributes),
85   // |SCAN_TYPE_LOW_POWER| (prioritize to reduce power consumption over other
86   // scan performance attributes),
87   // |SCAN_TYPE_HIGH_ACCURACY| (prioritize to increase accuracy over other scan
88   // performance atrributes) OR
89   // |SCAN_TYPE_DEFAULT| (no prioritization).
90   // - |enable_6ghz_rnr| Whether to scan for collocated 6Ghz APs reported by by 2.4/5Ghz APs.
91   // - |ssids| is a vector of ssids we request to scan, which mostly is used
92   // for hidden networks.
93   // If |ssids| is an empty vector, it will do a passive scan.
94   // If |ssids| contains an empty string, it will a scan for all ssids.
95   // - |freqs| is a vector of frequencies we request to scan.
96   // If |freqs| is an empty vector, it will scan all supported frequencies.
97   // - |vendor_ies| is a vector of vendor ies we add it in probe req.
98   // - |error_code| contains the errno kernel replied when this returns false.
99   // Returns true on success.
100   virtual bool Scan(uint32_t interface_index,
101                     bool request_random_mac,
102                     int scan_type,
103                     bool enable_6ghz_rnr,
104                     const std::vector<std::vector<uint8_t>>& ssids,
105                     const std::vector<uint32_t>& freqs,
106                     const std::vector<uint8_t>& vendor_ies,
107                     int* error_code);
108 
109   // Send scan request to kernel for interface with index |interface_index|.
110   // - |inteval_ms| is the expected scan interval in milliseconds.
111   // - |rssi_threshold_2g| is the minimum RSSI threshold value as a filter for
112   // 2GHz band.
113   // - |rssi_threshold_5g| is the minimum RSSI threshold value as a filter for
114   // 5GHz band.
115   // - |scan_ssids| is a vector of ssids we request to scan, which is mostly
116   // used for hidden networks.
117   // - |request_random_mac| If true, request device/driver to use a random MAC
118   // address during scan. Requires |supports_random_mac_sched_scan|
119   // - |request_low_power|: If true, prioritize power consumption over
120   // other scan performance attributes.
121   // Requires |supports_low_power_oneshot_scan|.
122   // - |request_sched_scan_relative_rssi| is sched_scan flag for better BSS's from connected BSS.
123   // If |request_sched_scan_relative_rssi| is true, it will fill scan rssi adjust to
124   // get BSS's with better RSSI from connected BSS.
125   // - |scan_ssids| is the list of ssids to actively scan for.
126   // If |scan_ssids| is an empty vector, it will do a passive scan.
127   // If |scan_ssids| contains an empty string, it will a scan for all ssids.
128   // - |match_ssids| is the list of ssids that we want to add as filters.
129   // - |freqs| is a vector of frequencies we request to scan.
130   // If |freqs| is an empty vector, it will scan all supported frequencies.
131   // - |error_code| contains the errno kernel replied when this returns false.
132   // Only BSSs match the |match_ssids| and |rssi_threshold| will be returned as
133   // scan results.
134   // Returns true on success.
135   virtual bool StartScheduledScan(
136       uint32_t interface_index,
137       const SchedScanIntervalSetting& interval_setting,
138       int32_t rssi_threshold_2g,
139       int32_t rssi_threshold_5g,
140       int32_t rssi_threshold_6g,
141       const SchedScanReqFlags& req_flags,
142       const std::vector<std::vector<uint8_t>>& scan_ssids,
143       const std::vector<std::vector<uint8_t>>& match_ssids,
144       const std::vector<uint32_t>& freqs,
145       int* error_code);
146 
147   // Stop existing scheduled scan on interface with index |interface_index|.
148   // Returns true on success.
149   // Returns false on error or when there is no scheduled scan running.
150   virtual bool StopScheduledScan(uint32_t interface_index);
151 
152   // Abort ongoing single scan on interface with index |interface_index|.
153   // Returns true on success.
154   virtual bool AbortScan(uint32_t interface_index);
155 
156   // Visible for testing.
157   // Get a timestamp for the scan result |bss| represents.
158   // This timestamp records the time passed since boot when last time the
159   // AP was seen.
160   virtual bool GetBssTimestampForTesting(
161       const NL80211NestedAttr& bss,
162        uint64_t* last_seen_since_boot_microseconds);
163 
164   // Sign up to be notified when new scan results are available.
165   // |handler| will be called when the kernel signals to wificond that a scan
166   // has been completed on the given |interface_index|.  See the declaration of
167   // OnScanResultsReadyHandler for documentation on the semantics of this
168   // callback.
169   virtual void SubscribeScanResultNotification(
170       uint32_t interface_index,
171       OnScanResultsReadyHandler handler);
172 
173   // Cancel the sign-up of receiving new scan result notification from
174   // interface with index |interface_index|.
175   virtual void UnsubscribeScanResultNotification(uint32_t interface_index);
176 
177   // Sign up to be notified when new scan results are available.
178   // |handler| will be called when the kernel signals to wificond that a
179   // scheduled scan has been completed on the given |interface_index|.
180   // See the declaration of OnSchedScanResultsReadyHandler for documentation
181   // on the semantics of this callback.
182   virtual void SubscribeSchedScanResultNotification(
183       uint32_t interface_index,
184       OnSchedScanResultsReadyHandler handler);
185 
186   // Cancel the sign-up of receiving new scheduled scan result notification from
187   // interface with index |interface_index|.
188   virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index);
189 
190  private:
191   bool GetBssTimestamp(const NL80211NestedAttr& bss,
192                        uint64_t* last_seen_since_boot_microseconds);
193   bool ParseRadioChainInfos(
194       const NL80211NestedAttr& bss,
195       std::vector<android::net::wifi::nl80211::RadioChainInfo>
196         *radio_chain_infos);
197   bool GetSSIDFromInfoElement(const std::vector<uint8_t>& ie,
198                               std::vector<uint8_t>* ssid);
199   // Converts a NL80211_CMD_NEW_SCAN_RESULTS packet to a ScanResult object.
200   bool ParseScanResult(
201       std::unique_ptr<const NL80211Packet> packet,
202       android::net::wifi::nl80211::NativeScanResult* scan_result);
203 
204   NetlinkManager* netlink_manager_;
205 
206   DISALLOW_COPY_AND_ASSIGN(ScanUtils);
207 };
208 
209 }  // namespace wificond
210 }  // namespace android
211 
212 #endif  // WIFICOND_SCANNING_SCAN_UTILS_H_
213