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/ap_interface_impl.h"
     18 
     19 #include <android-base/logging.h>
     20 
     21 #include "wificond/net/netlink_utils.h"
     22 
     23 #include "wificond/ap_interface_binder.h"
     24 #include "wificond/logging_utils.h"
     25 
     26 using android::net::wifi::IApInterface;
     27 using android::wifi_system::HostapdManager;
     28 using android::wifi_system::InterfaceTool;
     29 using std::endl;
     30 using std::string;
     31 using std::unique_ptr;
     32 using std::vector;
     33 
     34 using EncryptionType = android::wifi_system::HostapdManager::EncryptionType;
     35 
     36 using namespace std::placeholders;
     37 
     38 namespace android {
     39 namespace wificond {
     40 
     41 ApInterfaceImpl::ApInterfaceImpl(const string& interface_name,
     42                                  uint32_t interface_index,
     43                                  NetlinkUtils* netlink_utils,
     44                                  InterfaceTool* if_tool,
     45                                  HostapdManager* hostapd_manager)
     46     : interface_name_(interface_name),
     47       interface_index_(interface_index),
     48       netlink_utils_(netlink_utils),
     49       if_tool_(if_tool),
     50       hostapd_manager_(hostapd_manager),
     51       binder_(new ApInterfaceBinder(this)),
     52       number_of_associated_stations_(0) {
     53   // This log keeps compiler happy.
     54   LOG(DEBUG) << "Created ap interface " << interface_name_
     55              << " with index " << interface_index_;
     56 
     57   netlink_utils_->SubscribeStationEvent(
     58       interface_index_,
     59       std::bind(&ApInterfaceImpl::OnStationEvent,
     60                 this,
     61                 _1, _2));
     62 }
     63 
     64 ApInterfaceImpl::~ApInterfaceImpl() {
     65   binder_->NotifyImplDead();
     66   if_tool_->SetUpState(interface_name_.c_str(), false);
     67   netlink_utils_->UnsubscribeStationEvent(interface_index_);
     68 }
     69 
     70 sp<IApInterface> ApInterfaceImpl::GetBinder() const {
     71   return binder_;
     72 }
     73 
     74 void ApInterfaceImpl::Dump(std::stringstream* ss) const {
     75   *ss << "------- Dump of AP interface with index: "
     76       << interface_index_ << " and name: " << interface_name_
     77       << "-------" << endl;
     78   *ss << "Number of associated stations: "
     79       <<  number_of_associated_stations_ << endl;
     80   *ss << "------- Dump End -------" << endl;
     81 }
     82 
     83 bool ApInterfaceImpl::StartHostapd() {
     84   return hostapd_manager_->StartHostapd();
     85 }
     86 
     87 bool ApInterfaceImpl::StopHostapd() {
     88   // Drop SIGKILL on hostapd.
     89   if (!hostapd_manager_->StopHostapd()) {
     90     // Logging was done internally.
     91     return false;
     92   }
     93 
     94   // Take down the interface.
     95   if (!if_tool_->SetUpState(interface_name_.c_str(), false)) {
     96     // Logging was done internally.
     97     return false;
     98   }
     99 
    100   // Since wificond SIGKILLs hostapd, hostapd has no chance to handle
    101   // the cleanup.
    102   // Besides taking down the interface, we also need to set the interface mode
    103   // back to station mode for the cleanup.
    104   if (!netlink_utils_->SetInterfaceMode(interface_index_,
    105                                         NetlinkUtils::STATION_MODE)) {
    106     LOG(ERROR) << "Failed to set interface back to station mode";
    107     return false;
    108   }
    109 
    110   return true;
    111 }
    112 
    113 bool ApInterfaceImpl::WriteHostapdConfig(const vector<uint8_t>& ssid,
    114                                          bool is_hidden,
    115                                          int32_t channel,
    116                                          EncryptionType encryption_type,
    117                                          const vector<uint8_t>& passphrase) {
    118   string config = hostapd_manager_->CreateHostapdConfig(
    119       interface_name_, ssid, is_hidden, channel, encryption_type, passphrase);
    120 
    121   if (config.empty()) {
    122     return false;
    123   }
    124 
    125   return hostapd_manager_->WriteHostapdConfig(config);
    126 }
    127 
    128 void ApInterfaceImpl::OnStationEvent(StationEvent event,
    129                                      const vector<uint8_t>& mac_address) {
    130   if (event == NEW_STATION) {
    131     LOG(INFO) << "New station "
    132               << LoggingUtils::GetMacString(mac_address)
    133               << " associated with hotspot";
    134     number_of_associated_stations_++;
    135   } else if (event == DEL_STATION) {
    136     LOG(INFO) << "Station "
    137               << LoggingUtils::GetMacString(mac_address)
    138               << " disassociated from hotspot";
    139     if (number_of_associated_stations_ <= 0) {
    140       LOG(ERROR) << "Received DEL_STATION event when station counter is: "
    141                  << number_of_associated_stations_;
    142     } else {
    143       number_of_associated_stations_--;
    144     }
    145   }
    146 }
    147 
    148 int ApInterfaceImpl::GetNumberOfAssociatedStations() const {
    149   return number_of_associated_stations_;
    150 }
    151 
    152 }  // namespace wificond
    153 }  // namespace android
    154