summaryrefslogtreecommitdiff
path: root/scanning/scan_utils.h
blob: 3ac7f4a10e82b1340d2734d663ceaa2e03da611d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef WIFICOND_SCANNING_SCAN_UTILS_H_
#define WIFICOND_SCANNING_SCAN_UTILS_H_

#include <memory>
#include <vector>

#include <android-base/macros.h>

#include "wificond/net/netlink_manager.h"

namespace android {
namespace net {
namespace wifi {
namespace nl80211 {

class NativeScanResult;
class RadioChainInfo;

}  // namespace nl80211
}  // namespace wifi
}  // namespace net
}  // namespace android

namespace android {
namespace wificond {

class NL80211NestedAttr;
class NL80211Packet;

struct SchedScanIntervalSetting {
  struct ScanPlan {
    uint32_t interval_ms;
    uint32_t n_iterations;
  };
  std::vector<ScanPlan> plans;
  // After |plans| has been exhausted, scan at every
  // |final_interval_ms|.
  uint32_t final_interval_ms{0};
};

struct SchedScanReqFlags {
  bool request_random_mac;
  bool request_low_power;
  bool request_sched_scan_relative_rssi;
};

// Provides scanning helper functions.
class ScanUtils {
 public:
  explicit ScanUtils(NetlinkManager* netlink_manager);
  virtual ~ScanUtils();

  // Send 'get scan results' request to kernel and get the latest scan results.
  // |interface_index| is the index of interface we want to get scan results
  // from.
  // A vector of ScanResult object will be returned by |*out_scan_results|.
  // Returns true on success.
  virtual bool GetScanResult(
      uint32_t interface_index,
      std::vector<android::net::wifi::nl80211::NativeScanResult>* out_scan_results);

  // Send scan request to kernel for interface with index |interface_index|.
  // - |request_random_mac| If true, request device/driver to use a random MAC
  // address during scan. Requires |supports_random_mac_sched_scan|
  // address during scan.
  // - |scan_type| Type of scan to perform. One of,
  // |SCAN_TYPE_LOW_SPAN| (prioritize to reduce latency over other scan
  // performance attributes),
  // |SCAN_TYPE_LOW_POWER| (prioritize to reduce power consumption over other
  // scan performance attributes),
  // |SCAN_TYPE_HIGH_ACCURACY| (prioritize to increase accuracy over other scan
  // performance atrributes) OR
  // |SCAN_TYPE_DEFAULT| (no prioritization).
  // - |enable_6ghz_rnr| Whether to scan for collocated 6Ghz APs reported by by 2.4/5Ghz APs.
  // - |ssids| is a vector of ssids we request to scan, which mostly is used
  // for hidden networks.
  // If |ssids| is an empty vector, it will do a passive scan.
  // If |ssids| contains an empty string, it will a scan for all ssids.
  // - |freqs| is a vector of frequencies we request to scan.
  // If |freqs| is an empty vector, it will scan all supported frequencies.
  // - |error_code| contains the errno kernel replied when this returns false.
  // Returns true on success.
  virtual bool Scan(uint32_t interface_index,
                    bool request_random_mac,
                    int scan_type,
                    bool enable_6ghz_rnr,
                    const std::vector<std::vector<uint8_t>>& ssids,
                    const std::vector<uint32_t>& freqs,
                    int* error_code);

  // Send scan request to kernel for interface with index |interface_index|.
  // - |inteval_ms| is the expected scan interval in milliseconds.
  // - |rssi_threshold_2g| is the minimum RSSI threshold value as a filter for
  // 2GHz band.
  // - |rssi_threshold_5g| is the minimum RSSI threshold value as a filter for
  // 5GHz band.
  // - |scan_ssids| is a vector of ssids we request to scan, which is mostly
  // used for hidden networks.
  // - |request_random_mac| If true, request device/driver to use a random MAC
  // address during scan. Requires |supports_random_mac_sched_scan|
  // - |request_low_power|: If true, prioritize power consumption over
  // other scan performance attributes.
  // Requires |supports_low_power_oneshot_scan|.
  // - |request_sched_scan_relative_rssi| is sched_scan flag for better BSS's from connected BSS.
  // If |request_sched_scan_relative_rssi| is true, it will fill scan rssi adjust to
  // get BSS's with better RSSI from connected BSS.
  // - |scan_ssids| is the list of ssids to actively scan for.
  // If |scan_ssids| is an empty vector, it will do a passive scan.
  // If |scan_ssids| contains an empty string, it will a scan for all ssids.
  // - |match_ssids| is the list of ssids that we want to add as filters.
  // - |freqs| is a vector of frequencies we request to scan.
  // If |freqs| is an empty vector, it will scan all supported frequencies.
  // - |error_code| contains the errno kernel replied when this returns false.
  // Only BSSs match the |match_ssids| and |rssi_threshold| will be returned as
  // scan results.
  // Returns true on success.
  virtual bool StartScheduledScan(
      uint32_t interface_index,
      const SchedScanIntervalSetting& interval_setting,
      int32_t rssi_threshold_2g,
      int32_t rssi_threshold_5g,
      int32_t rssi_threshold_6g,
      const SchedScanReqFlags& req_flags,
      const std::vector<std::vector<uint8_t>>& scan_ssids,
      const std::vector<std::vector<uint8_t>>& match_ssids,
      const std::vector<uint32_t>& freqs,
      int* error_code);

  // Stop existing scheduled scan on interface with index |interface_index|.
  // Returns true on success.
  // Returns false on error or when there is no scheduled scan running.
  virtual bool StopScheduledScan(uint32_t interface_index);

  // Abort ongoing single scan on interface with index |interface_index|.
  // Returns true on success.
  virtual bool AbortScan(uint32_t interface_index);

  // Visible for testing.
  // Get a timestamp for the scan result |bss| represents.
  // This timestamp records the time passed since boot when last time the
  // AP was seen.
  virtual bool GetBssTimestampForTesting(
      const NL80211NestedAttr& bss,
       uint64_t* last_seen_since_boot_microseconds);

  // Sign up to be notified when new scan results are available.
  // |handler| will be called when the kernel signals to wificond that a scan
  // has been completed on the given |interface_index|.  See the declaration of
  // OnScanResultsReadyHandler for documentation on the semantics of this
  // callback.
  virtual void SubscribeScanResultNotification(
      uint32_t interface_index,
      OnScanResultsReadyHandler handler);

  // Cancel the sign-up of receiving new scan result notification from
  // interface with index |interface_index|.
  virtual void UnsubscribeScanResultNotification(uint32_t interface_index);

  // Sign up to be notified when new scan results are available.
  // |handler| will be called when the kernel signals to wificond that a
  // scheduled scan has been completed on the given |interface_index|.
  // See the declaration of OnSchedScanResultsReadyHandler for documentation
  // on the semantics of this callback.
  virtual void SubscribeSchedScanResultNotification(
      uint32_t interface_index,
      OnSchedScanResultsReadyHandler handler);

  // Cancel the sign-up of receiving new scheduled scan result notification from
  // interface with index |interface_index|.
  virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index);

 private:
  bool GetBssTimestamp(const NL80211NestedAttr& bss,
                       uint64_t* last_seen_since_boot_microseconds);
  bool ParseRadioChainInfos(
      const NL80211NestedAttr& bss,
      std::vector<android::net::wifi::nl80211::RadioChainInfo>
        *radio_chain_infos);
  bool GetSSIDFromInfoElement(const std::vector<uint8_t>& ie,
                              std::vector<uint8_t>* ssid);
  // Converts a NL80211_CMD_NEW_SCAN_RESULTS packet to a ScanResult object.
  bool ParseScanResult(
      std::unique_ptr<const NL80211Packet> packet,
      android::net::wifi::nl80211::NativeScanResult* scan_result);

  NetlinkManager* netlink_manager_;

  DISALLOW_COPY_AND_ASSIGN(ScanUtils);
};

}  // namespace wificond
}  // namespace android

#endif  // WIFICOND_SCANNING_SCAN_UTILS_H_