OSDN Git Service

Restart wificond on ENODEV scan failure
authorNingyuan Wang <nywang@google.com>
Mon, 26 Jun 2017 22:14:03 +0000 (22:14 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Mon, 26 Jun 2017 22:14:03 +0000 (22:14 +0000)
am: 793978cb7f

Change-Id: Iec003a60e0c3abf0ad3fd7909a1cc74d14555cec

scanning/scan_utils.cpp
scanning/scan_utils.h
scanning/scanner_impl.cpp
tests/mock_scan_utils.h
tests/scan_utils_unittest.cpp

index 5199e2b..21b6f82 100644 (file)
@@ -220,7 +220,8 @@ bool ScanUtils::GetSSIDFromInfoElement(const vector<uint8_t>& ie,
 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,
@@ -261,8 +262,13 @@ bool ScanUtils::Scan(uint32_t interface_index,
   // 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;
@@ -323,7 +329,8 @@ bool ScanUtils::StartScheduledScan(
     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,
@@ -374,8 +381,13 @@ bool ScanUtils::StartScheduledScan(
   }
 
   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;
   }
 
index 84baeec..d4617c7 100644 (file)
@@ -69,11 +69,13 @@ class ScanUtils {
   // 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.
@@ -91,6 +93,7 @@ class ScanUtils {
   // 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,
@@ -99,7 +102,8 @@ class ScanUtils {
       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.
index 9033dc1..7beef34 100644 (file)
@@ -204,7 +204,10 @@ Status ScannerImpl::scan(const SingleScanSettings& scan_settings,
     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();
   }
@@ -297,6 +300,7 @@ bool ScannerImpl::StartPnoScanDefault(const PnoSettings& pno_settings) {
   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.
@@ -304,8 +308,10 @@ bool ScannerImpl::StartPnoScanDefault(const PnoSettings& pno_settings) {
                                        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";
index 4f9e461..8a60888 100644 (file)
@@ -33,11 +33,12 @@ class MockScanUtils : public ScanUtils {
       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,
index 3dbfe21..a76ede5 100644 (file)
@@ -130,7 +130,9 @@ TEST_F(ScanUtilsTest, CanSendScanRequest) {
               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.
 }
@@ -143,7 +145,10 @@ TEST_F(ScanUtilsTest, CanHandleScanRequestFailure) {
           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) {
@@ -154,10 +159,11 @@ 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.
 }
@@ -170,10 +176,12 @@ TEST_F(ScanUtilsTest, CanHandleSchedScanRequestFailure) {
            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