Home | History | Annotate | Download | only in wificond
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "wificond/client_interface_impl.h"
     18 
     19 #include <vector>
     20 
     21 #include <android-base/logging.h>
     22 #include <wifi_system/supplicant_manager.h>
     23 
     24 #include "wificond/client_interface_binder.h"
     25 #include "wificond/net/mlme_event.h"
     26 #include "wificond/net/netlink_utils.h"
     27 #include "wificond/scanning/scan_result.h"
     28 #include "wificond/scanning/scan_utils.h"
     29 #include "wificond/scanning/scanner_impl.h"
     30 
     31 using android::net::wifi::IClientInterface;
     32 using com::android::server::wifi::wificond::NativeScanResult;
     33 using android::sp;
     34 using android::wifi_system::InterfaceTool;
     35 using android::wifi_system::SupplicantManager;
     36 
     37 using std::endl;
     38 using std::string;
     39 using std::unique_ptr;
     40 using std::vector;
     41 
     42 namespace android {
     43 namespace wificond {
     44 
     45 MlmeEventHandlerImpl::MlmeEventHandlerImpl(ClientInterfaceImpl* client_interface)
     46     : client_interface_(client_interface) {
     47 }
     48 
     49 MlmeEventHandlerImpl::~MlmeEventHandlerImpl() {
     50 }
     51 
     52 void MlmeEventHandlerImpl::OnConnect(unique_ptr<MlmeConnectEvent> event) {
     53   if (!event->IsTimeout() && event->GetStatusCode() == 0) {
     54     client_interface_->is_associated_ = true;
     55     client_interface_->RefreshAssociateFreq();
     56     client_interface_->bssid_ = event->GetBSSID();
     57   } else {
     58     if (event->IsTimeout()) {
     59       LOG(INFO) << "Connect timeout";
     60     }
     61     client_interface_->is_associated_ = false;
     62     client_interface_->bssid_.clear();
     63   }
     64 }
     65 
     66 void MlmeEventHandlerImpl::OnRoam(unique_ptr<MlmeRoamEvent> event) {
     67   if (event->GetStatusCode() == 0) {
     68     client_interface_->is_associated_ = true;
     69     client_interface_->RefreshAssociateFreq();
     70     client_interface_->bssid_ = event->GetBSSID();
     71   } else {
     72     client_interface_->is_associated_ = false;
     73     client_interface_->bssid_.clear();
     74   }
     75 }
     76 
     77 void MlmeEventHandlerImpl::OnAssociate(unique_ptr<MlmeAssociateEvent> event) {
     78   if (!event->IsTimeout() && event->GetStatusCode() == 0) {
     79     client_interface_->is_associated_ = true;
     80     client_interface_->RefreshAssociateFreq();
     81     client_interface_->bssid_ = event->GetBSSID();
     82   } else {
     83     if (event->IsTimeout()) {
     84       LOG(INFO) << "Associate timeout";
     85     }
     86     client_interface_->is_associated_ = false;
     87     client_interface_->bssid_.clear();
     88   }
     89 }
     90 
     91 void MlmeEventHandlerImpl::OnDisconnect(unique_ptr<MlmeDisconnectEvent> event) {
     92   client_interface_->is_associated_ = false;
     93   client_interface_->bssid_.clear();
     94 }
     95 
     96 void MlmeEventHandlerImpl::OnDisassociate(unique_ptr<MlmeDisassociateEvent> event) {
     97   client_interface_->is_associated_ = false;
     98   client_interface_->bssid_.clear();
     99 }
    100 
    101 
    102 ClientInterfaceImpl::ClientInterfaceImpl(
    103     uint32_t wiphy_index,
    104     const std::string& interface_name,
    105     uint32_t interface_index,
    106     const std::vector<uint8_t>& interface_mac_addr,
    107     InterfaceTool* if_tool,
    108     SupplicantManager* supplicant_manager,
    109     NetlinkUtils* netlink_utils,
    110     ScanUtils* scan_utils)
    111     : wiphy_index_(wiphy_index),
    112       interface_name_(interface_name),
    113       interface_index_(interface_index),
    114       interface_mac_addr_(interface_mac_addr),
    115       if_tool_(if_tool),
    116       supplicant_manager_(supplicant_manager),
    117       netlink_utils_(netlink_utils),
    118       scan_utils_(scan_utils),
    119       mlme_event_handler_(new MlmeEventHandlerImpl(this)),
    120       binder_(new ClientInterfaceBinder(this)),
    121       is_associated_(false) {
    122   netlink_utils_->SubscribeMlmeEvent(
    123       interface_index_,
    124       mlme_event_handler_.get());
    125   if (!netlink_utils_->GetWiphyInfo(wiphy_index_,
    126                                &band_info_,
    127                                &scan_capabilities_,
    128                                &wiphy_features_)) {
    129     LOG(ERROR) << "Failed to get wiphy info from kernel";
    130   }
    131   LOG(INFO) << "create scanner for interface with index: "
    132             << (int)interface_index_;
    133   scanner_ = new ScannerImpl(wiphy_index,
    134                              interface_index_,
    135                              scan_capabilities_,
    136                              wiphy_features_,
    137                              this,
    138                              netlink_utils_,
    139                              scan_utils_);
    140 }
    141 
    142 ClientInterfaceImpl::~ClientInterfaceImpl() {
    143   binder_->NotifyImplDead();
    144   scanner_->Invalidate();
    145   DisableSupplicant();
    146   netlink_utils_->UnsubscribeMlmeEvent(interface_index_);
    147   if_tool_->SetUpState(interface_name_.c_str(), false);
    148 }
    149 
    150 sp<android::net::wifi::IClientInterface> ClientInterfaceImpl::GetBinder() const {
    151   return binder_;
    152 }
    153 
    154 void ClientInterfaceImpl::Dump(std::stringstream* ss) const {
    155   *ss << "------- Dump of client interface with index: "
    156       << interface_index_ << " and name: " << interface_name_
    157       << "-------" << endl;
    158   *ss << "Max number of ssids for single shot scan: "
    159       << static_cast<int>(scan_capabilities_.max_num_scan_ssids) << endl;
    160   *ss << "Max number of ssids for scheduled scan: "
    161       << static_cast<int>(scan_capabilities_.max_num_sched_scan_ssids) << endl;
    162   *ss << "Max number of match sets for scheduled scan: "
    163       << static_cast<int>(scan_capabilities_.max_match_sets) << endl;
    164   *ss << "Device supports random MAC for single shot scan: "
    165       << wiphy_features_.supports_random_mac_oneshot_scan << endl;
    166   *ss << "Device supports random MAC for scheduled scan: "
    167       << wiphy_features_.supports_random_mac_sched_scan << endl;
    168   *ss << "------- Dump End -------" << endl;
    169 }
    170 
    171 bool ClientInterfaceImpl::EnableSupplicant() {
    172   return supplicant_manager_->StartSupplicant();
    173 }
    174 
    175 bool ClientInterfaceImpl::DisableSupplicant() {
    176   return supplicant_manager_->StopSupplicant();
    177 }
    178 
    179 bool ClientInterfaceImpl::GetPacketCounters(vector<int32_t>* out_packet_counters) {
    180   StationInfo station_info;
    181   if (!netlink_utils_->GetStationInfo(interface_index_,
    182                                       interface_mac_addr_,
    183                                       &station_info)) {
    184     return false;
    185   }
    186   out_packet_counters->push_back(station_info.station_tx_packets);
    187   out_packet_counters->push_back(station_info.station_tx_failed);
    188 
    189   return true;
    190 }
    191 
    192 bool ClientInterfaceImpl::SignalPoll(vector<int32_t>* out_signal_poll_results) {
    193   StationInfo station_info;
    194   if (!netlink_utils_->GetStationInfo(interface_index_,
    195                                       bssid_,
    196                                       &station_info)) {
    197     return false;
    198   }
    199   out_signal_poll_results->push_back(
    200       static_cast<int32_t>(station_info.current_rssi));
    201   // Convert from 100kbit/s to Mbps.
    202   out_signal_poll_results->push_back(
    203       static_cast<int32_t>(station_info.station_tx_bitrate/10));
    204   // Association frequency.
    205   out_signal_poll_results->push_back(
    206       static_cast<int32_t>(associate_freq_));
    207 
    208   return true;
    209 }
    210 
    211 const vector<uint8_t>& ClientInterfaceImpl::GetMacAddress() {
    212   return interface_mac_addr_;
    213 }
    214 
    215 bool ClientInterfaceImpl::requestANQP(
    216       const ::std::vector<uint8_t>& bssid,
    217       const ::android::sp<::android::net::wifi::IANQPDoneCallback>& callback) {
    218   // TODO(nywang): query ANQP information from wpa_supplicant.
    219   return true;
    220 }
    221 
    222 bool ClientInterfaceImpl::RefreshAssociateFreq() {
    223   // wpa_supplicant fetches associate frequency using the latest scan result.
    224   // We should follow the same method here before we find a better solution.
    225   std::vector<NativeScanResult> scan_results;
    226   if (!scan_utils_->GetScanResult(interface_index_, &scan_results)) {
    227     return false;
    228   }
    229   for (auto& scan_result : scan_results) {
    230     if (scan_result.associated) {
    231       associate_freq_ = scan_result.frequency;
    232     }
    233   }
    234   return false;
    235 }
    236 
    237 bool ClientInterfaceImpl::IsAssociated() const {
    238   return is_associated_;
    239 }
    240 
    241 }  // namespace wificond
    242 }  // namespace android
    243