我们通过代码分析wificond的scan流程,在WifiScanningService的startScan流程分析中我们分析了HAL层以上的流程,下面我们继续分析HAL层的流程,首先是ScannerImpl的scan方法:
//system/connectivity/wificond/scanning/ScannerImpl.h
class ScannerImpl : public android::net::wifi::nl80211::BnWifiScannerImpl {
private:
ScanUtils* const scan_utils_;
}
//system/connectivity/wificond/scanning/ScannerImpl.cpp
class ScannerImpl : public android::net::wifi::nl80211::BnWifiScannerImpl {
Status ScannerImpl::scan(const SingleScanSettings& scan_settings,
bool* out_success) {
if (!CheckIsValid()) {
*out_success = false;
return Status::ok();
}
if (scan_started_) {
LOG(WARNING) << "Scan already started";
}
// Only request MAC address randomization when station is not associated.
bool request_random_mac =
wiphy_features_.supports_random_mac_oneshot_scan &&
!client_interface_->IsAssociated();
int scan_type = scan_settings.scan_type_;
//wiphy_features_是硬件层直接返回的当前WLAN芯片支持的扫描类型
//如果请求的类型不被硬件支持,则回落为SCAN_TYPE_DEFAULT
if (!IsScanTypeSupported(scan_settings.scan_type_, wiphy_features_)) {
LOG(DEBUG) << "Ignoring scan type because device does not support it";
scan_type = SCAN_TYPE_DEFAULT;
}
// Initialize it with an empty ssid for a wild card scan.
vector<vector<uint8_t>> ssids = {
{}};
//wiphy_features_是硬件层直接返回的当前WLAN芯片支持的扫描类型
//如果请求的类型不被硬件支持,则回落为SCAN_TYPE_DEFAULT
vector<vector<uint8_t>> skipped_scan_ssids;
vector<vector<uint8_t>> skipped_long_ssids;
for (auto& network : scan_settings.hidden_networks_) {
if (ssids.size() + 1 > scan_capabilities_.max_num_scan_ssids) {
skipped_scan_ssids.emplace_back(network.ssid_);
continue;
}
if (network.ssid_.size() > 32) {
skipped_long_ssids.emplace_back(network.ssid_);
continue;
}
ssids.push_back(network.ssid_);
}
LogSsidList(skipped_scan_ssids, "Skip scan ssid for single scan");
LogSsidList(skipped_long_ssids, "Skip too long ssid");
//将扫描需要覆盖的信道频率添加到freqs向量中
vector<uint32_t> freqs;
for (auto& channel : scan_settings.channel_settings_) {
freqs.push_back(channel.frequency_);
}
int error_code = 0;
if (!scan_utils_->Scan(interface_index_, request_random_mac, scan_type,
scan_settings.enable_6ghz_rnr_, ssids, freqs, &error_code)) { //调用ScanUtils的Scan方法
if (error_code == ENODEV) {
nodev_counter_ ++;
LOG(WARNING) << "Scan failed with error=nodev. counter=" << nodev_counter_;
}
CHECK(error_code != ENODEV || nodev_counter_ <= 3)
<< "Driver is in a bad state, restarting wificond";
*out_success = false;
return Status::ok();
}
nodev_counter_ = 0;
scan_started_