OSDN Git Service

Wificond: Offload HAL APIs return status
[android-x86/system-connectivity-wificond.git] / client_interface_impl.cpp
index 1de2dac..405d1fd 100644 (file)
 
 #include <android-base/logging.h>
 #include <wifi_system/supplicant_manager.h>
-#include <wifi_system/wifi.h>
 
 #include "wificond/client_interface_binder.h"
+#include "wificond/net/mlme_event.h"
 #include "wificond/net/netlink_utils.h"
 #include "wificond/scanning/scan_result.h"
 #include "wificond/scanning/scan_utils.h"
+#include "wificond/scanning/scanner_impl.h"
 
 using android::net::wifi::IClientInterface;
+using com::android::server::wifi::wificond::NativeScanResult;
 using android::sp;
+using android::wifi_system::InterfaceTool;
 using android::wifi_system::SupplicantManager;
 
-using namespace std::placeholders;
+using std::endl;
 using std::string;
 using std::unique_ptr;
 using std::vector;
@@ -39,37 +42,132 @@ using std::vector;
 namespace android {
 namespace wificond {
 
+MlmeEventHandlerImpl::MlmeEventHandlerImpl(ClientInterfaceImpl* client_interface)
+    : client_interface_(client_interface) {
+}
+
+MlmeEventHandlerImpl::~MlmeEventHandlerImpl() {
+}
+
+void MlmeEventHandlerImpl::OnConnect(unique_ptr<MlmeConnectEvent> event) {
+  if (!event->IsTimeout() && event->GetStatusCode() == 0) {
+    client_interface_->is_associated_ = true;
+    client_interface_->RefreshAssociateFreq();
+    client_interface_->bssid_ = event->GetBSSID();
+  } else {
+    if (event->IsTimeout()) {
+      LOG(INFO) << "Connect timeout";
+    }
+    client_interface_->is_associated_ = false;
+    client_interface_->bssid_.clear();
+  }
+}
+
+void MlmeEventHandlerImpl::OnRoam(unique_ptr<MlmeRoamEvent> event) {
+  if (event->GetStatusCode() == 0) {
+    client_interface_->is_associated_ = true;
+    client_interface_->RefreshAssociateFreq();
+    client_interface_->bssid_ = event->GetBSSID();
+  } else {
+    client_interface_->is_associated_ = false;
+    client_interface_->bssid_.clear();
+  }
+}
+
+void MlmeEventHandlerImpl::OnAssociate(unique_ptr<MlmeAssociateEvent> event) {
+  if (!event->IsTimeout() && event->GetStatusCode() == 0) {
+    client_interface_->is_associated_ = true;
+    client_interface_->RefreshAssociateFreq();
+    client_interface_->bssid_ = event->GetBSSID();
+  } else {
+    if (event->IsTimeout()) {
+      LOG(INFO) << "Associate timeout";
+    }
+    client_interface_->is_associated_ = false;
+    client_interface_->bssid_.clear();
+  }
+}
+
+void MlmeEventHandlerImpl::OnDisconnect(unique_ptr<MlmeDisconnectEvent> event) {
+  client_interface_->is_associated_ = false;
+  client_interface_->bssid_.clear();
+}
+
+void MlmeEventHandlerImpl::OnDisassociate(unique_ptr<MlmeDisassociateEvent> event) {
+  client_interface_->is_associated_ = false;
+  client_interface_->bssid_.clear();
+}
+
+
 ClientInterfaceImpl::ClientInterfaceImpl(
+    uint32_t wiphy_index,
     const std::string& interface_name,
     uint32_t interface_index,
     const std::vector<uint8_t>& interface_mac_addr,
+    InterfaceTool* if_tool,
     SupplicantManager* supplicant_manager,
     NetlinkUtils* netlink_utils,
     ScanUtils* scan_utils)
-    : interface_name_(interface_name),
+    : wiphy_index_(wiphy_index),
+      interface_name_(interface_name),
       interface_index_(interface_index),
       interface_mac_addr_(interface_mac_addr),
+      if_tool_(if_tool),
       supplicant_manager_(supplicant_manager),
       netlink_utils_(netlink_utils),
       scan_utils_(scan_utils),
-      binder_(new ClientInterfaceBinder(this)) {
-  scan_utils_->SubscribeScanResultNotification(
+      mlme_event_handler_(new MlmeEventHandlerImpl(this)),
+      binder_(new ClientInterfaceBinder(this)),
+      is_associated_(false) {
+  netlink_utils_->SubscribeMlmeEvent(
       interface_index_,
-      std::bind(&ClientInterfaceImpl::OnScanResultsReady,
-                this,
-                _1, _2, _3, _4));
+      mlme_event_handler_.get());
+  if (!netlink_utils_->GetWiphyInfo(wiphy_index_,
+                               &band_info_,
+                               &scan_capabilities_,
+                               &wiphy_features_)) {
+    LOG(ERROR) << "Failed to get wiphy info from kernel";
+  }
+  LOG(INFO) << "create scanner for interface with index: "
+            << (int)interface_index_;
+  scanner_ = new ScannerImpl(wiphy_index,
+                             interface_index_,
+                             scan_capabilities_,
+                             wiphy_features_,
+                             this,
+                             netlink_utils_,
+                             scan_utils_);
 }
 
 ClientInterfaceImpl::~ClientInterfaceImpl() {
   binder_->NotifyImplDead();
+  scanner_->Invalidate();
   DisableSupplicant();
-  scan_utils_->UnsubscribeScanResultNotification(interface_index_);
+  netlink_utils_->UnsubscribeMlmeEvent(interface_index_);
+  if_tool_->SetUpState(interface_name_.c_str(), false);
 }
 
 sp<android::net::wifi::IClientInterface> ClientInterfaceImpl::GetBinder() const {
   return binder_;
 }
 
+void ClientInterfaceImpl::Dump(std::stringstream* ss) const {
+  *ss << "------- Dump of client interface with index: "
+      << interface_index_ << " and name: " << interface_name_
+      << "-------" << endl;
+  *ss << "Max number of ssids for single shot scan: "
+      << static_cast<int>(scan_capabilities_.max_num_scan_ssids) << endl;
+  *ss << "Max number of ssids for scheduled scan: "
+      << static_cast<int>(scan_capabilities_.max_num_sched_scan_ssids) << endl;
+  *ss << "Max number of match sets for scheduled scan: "
+      << static_cast<int>(scan_capabilities_.max_match_sets) << endl;
+  *ss << "Device supports random MAC for single shot scan: "
+      << wiphy_features_.supports_random_mac_oneshot_scan << endl;
+  *ss << "Device supports random MAC for scheduled scan: "
+      << wiphy_features_.supports_random_mac_sched_scan << endl;
+  *ss << "------- Dump End -------" << endl;
+}
+
 bool ClientInterfaceImpl::EnableSupplicant() {
   return supplicant_manager_->StartSupplicant();
 }
@@ -80,31 +178,64 @@ bool ClientInterfaceImpl::DisableSupplicant() {
 
 bool ClientInterfaceImpl::GetPacketCounters(vector<int32_t>* out_packet_counters) {
   StationInfo station_info;
-  if(!netlink_utils_->GetStationInfo(interface_index_,
-                                     interface_mac_addr_,
-                                     &station_info)) {
+  if (!netlink_utils_->GetStationInfo(interface_index_,
+                                      interface_mac_addr_,
+                                      &station_info)) {
     return false;
   }
   out_packet_counters->push_back(station_info.station_tx_packets);
   out_packet_counters->push_back(station_info.station_tx_failed);
+
   return true;
 }
 
-void ClientInterfaceImpl::OnScanResultsReady(
-                         uint32_t interface_index,
-                         bool aborted,
-                         std::vector<std::vector<uint8_t>>& ssids,
-                         std::vector<uint32_t>& frequencies) {
-  if (aborted) {
-    LOG(ERROR) << "Scan aborted";
-    return;
+bool ClientInterfaceImpl::SignalPoll(vector<int32_t>* out_signal_poll_results) {
+  StationInfo station_info;
+  if (!netlink_utils_->GetStationInfo(interface_index_,
+                                      bssid_,
+                                      &station_info)) {
+    return false;
   }
-  vector<ScanResult> scan_results;
-  // TODO(nywang): Find a way to differentiate scan results for
-  // internel/external scan request. This is useful when location is
-  // scanning using regular NL80211 commands.
-  scan_utils_->GetScanResult(interface_index, &scan_results);
-  // TODO(nywang): Send these scan results back to java framework.
+  out_signal_poll_results->push_back(
+      static_cast<int32_t>(station_info.current_rssi));
+  // Convert from 100kbit/s to Mbps.
+  out_signal_poll_results->push_back(
+      static_cast<int32_t>(station_info.station_tx_bitrate/10));
+  // Association frequency.
+  out_signal_poll_results->push_back(
+      static_cast<int32_t>(associate_freq_));
+
+  return true;
+}
+
+const vector<uint8_t>& ClientInterfaceImpl::GetMacAddress() {
+  return interface_mac_addr_;
+}
+
+bool ClientInterfaceImpl::requestANQP(
+      const ::std::vector<uint8_t>& bssid,
+      const ::android::sp<::android::net::wifi::IANQPDoneCallback>& callback) {
+  // TODO(nywang): query ANQP information from wpa_supplicant.
+  return true;
+}
+
+bool ClientInterfaceImpl::RefreshAssociateFreq() {
+  // wpa_supplicant fetches associate frequency using the latest scan result.
+  // We should follow the same method here before we find a better solution.
+  std::vector<NativeScanResult> scan_results;
+  if (!scan_utils_->GetScanResult(interface_index_, &scan_results)) {
+    return false;
+  }
+  for (auto& scan_result : scan_results) {
+    if (scan_result.associated) {
+      associate_freq_ = scan_result.frequency;
+    }
+  }
+  return false;
+}
+
+bool ClientInterfaceImpl::IsAssociated() const {
+  return is_associated_;
 }
 
 }  // namespace wificond