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 // Provides scanning helper functions. 60 class 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