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;
34
35}  // namespace wificond
36}  // namespace wifi
37}  // namespace server
38}  // namespace android
39}  // namespace com
40
41namespace android {
42namespace wificond {
43
44class NL80211NestedAttr;
45class NL80211Packet;
46
47struct SchedScanIntervalSetting {
48  struct ScanPlan {
49    uint32_t interval_ms;
50    uint32_t n_iterations;
51  };
52  std::vector<ScanPlan> plans;
53  // After |plans| has been exhausted, scan at every
54  // |final_interval_ms|.
55  uint32_t final_interval_ms{0};
56};
57
58// Provides scanning helper functions.
59class ScanUtils {
60 public:
61  explicit ScanUtils(NetlinkManager* netlink_manager);
62  virtual ~ScanUtils();
63
64  // Send 'get scan results' request to kernel and get the latest scan results.
65  // |interface_index| is the index of interface we want to get scan results
66  // from.
67  // A vector of ScanResult object will be returned by |*out_scan_results|.
68  // Returns true on success.
69  virtual bool GetScanResult(
70      uint32_t interface_index,
71      std::vector<::com::android::server::wifi::wificond::NativeScanResult>* out_scan_results);
72
73  // Send scan request to kernel for interface with index |interface_index|.
74  // |request_random_mac| is used for asking device/driver to use a random MAC
75  // address during scan.
76  // This flag should only be set if kernel supports this feature as
77  // |supports_random_mac_oneshot_scan| indicates.
78  // |ssids| is a vector of ssids we request to scan, which mostly is used
79  // for hidden networks.
80  // If |ssids| is an empty vector, it will do a passive scan.
81  // If |ssids| contains an empty string, it will a scan for all ssids.
82  // |freqs| is a vector of frequencies we request to scan.
83  // If |freqs| is an empty vector, it will scan all supported frequencies.
84  // |error_code| contains the errno kernel replied when this returns false.
85  // Returns true on success.
86  virtual bool Scan(uint32_t interface_index,
87                    bool request_random_mac,
88                    const std::vector<std::vector<uint8_t>>& ssids,
89                    const std::vector<uint32_t>& freqs,
90                    int* error_code);
91
92  // Send scan request to kernel for interface with index |interface_index|.
93  // |inteval_ms| is the expected scan interval in milliseconds.
94  // |rssi_threshold| is the minimum RSSI threshold value as a filter.
95  // |scan_ssids| is a vector of ssids we request to scan, which is mostly
96  // used for hidden networks.
97  // |request_random_mac| is used for asking device/driver to use a random MAC
98  // address during scan.
99  // This flag should only be set if kernel supports this feature as
100  // |supports_random_mac_sched_scan| indicates.
101  // If |scan_ssids| is an empty vector, it will do a passive scan.
102  // If |scan_ssids| contains an empty string, it will a scan for all ssids.
103  // |freqs| is a vector of frequencies we request to scan.
104  // |match_ssids| is the list of ssids that we want to add as filters.
105  // If |freqs| is an empty vector, it will scan all supported frequencies.
106  // Only BSSs match the |match_ssids| and |rssi_threshold| will be returned as
107  // scan results.
108  // |error_code| contains the errno kernel replied when this returns false.
109  // Returns true on success.
110  virtual bool StartScheduledScan(
111      uint32_t interface_index,
112      const SchedScanIntervalSetting& interval_setting,
113      int32_t rssi_threshold,
114      bool request_random_mac,
115      const std::vector<std::vector<uint8_t>>& scan_ssids,
116      const std::vector<std::vector<uint8_t>>& match_ssids,
117      const std::vector<uint32_t>& freqs,
118      int* error_code);
119
120  // Stop existing scheduled scan on interface with index |interface_index|.
121  // Returns true on success.
122  // Returns false on error or when there is no scheduled scan running.
123  virtual bool StopScheduledScan(uint32_t interface_index);
124
125  // Abort ongoing single scan on interface with index |interface_index|.
126  // Returns true on success.
127  virtual bool AbortScan(uint32_t interface_index);
128
129  // Visible for testing.
130  // Get a timestamp for the scan result |bss| represents.
131  // This timestamp records the time passed since boot when last time the
132  // AP was seen.
133  virtual bool GetBssTimestampForTesting(
134      const NL80211NestedAttr& bss,
135       uint64_t* last_seen_since_boot_microseconds);
136
137  // Sign up to be notified when new scan results are available.
138  // |handler| will be called when the kernel signals to wificond that a scan
139  // has been completed on the given |interface_index|.  See the declaration of
140  // OnScanResultsReadyHandler for documentation on the semantics of this
141  // callback.
142  virtual void SubscribeScanResultNotification(
143      uint32_t interface_index,
144      OnScanResultsReadyHandler handler);
145
146  // Cancel the sign-up of receiving new scan result notification from
147  // interface with index |interface_index|.
148  virtual void UnsubscribeScanResultNotification(uint32_t interface_index);
149
150  // Sign up to be notified when new scan results are available.
151  // |handler| will be called when the kernel signals to wificond that a
152  // scheduled scan has been completed on the given |interface_index|.
153  // See the declaration of OnSchedScanResultsReadyHandler for documentation
154  // on the semantics of this callback.
155  virtual void SubscribeSchedScanResultNotification(
156      uint32_t interface_index,
157      OnSchedScanResultsReadyHandler handler);
158
159  // Cancel the sign-up of receiving new scheduled scan result notification from
160  // interface with index |interface_index|.
161  virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index);
162
163 private:
164  bool GetBssTimestamp(const NL80211NestedAttr& bss,
165                       uint64_t* last_seen_since_boot_microseconds);
166  bool GetSSIDFromInfoElement(const std::vector<uint8_t>& ie,
167                              std::vector<uint8_t>* ssid);
168  // Converts a NL80211_CMD_NEW_SCAN_RESULTS packet to a ScanResult object.
169  bool ParseScanResult(
170      std::unique_ptr<const NL80211Packet> packet,
171      ::com::android::server::wifi::wificond::NativeScanResult* scan_result);
172
173  NetlinkManager* netlink_manager_;
174
175  DISALLOW_COPY_AND_ASSIGN(ScanUtils);
176};
177
178}  // namespace wificond
179}  // namespace android
180
181#endif  // WIFICOND_SCANNING_SCAN_UTILS_H_
182