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