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