OSDN Git Service

Use new netlink attribute for scan result timestamp
authorNingyuan Wang <nywang@google.com>
Fri, 9 Jun 2017 16:41:21 +0000 (09:41 -0700)
committerNingyuan Wang <nywang@google.com>
Thu, 13 Jul 2017 19:55:42 +0000 (12:55 -0700)
Bug: 37758502
Test: compile, manual test
Test: integration test
Test: manually test that on new and old devices, there should
be only a small portion of scan results filtered out.

Change-Id: I2cbcb6f4c5b58b6a56a746de97afe491a9e338ac

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

index 21b6f82..5f0a6e3 100644 (file)
@@ -151,17 +151,11 @@ bool ScanUtils::ParseScanResult(unique_ptr<const NL80211Packet> packet,
       // These scan results are considered as malformed.
       return false;
     }
-    uint64_t tsf;
-    if (!bss.GetAttributeValue(NL80211_BSS_TSF, &tsf)) {
-      LOG(ERROR) << "Failed to get TSF from scan result packet";
+    uint64_t last_seen_since_boot_microseconds;
+    if (!GetBssTimestamp(bss, &last_seen_since_boot_microseconds)) {
+      // Logging is done inside |GetBssTimestamp|.
       return false;
     }
-    uint64_t beacon_tsf;
-    if (bss.GetAttributeValue(NL80211_BSS_BEACON_TSF, &beacon_tsf)) {
-      if (beacon_tsf > tsf) {
-        tsf = beacon_tsf;
-      }
-    }
     int32_t signal;
     if (!bss.GetAttributeValue(NL80211_BSS_SIGNAL_MBM, &signal)) {
       LOG(ERROR) << "Failed to get Signal Strength from scan result packet";
@@ -181,7 +175,37 @@ bool ScanUtils::ParseScanResult(unique_ptr<const NL80211Packet> packet,
     }
 
     *scan_result =
-        NativeScanResult(ssid, bssid, ie, freq, signal, tsf, capability, associated);
+        NativeScanResult(ssid, bssid, ie, freq, signal,
+                         last_seen_since_boot_microseconds,
+                         capability, associated);
+  }
+  return true;
+}
+
+bool ScanUtils::GetBssTimestampForTesting(
+    const NL80211NestedAttr& bss,
+    uint64_t* last_seen_since_boot_microseconds){
+  return GetBssTimestamp(bss, last_seen_since_boot_microseconds);
+}
+
+bool ScanUtils::GetBssTimestamp(const NL80211NestedAttr& bss,
+                                uint64_t* last_seen_since_boot_microseconds){
+  uint64_t last_seen_since_boot_nanoseconds;
+  if (bss.GetAttributeValue(NL80211_BSS_LAST_SEEN_BOOTTIME,
+                            &last_seen_since_boot_nanoseconds)) {
+    *last_seen_since_boot_microseconds = last_seen_since_boot_nanoseconds / 1000;
+  } else {
+    // Fall back to use TSF if we can't find NL80211_BSS_LAST_SEEN_BOOTTIME
+    // attribute.
+    if (!bss.GetAttributeValue(NL80211_BSS_TSF, last_seen_since_boot_microseconds)) {
+      LOG(ERROR) << "Failed to get TSF from scan result packet";
+      return false;
+    }
+    uint64_t beacon_tsf_microseconds;
+    if (bss.GetAttributeValue(NL80211_BSS_BEACON_TSF, &beacon_tsf_microseconds)) {
+      *last_seen_since_boot_microseconds = std::max(*last_seen_since_boot_microseconds,
+                                                    beacon_tsf_microseconds);
+    }
   }
   return true;
 }
index d4617c7..dbc2556 100644 (file)
@@ -41,6 +41,7 @@ class NativeScanResult;
 namespace android {
 namespace wificond {
 
+class NL80211NestedAttr;
 class NL80211Packet;
 
 // Provides scanning helper functions.
@@ -114,6 +115,14 @@ class ScanUtils {
   // Returns true on success.
   virtual bool AbortScan(uint32_t interface_index);
 
+  // Visible for testing.
+  // Get a timestamp for the scan result |bss| represents.
+  // This timestamp records the time passed since boot when last time the
+  // AP was seen.
+  virtual bool GetBssTimestampForTesting(
+      const NL80211NestedAttr& bss,
+       uint64_t* last_seen_since_boot_microseconds);
+
   // Sign up to be notified when new scan results are available.
   // |handler| will be called when the kernel signals to wificond that a scan
   // has been completed on the given |interface_index|.  See the declaration of
@@ -141,6 +150,8 @@ class ScanUtils {
   virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index);
 
  private:
+  bool GetBssTimestamp(const NL80211NestedAttr& bss,
+                       uint64_t* last_seen_since_boot_microseconds);
   bool GetSSIDFromInfoElement(const std::vector<uint8_t>& ie,
                               std::vector<uint8_t>* ssid);
   // Converts a NL80211_CMD_NEW_SCAN_RESULTS packet to a ScanResult object.
index a76ede5..9e36ab2 100644 (file)
@@ -184,5 +184,65 @@ TEST_F(ScanUtilsTest, CanHandleSchedScanRequestFailure) {
   EXPECT_EQ(kFakeErrorCode, error_code);
 }
 
+TEST_F(ScanUtilsTest, CanPrioritizeLastSeenSinceBootNetlinkAttribute) {
+  constexpr uint64_t kLastSeenTimestampNanoSeconds = 123456;
+  constexpr uint64_t kBssTsfTimestampMicroSeconds = 654321;
+  NL80211NestedAttr bss(NL80211_ATTR_BSS);
+  bss.AddAttribute(
+      NL80211Attr<uint64_t>(NL80211_BSS_LAST_SEEN_BOOTTIME,
+                            kLastSeenTimestampNanoSeconds));
+  bss.AddAttribute(
+      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
+  uint64_t timestamp_microseconds;
+  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
+      bss, &timestamp_microseconds));
+  EXPECT_EQ(kLastSeenTimestampNanoSeconds/1000, timestamp_microseconds);
+}
+
+TEST_F(ScanUtilsTest, CanHandleMissingLastSeenSinceBootNetlinkAttribute) {
+  constexpr uint64_t kBssTsfTimestampMicroSeconds = 654321;
+  NL80211NestedAttr bss(NL80211_ATTR_BSS);
+  bss.AddAttribute(
+      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
+  uint64_t timestamp_microseconds;
+  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
+      bss, &timestamp_microseconds));
+  EXPECT_EQ(kBssTsfTimestampMicroSeconds, timestamp_microseconds);
+}
+
+// Probe TSF is newer.
+TEST_F(ScanUtilsTest, CanPickMostRecentTimestampBetweenBetweenProbeAndBeacon1) {
+  constexpr uint64_t kBssBeaconTsfTimestampMicroSeconds = 654321;
+  constexpr uint64_t kBssTsfTimestampMicroSeconds =
+      kBssBeaconTsfTimestampMicroSeconds + 2000;
+  NL80211NestedAttr bss(NL80211_ATTR_BSS);
+  bss.AddAttribute(
+      NL80211Attr<uint64_t>(NL80211_BSS_BEACON_TSF,
+                            kBssBeaconTsfTimestampMicroSeconds));
+  bss.AddAttribute(
+      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
+  uint64_t timestamp_microseconds;
+  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
+      bss, &timestamp_microseconds));
+  EXPECT_EQ(kBssTsfTimestampMicroSeconds, timestamp_microseconds);
+}
+
+// Beacon TSF is newer.
+TEST_F(ScanUtilsTest, CanPickMostRecentTimestampBetweenBetweenProbeAndBeacon2) {
+  constexpr uint64_t kBssTsfTimestampMicroSeconds = 654321;
+  constexpr uint64_t kBssBeaconTsfTimestampMicroSeconds =
+      kBssTsfTimestampMicroSeconds + 2000;
+  NL80211NestedAttr bss(NL80211_ATTR_BSS);
+  bss.AddAttribute(
+      NL80211Attr<uint64_t>(NL80211_BSS_BEACON_TSF,
+                            kBssBeaconTsfTimestampMicroSeconds));
+  bss.AddAttribute(
+      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
+  uint64_t timestamp_microseconds;
+  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
+      bss, &timestamp_microseconds));
+  EXPECT_EQ(kBssBeaconTsfTimestampMicroSeconds, timestamp_microseconds);
+}
+
 }  // namespace wificond
 }  // namespace android