OSDN Git Service

WifiCond: Invoke OffloadScanManager APIs for PNO scans
authorSohani Rao <sohanirao@google.com>
Thu, 20 Apr 2017 00:39:25 +0000 (17:39 -0700)
committerSohani Rao <sohanirao@google.com>
Sat, 13 May 2017 01:16:44 +0000 (18:16 -0700)
Offload Scan Manager APIs will be used if available. If scans over
Offload fail, scans will be performed over netlink as a fallback.

Bug: 32842314
Test: Unit tests
Change-Id: If48eb0bd1de38c29a2b3a7d461673b1e3502baa5

Android.mk
scanning/offload/offload_scan_manager.cpp
scanning/offload/offload_scan_manager.h
scanning/scanner_impl.cpp
scanning/scanner_impl.h
tests/offload_scan_manager_test.cpp

index 27215f3..385eb54 100644 (file)
@@ -14,6 +14,9 @@
 
 LOCAL_PATH := $(call my-dir)
 wificond_cpp_flags := -Wall -Werror -Wno-unused-parameter
+ifdef WIFI_OFFLOAD_SCANS
+wificond_cpp_flags += -DWIFI_OFFLOAD_SCANS=\"$(WIFI_OFFLOAD_SCANS)\"
+endif
 wificond_parent_dir := $(LOCAL_PATH)/../
 wificond_includes := \
     $(wificond_parent_dir)
index f19419f..b8dfcd8 100644 (file)
@@ -72,6 +72,7 @@ OffloadScanManager::OffloadScanManager(OffloadServiceUtils *utils,
       wifi_offload_callback_(nullptr),
       offload_status_(OffloadScanManager::kError),
       subscription_enabled_(false),
+      service_available_(false),
       offload_callback_handlers_(new OffloadCallbackHandlersImpl(this)),
       scan_result_handler_(handler) {
   if (utils == nullptr) {
@@ -84,28 +85,27 @@ OffloadScanManager::OffloadScanManager(OffloadServiceUtils *utils,
   }
   wifi_offload_hal_ = utils->GetOffloadService();
   if (wifi_offload_hal_ == nullptr) {
-    LOG(WARNING) << "No Offload Service available";
-    offload_status_ = OffloadScanManager::kNoService;
+    LOG(ERROR) << "No Offload Service available";
     return;
   }
   wifi_offload_callback_ = utils->GetOffloadCallback(
       offload_callback_handlers_.get());
   if (wifi_offload_callback_ == nullptr) {
-    offload_status_ = OffloadScanManager::kNoService;
     LOG(ERROR) << "Invalid Offload callback object";
     return;
   }
   wifi_offload_hal_->setEventCallback(wifi_offload_callback_);
+  service_available_ = true;
   offload_status_ = OffloadScanManager::kNoError;
 }
 
 bool OffloadScanManager::stopScan(OffloadScanManager::ReasonCode* reason_code) {
   if (!subscription_enabled_) {
-    LOG(INFO) << "Scans are not subscribed over Offload HAL";
+    LOG(VERBOSE) << "Scans are not subscribed over Offload HAL";
     *reason_code = OffloadScanManager::kNotSubscribed;
     return false;
   }
-  if (offload_status_ != OffloadScanManager::kNoService) {
+  if (service_available_) {
     wifi_offload_hal_->unsubscribeScanResults();
     subscription_enabled_ = false;
   }
@@ -121,7 +121,7 @@ bool OffloadScanManager::startScan(
     const vector<uint8_t>& match_security,
     const vector<uint32_t> &freqs,
     OffloadScanManager::ReasonCode* reason_code) {
-  if (offload_status_ == OffloadScanManager::kNoService) {
+  if (!service_available_) {
     *reason_code = OffloadScanManager::kNotSupported;
     LOG(WARNING) << "Offload HAL scans are not supported";
     return false;
@@ -146,12 +146,24 @@ bool OffloadScanManager::startScan(
 }
 
 OffloadScanManager::StatusCode OffloadScanManager::getOffloadStatus() const {
+  if (!service_available_) {
+    return OffloadScanManager::kNoService;
+  }
   return offload_status_;
 }
 
+bool OffloadScanManager::isOffloadScanSupported() const {
+    bool result = false;
+#ifdef WIFI_OFFLOAD_SCANS
+    LOG(VERBOSE) << "Offload HAL supported";
+    result = true;
+#endif
+    return result;
+}
+
 bool OffloadScanManager::getScanStats(NativeScanStats* native_scan_stats) {
-  if (offload_status_ != OffloadScanManager::kNoError) {
-    LOG(ERROR) << "Unable to get scan stats due to Wifi Offload HAL error";
+  if (getOffloadStatus() != OffloadScanManager::kNoError) {
+    LOG(WARNING) << "Unable to get scan stats due to Wifi Offload HAL error";
     return false;
   }
   wifi_offload_hal_->getScanStats(
index 2a3ec0c..5f589d8 100644 (file)
@@ -118,6 +118,8 @@ class OffloadScanManager {
       ::com::android::server::wifi::wificond::NativeScanStats* /* scanStats */);
   /* Otain status of the Offload HAL service */
   StatusCode getOffloadStatus() const;
+  /* Check if Offload service is supported on this device */
+  bool isOffloadScanSupported() const;
 
  private:
   void ReportScanResults(const std::vector<ScanResult> scanResult);
@@ -127,6 +129,7 @@ class OffloadScanManager {
   android::sp<OffloadCallback> wifi_offload_callback_;
   StatusCode offload_status_;
   bool subscription_enabled_;
+  bool service_available_;
 
   const std::unique_ptr<OffloadCallbackHandlersImpl> offload_callback_handlers_;
   OnNativeScanResultsReadyHandler scan_result_handler_;
index 0a999f6..05ebedf 100644 (file)
@@ -53,6 +53,7 @@ ScannerImpl::ScannerImpl(uint32_t wiphy_index,
     : valid_(true),
       scan_started_(false),
       pno_scan_started_(false),
+      offload_scan_supported_(false),
       wiphy_index_(wiphy_index),
       interface_index_(interface_index),
       scan_capabilities_(scan_capabilities),
@@ -79,6 +80,7 @@ ScannerImpl::ScannerImpl(uint32_t wiphy_index,
       new OffloadScanManager(new OffloadServiceUtils(),
           std::bind(&ScannerImpl::OnOffloadScanResult,
               this, _1)));
+  offload_scan_supported_ = offload_scan_manager_->isOffloadScanSupported();
 }
 
 ScannerImpl::~ScannerImpl() {
@@ -213,41 +215,84 @@ Status ScannerImpl::scan(const SingleScanSettings& scan_settings,
 
 Status ScannerImpl::startPnoScan(const PnoSettings& pno_settings,
                                  bool* out_success) {
-  if (!CheckIsValid()) {
-    *out_success = false;
-    return Status::ok();
-  }
-  if (pno_scan_started_) {
-    LOG(WARNING) << "Pno scan already started";
+  if (!offload_scan_supported_ || !StartPnoScanOffload(pno_settings)) {
+    *out_success = StartPnoScanDefault(pno_settings);
+  } else {
+    // scanning over offload succeeded
+    *out_success = true;
   }
-  // An empty ssid for a wild card scan.
-  vector<vector<uint8_t>> scan_ssids = {{}};
+  return Status::ok();
+}
+
+bool ScannerImpl::StartPnoScanOffload(const PnoSettings& pno_settings) {
+  OffloadScanManager::ReasonCode reason_code;
+  vector<vector<uint8_t>> scan_ssids;
   vector<vector<uint8_t>> match_ssids;
+  vector<uint8_t> match_security;
   // Empty frequency list: scan all frequencies.
   vector<uint32_t> freqs;
 
+  ParsePnoSettings(pno_settings, &scan_ssids, &match_ssids, &freqs, &match_security);
+
+  bool success = offload_scan_manager_->startScan(
+          pno_settings.interval_ms_,
+          // TODO: honor both rssi thresholds.
+          pno_settings.min_5g_rssi_,
+          scan_ssids,
+          match_ssids,
+          match_security,
+          freqs,
+          &reason_code);
+  return success;
+}
+
+void ScannerImpl::ParsePnoSettings(const PnoSettings& pno_settings,
+    vector<vector<uint8_t>>* scan_ssids,
+    vector<vector<uint8_t>>* match_ssids,
+    vector<uint32_t>* freqs,
+    vector<uint8_t>* match_security) {
+  // TODO provide actionable security match parameters
+  const uint8_t kNetworkFlagsDefault = 0;
   vector<vector<uint8_t>> skipped_scan_ssids;
   vector<vector<uint8_t>> skipped_match_ssids;
   for (auto& network : pno_settings.pno_networks_) {
     // Add hidden network ssid.
     if (network.is_hidden_) {
-      if (scan_ssids.size() + 1 > scan_capabilities_.max_num_sched_scan_ssids) {
+      // TODO remove pruning for Offload Scans
+      if (scan_ssids->size() + 1 > scan_capabilities_.max_num_sched_scan_ssids) {
         skipped_scan_ssids.emplace_back(network.ssid_);
         continue;
       }
-      scan_ssids.push_back(network.ssid_);
+      scan_ssids->push_back(network.ssid_);
     }
 
-    if (match_ssids.size() + 1 > scan_capabilities_.max_match_sets) {
+    if (match_ssids->size() + 1 > scan_capabilities_.max_match_sets) {
       skipped_match_ssids.emplace_back(network.ssid_);
       continue;
     }
-    match_ssids.push_back(network.ssid_);
+    match_ssids->push_back(network.ssid_);
+    match_security->push_back(kNetworkFlagsDefault);
   }
 
   LogSsidList(skipped_scan_ssids, "Skip scan ssid for pno scan");
   LogSsidList(skipped_match_ssids, "Skip match ssid for pno scan");
+}
 
+bool ScannerImpl::StartPnoScanDefault(const PnoSettings& pno_settings) {
+  if (!CheckIsValid()) {
+      return false;
+  }
+  if (pno_scan_started_) {
+    LOG(WARNING) << "Pno scan already started";
+  }
+  // An empty ssid for a wild card scan.
+  vector<vector<uint8_t>> scan_ssids = {{}};
+  vector<vector<uint8_t>> match_ssids;
+  vector<uint8_t> unused;
+  // Empty frequency list: scan all frequencies.
+  vector<uint32_t> freqs;
+
+  ParsePnoSettings(pno_settings, &scan_ssids, &match_ssids, &freqs, &unused);
   // Only request MAC address randomization when station is not associated.
   bool request_random_mac = wiphy_features_.supports_random_mac_sched_scan &&
       !client_interface_->IsAssociated();
@@ -260,33 +305,43 @@ Status ScannerImpl::startPnoScan(const PnoSettings& pno_settings,
                                        scan_ssids,
                                        match_ssids,
                                        freqs)) {
-    *out_success = false;
     LOG(ERROR) << "Failed to start pno scan";
-    return Status::ok();
+    return false;
   }
   LOG(INFO) << "Pno scan started";
   pno_scan_started_ = true;
-  *out_success = true;
-  return Status::ok();
+  return true;
 }
 
 Status ScannerImpl::stopPnoScan(bool* out_success) {
+  if (!offload_scan_supported_ || !StopPnoScanOffload()) {
+    *out_success = StopPnoScanDefault();
+  } else {
+    // Pno scans over offload stopped successfully
+    *out_success = true;
+  }
+  return Status::ok();
+}
+
+bool ScannerImpl::StopPnoScanOffload() {
+  OffloadScanManager::ReasonCode reason_code;
+  return(offload_scan_manager_->stopScan(&reason_code));
+}
+
+bool ScannerImpl::StopPnoScanDefault() {
   if (!CheckIsValid()) {
-    *out_success = false;
-    return Status::ok();
+    return false;
   }
 
   if (!pno_scan_started_) {
     LOG(WARNING) << "No pno scan started";
   }
   if (!scan_utils_->StopScheduledScan(interface_index_)) {
-    *out_success = false;
-    return Status::ok();
+    return false;
   }
   LOG(INFO) << "Pno scan stopped";
   pno_scan_started_ = false;
-  *out_success = true;
-  return Status::ok();
+  return true;
 }
 
 Status ScannerImpl::abortScan(bool* out_success) {
@@ -399,9 +454,9 @@ void ScannerImpl::LogSsidList(vector<vector<uint8_t>>& ssid_list,
 
 void ScannerImpl::OnOffloadScanResult(
     std::vector<NativeScanResult> scanResult) {
-  // TODO: Process scan result
-  if (scan_event_handler_ != nullptr) {
-    scan_event_handler_->OnScanResultReady();
+  LOG(INFO) << "Offload Scan results received";
+  if (pno_scan_event_handler_ != nullptr) {
+    pno_scan_event_handler_->OnPnoNetworkFound();
   } else {
     LOG(WARNING) << "No scan event handler Offload Scan result";
   }
index 576f8ec..20bed00 100644 (file)
@@ -85,11 +85,23 @@ class ScannerImpl : public android::net::wifi::BnWifiScannerImpl {
   void OnSchedScanResultsReady(uint32_t interface_index, bool scan_stopped);
   void LogSsidList(std::vector<std::vector<uint8_t>>& ssid_list,
                    std::string prefix);
-
+  bool StartPnoScanDefault(
+      const ::com::android::server::wifi::wificond::PnoSettings& pno_settings);
+  bool StartPnoScanOffload(
+      const ::com::android::server::wifi::wificond::PnoSettings& pno_settings);
+  bool StopPnoScanDefault();
+  bool StopPnoScanOffload();
+  void ParsePnoSettings(
+    const ::com::android::server::wifi::wificond::PnoSettings& pno_settings,
+    std::vector<std::vector<uint8_t>>* scan_ssids,
+    std::vector<std::vector<uint8_t>>* match_ssids,
+    std::vector<uint32_t>* freqs,
+    std::vector<uint8_t>* match_security);
   // Boolean variables describing current scanner status.
   bool valid_;
   bool scan_started_;
   bool pno_scan_started_;
+  bool offload_scan_supported_;
 
   const uint32_t wiphy_index_;
   const uint32_t interface_index_;
index 909bd81..53f423f 100644 (file)
@@ -88,7 +88,7 @@ class OffloadScanManagerTest: public ::testing::Test {
  */
 TEST_F(OffloadScanManagerTest, ServiceUtilsNotAvailableTest) {
   offload_scan_manager_.reset(new OffloadScanManager(nullptr, nullptr));
-  EXPECT_EQ(OffloadScanManager::kError,
+  EXPECT_EQ(OffloadScanManager::kNoService,
       offload_scan_manager_->getOffloadStatus());
 }