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