bool ScanUtils::Scan(uint32_t interface_index,
bool request_random_mac,
const vector<vector<uint8_t>>& ssids,
- const vector<uint32_t>& freqs) {
+ const vector<uint32_t>& freqs,
+ int* error_code) {
NL80211Packet trigger_scan(
netlink_manager_->GetFamilyId(),
NL80211_CMD_TRIGGER_SCAN,
// scan results here, so it is OK to expect a timely response because
// kernel is supposed to send the ERROR/ACK back before the scan starts.
vector<unique_ptr<const NL80211Packet>> response;
- if (!netlink_manager_->SendMessageAndGetAck(trigger_scan)) {
- LOG(ERROR) << "NL80211_CMD_TRIGGER_SCAN failed";
+ if (!netlink_manager_->SendMessageAndGetAckOrError(trigger_scan,
+ error_code)) {
+ // Logging is done inside |SendMessageAndGetAckOrError|.
+ return false;
+ }
+ if (*error_code != 0) {
+ LOG(ERROR) << "NL80211_CMD_TRIGGER_SCAN failed: " << strerror(*error_code);
return false;
}
return true;
bool request_random_mac,
const std::vector<std::vector<uint8_t>>& scan_ssids,
const std::vector<std::vector<uint8_t>>& match_ssids,
- const std::vector<uint32_t>& freqs) {
+ const std::vector<uint32_t>& freqs,
+ int* error_code) {
NL80211Packet start_sched_scan(
netlink_manager_->GetFamilyId(),
NL80211_CMD_START_SCHED_SCAN,
}
vector<unique_ptr<const NL80211Packet>> response;
- if (!netlink_manager_->SendMessageAndGetAck(start_sched_scan)) {
- LOG(ERROR) << "NL80211_CMD_START_SCHED_SCAN failed";
+ if (!netlink_manager_->SendMessageAndGetAckOrError(start_sched_scan,
+ error_code)) {
+ // Logging is done inside |SendMessageAndGetAckOrError|.
+ return false;
+ }
+ if (*error_code != 0) {
+ LOG(ERROR) << "NL80211_CMD_START_SCHED_SCAN failed: " << strerror(*error_code);
return false;
}
// 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,
const std::vector<std::vector<uint8_t>>& ssids,
- const std::vector<uint32_t>& freqs);
+ 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.
// If |freqs| is an empty vector, it will scan all supported frequencies.
// Only BSSs match the |match_ssids| and |rssi_threshold| will be returned as
// scan results.
+ // |error_code| contains the errno kernel replied when this returns false.
// Returns true on success.
virtual bool StartScheduledScan(
uint32_t interface_index,
bool request_random_mac,
const std::vector<std::vector<uint8_t>>& scan_ssids,
const std::vector<std::vector<uint8_t>>& match_ssids,
- const std::vector<uint32_t>& freqs);
+ const std::vector<uint32_t>& freqs,
+ int* error_code);
// Stop existing scheduled scan on interface with index |interface_index|.
// Returns true on success.
freqs.push_back(channel.frequency_);
}
- if (!scan_utils_->Scan(interface_index_, request_random_mac, ssids, freqs)) {
+ int error_code = 0;
+ if (!scan_utils_->Scan(interface_index_, request_random_mac, ssids, freqs,
+ &error_code)) {
+ CHECK(error_code != ENODEV) << "Driver is in a bad state, restarting wificond";
*out_success = false;
return Status::ok();
}
bool request_random_mac = wiphy_features_.supports_random_mac_sched_scan &&
!client_interface_->IsAssociated();
+ int error_code = 0;
if (!scan_utils_->StartScheduledScan(interface_index_,
pno_settings.interval_ms_,
// TODO: honor both rssi thresholds.
request_random_mac,
scan_ssids,
match_ssids,
- freqs)) {
+ freqs,
+ &error_code)) {
LOG(ERROR) << "Failed to start pno scan";
+ CHECK(error_code != ENODEV) << "Driver is in a bad state, restarting wificond";
return false;
}
LOG(INFO) << "Pno scan started";
uint32_t interface_index,
std::vector<::com::android::server::wifi::wificond::NativeScanResult>* out_scan_results));
- MOCK_METHOD4(Scan, bool(
+ MOCK_METHOD5(Scan, bool(
uint32_t interface_index,
bool random_mac,
const std::vector<std::vector<uint8_t>>& ssids,
- const std::vector<uint32_t>& freqs));
+ const std::vector<uint32_t>& freqs,
+ int* error_code));
MOCK_METHOD2(SubscribeScanResultNotification,void(
uint32_t interface_index,
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
- EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {}));
+ int errno_ignored;
+ EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {},
+ &errno_ignored));
// TODO(b/34231420): Add validation of requested scan ssids, threshold,
// and frequencies.
}
DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
- EXPECT_FALSE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {}));
+ int error_code;
+ EXPECT_FALSE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {},
+ &error_code));
+ EXPECT_EQ(kFakeErrorCode, error_code);
}
TEST_F(ScanUtilsTest, CanSendSchedScanRequest) {
DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
+ int errno_ignored;
EXPECT_TRUE(scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
kFakeScheduledScanIntervalMs,
- kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {}));
+ kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {}, &errno_ignored));
// TODO(b/34231420): Add validation of requested scan ssids, threshold,
// and frequencies.
}
DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
+ int error_code;
EXPECT_FALSE(scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
kFakeScheduledScanIntervalMs,
- kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {}));
+ kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {}, &error_code));
+ EXPECT_EQ(kFakeErrorCode, error_code);
}
} // namespace wificond