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/server.h"
     18 
     19 #include <sstream>
     20 
     21 #include <android-base/file.h>
     22 #include <android-base/logging.h>
     23 #include <android-base/strings.h>
     24 #include <binder/IPCThreadState.h>
     25 #include <binder/PermissionCache.h>
     26 
     27 #include "wificond/logging_utils.h"
     28 #include "wificond/net/netlink_utils.h"
     29 #include "wificond/scanning/scan_utils.h"
     30 
     31 using android::base::WriteStringToFd;
     32 using android::binder::Status;
     33 using android::sp;
     34 using android::IBinder;
     35 using android::net::wifi::IApInterface;
     36 using android::net::wifi::IClientInterface;
     37 using android::net::wifi::IInterfaceEventCallback;
     38 using android::wifi_system::HostapdManager;
     39 using android::wifi_system::InterfaceTool;
     40 using android::wifi_system::SupplicantManager;
     41 
     42 using std::endl;
     43 using std::placeholders::_1;
     44 using std::string;
     45 using std::stringstream;
     46 using std::unique_ptr;
     47 using std::vector;
     48 
     49 namespace android {
     50 namespace wificond {
     51 
     52 namespace {
     53 
     54 constexpr const char* kPermissionDump = "android.permission.DUMP";
     55 
     56 }  // namespace
     57 
     58 Server::Server(unique_ptr<InterfaceTool> if_tool,
     59                unique_ptr<SupplicantManager> supplicant_manager,
     60                unique_ptr<HostapdManager> hostapd_manager,
     61                NetlinkUtils* netlink_utils,
     62                ScanUtils* scan_utils)
     63     : if_tool_(std::move(if_tool)),
     64       supplicant_manager_(std::move(supplicant_manager)),
     65       hostapd_manager_(std::move(hostapd_manager)),
     66       netlink_utils_(netlink_utils),
     67       scan_utils_(scan_utils) {
     68 }
     69 
     70 Status Server::RegisterCallback(const sp<IInterfaceEventCallback>& callback) {
     71   for (auto& it : interface_event_callbacks_) {
     72     if (IInterface::asBinder(callback) == IInterface::asBinder(it)) {
     73       LOG(WARNING) << "Ignore duplicate interface event callback registration";
     74       return Status::ok();
     75     }
     76   }
     77   LOG(INFO) << "New interface event callback registered";
     78   interface_event_callbacks_.push_back(callback);
     79   return Status::ok();
     80 }
     81 
     82 Status Server::UnregisterCallback(const sp<IInterfaceEventCallback>& callback) {
     83   for (auto it = interface_event_callbacks_.begin();
     84        it != interface_event_callbacks_.end();
     85        it++) {
     86     if (IInterface::asBinder(callback) == IInterface::asBinder(*it)) {
     87       interface_event_callbacks_.erase(it);
     88       LOG(INFO) << "Unregister interface event callback";
     89       return Status::ok();
     90     }
     91   }
     92   LOG(WARNING) << "Failed to find registered interface event callback"
     93                << " to unregister";
     94   return Status::ok();
     95 }
     96 
     97 Status Server::createApInterface(const std::string& iface_name,
     98                                  sp<IApInterface>* created_interface) {
     99   InterfaceInfo interface;
    100   if (!SetupInterface(iface_name, &interface)) {
    101     return Status::ok();  // Logging was done internally
    102   }
    103 
    104   unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
    105       interface.name,
    106       interface.index,
    107       netlink_utils_,
    108       if_tool_.get(),
    109       hostapd_manager_.get()));
    110   *created_interface = ap_interface->GetBinder();
    111   BroadcastApInterfaceReady(ap_interface->GetBinder());
    112   ap_interfaces_[iface_name] = std::move(ap_interface);
    113 
    114   return Status::ok();
    115 }
    116 
    117 Status Server::tearDownApInterface(const std::string& iface_name,
    118                                    bool* out_success) {
    119   *out_success = false;
    120   const auto iter = ap_interfaces_.find(iface_name);
    121   if (iter != ap_interfaces_.end()) {
    122     BroadcastApInterfaceTornDown(iter->second->GetBinder());
    123     ap_interfaces_.erase(iter);
    124     *out_success = true;
    125   }
    126   return Status::ok();
    127 }
    128 
    129 Status Server::createClientInterface(const std::string& iface_name,
    130                                      sp<IClientInterface>* created_interface) {
    131   InterfaceInfo interface;
    132   if (!SetupInterface(iface_name, &interface)) {
    133     return Status::ok();  // Logging was done internally
    134   }
    135 
    136   unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
    137       wiphy_index_,
    138       interface.name,
    139       interface.index,
    140       interface.mac_address,
    141       if_tool_.get(),
    142       netlink_utils_,
    143       scan_utils_));
    144   *created_interface = client_interface->GetBinder();
    145   BroadcastClientInterfaceReady(client_interface->GetBinder());
    146   client_interfaces_[iface_name] = std::move(client_interface);
    147 
    148   return Status::ok();
    149 }
    150 
    151 Status Server::tearDownClientInterface(const std::string& iface_name,
    152                                        bool* out_success) {
    153   *out_success = false;
    154   const auto iter = client_interfaces_.find(iface_name);
    155   if (iter != client_interfaces_.end()) {
    156     BroadcastClientInterfaceTornDown(iter->second->GetBinder());
    157     client_interfaces_.erase(iter);
    158     *out_success = true;
    159   }
    160   return Status::ok();
    161 }
    162 
    163 Status Server::tearDownInterfaces() {
    164   for (auto& it : client_interfaces_) {
    165     BroadcastClientInterfaceTornDown(it.second->GetBinder());
    166   }
    167   client_interfaces_.clear();
    168 
    169   for (auto& it : ap_interfaces_) {
    170     BroadcastApInterfaceTornDown(it.second->GetBinder());
    171   }
    172   ap_interfaces_.clear();
    173 
    174   MarkDownAllInterfaces();
    175 
    176   netlink_utils_->UnsubscribeRegDomainChange(wiphy_index_);
    177 
    178   return Status::ok();
    179 }
    180 
    181 Status Server::enableSupplicant(bool* success) {
    182   *success = supplicant_manager_->StartSupplicant();
    183   return Status::ok();
    184 }
    185 
    186 Status Server::disableSupplicant(bool* success) {
    187   *success = supplicant_manager_->StopSupplicant();
    188   return Status::ok();
    189 }
    190 
    191 Status Server::GetClientInterfaces(vector<sp<IBinder>>* out_client_interfaces) {
    192   vector<sp<android::IBinder>> client_interfaces_binder;
    193   for (auto& it : client_interfaces_) {
    194     out_client_interfaces->push_back(asBinder(it.second->GetBinder()));
    195   }
    196   return binder::Status::ok();
    197 }
    198 
    199 Status Server::GetApInterfaces(vector<sp<IBinder>>* out_ap_interfaces) {
    200   vector<sp<IBinder>> ap_interfaces_binder;
    201   for (auto& it : ap_interfaces_) {
    202     out_ap_interfaces->push_back(asBinder(it.second->GetBinder()));
    203   }
    204   return binder::Status::ok();
    205 }
    206 
    207 status_t Server::dump(int fd, const Vector<String16>& /*args*/) {
    208   if (!PermissionCache::checkCallingPermission(String16(kPermissionDump))) {
    209     IPCThreadState* ipc = android::IPCThreadState::self();
    210     LOG(ERROR) << "Caller (uid: " << ipc->getCallingUid()
    211                << ") is not permitted to dump wificond state";
    212     return PERMISSION_DENIED;
    213   }
    214 
    215   stringstream ss;
    216   ss << "Current wiphy index: " << wiphy_index_ << endl;
    217   ss << "Cached interfaces list from kernel message: " << endl;
    218   for (const auto& iface : interfaces_) {
    219     ss << "Interface index: " << iface.index
    220        << ", name: " << iface.name
    221        << ", mac address: "
    222        << LoggingUtils::GetMacString(iface.mac_address) << endl;
    223   }
    224 
    225   string country_code;
    226   if (netlink_utils_->GetCountryCode(&country_code)) {
    227     ss << "Current country code from kernel: " << country_code << endl;
    228   } else {
    229     ss << "Failed to get country code from kernel." << endl;
    230   }
    231 
    232   for (const auto& iface : client_interfaces_) {
    233     iface.second->Dump(&ss);
    234   }
    235 
    236   for (const auto& iface : ap_interfaces_) {
    237     iface.second->Dump(&ss);
    238   }
    239 
    240   if (!WriteStringToFd(ss.str(), fd)) {
    241     PLOG(ERROR) << "Failed to dump state to fd " << fd;
    242     return FAILED_TRANSACTION;
    243   }
    244 
    245   return OK;
    246 }
    247 
    248 void Server::MarkDownAllInterfaces() {
    249   uint32_t wiphy_index;
    250   vector<InterfaceInfo> interfaces;
    251   if (netlink_utils_->GetWiphyIndex(&wiphy_index) &&
    252       netlink_utils_->GetInterfaces(wiphy_index, &interfaces)) {
    253     for (InterfaceInfo& interface : interfaces) {
    254       if_tool_->SetUpState(interface.name.c_str(), false);
    255     }
    256   }
    257 }
    258 
    259 Status Server::getAvailable2gChannels(
    260     std::unique_ptr<vector<int32_t>>* out_frequencies) {
    261   BandInfo band_info;
    262   ScanCapabilities scan_capabilities_ignored;
    263   WiphyFeatures wiphy_features_ignored;
    264 
    265   if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
    266                                     &scan_capabilities_ignored,
    267                                     &wiphy_features_ignored)) {
    268     LOG(ERROR) << "Failed to get wiphy info from kernel";
    269     out_frequencies->reset(nullptr);
    270     return Status::ok();
    271   }
    272 
    273   out_frequencies->reset(
    274       new vector<int32_t>(band_info.band_2g.begin(), band_info.band_2g.end()));
    275   return Status::ok();
    276 }
    277 
    278 Status Server::getAvailable5gNonDFSChannels(
    279     std::unique_ptr<vector<int32_t>>* out_frequencies) {
    280   BandInfo band_info;
    281   ScanCapabilities scan_capabilities_ignored;
    282   WiphyFeatures wiphy_features_ignored;
    283 
    284   if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
    285                                     &scan_capabilities_ignored,
    286                                     &wiphy_features_ignored)) {
    287     LOG(ERROR) << "Failed to get wiphy info from kernel";
    288     out_frequencies->reset(nullptr);
    289     return Status::ok();
    290   }
    291 
    292   out_frequencies->reset(
    293       new vector<int32_t>(band_info.band_5g.begin(), band_info.band_5g.end()));
    294   return Status::ok();
    295 }
    296 
    297 Status Server::getAvailableDFSChannels(
    298     std::unique_ptr<vector<int32_t>>* out_frequencies) {
    299   BandInfo band_info;
    300   ScanCapabilities scan_capabilities_ignored;
    301   WiphyFeatures wiphy_features_ignored;
    302 
    303   if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
    304                                     &scan_capabilities_ignored,
    305                                     &wiphy_features_ignored)) {
    306     LOG(ERROR) << "Failed to get wiphy info from kernel";
    307     out_frequencies->reset(nullptr);
    308     return Status::ok();
    309   }
    310 
    311   out_frequencies->reset(new vector<int32_t>(band_info.band_dfs.begin(),
    312                                              band_info.band_dfs.end()));
    313   return Status::ok();
    314 }
    315 
    316 bool Server::SetupInterface(const std::string& iface_name,
    317                             InterfaceInfo* interface) {
    318   if (!RefreshWiphyIndex()) {
    319     return false;
    320   }
    321 
    322   netlink_utils_->SubscribeRegDomainChange(
    323           wiphy_index_,
    324           std::bind(&Server::OnRegDomainChanged,
    325           this,
    326           _1));
    327 
    328   interfaces_.clear();
    329   if (!netlink_utils_->GetInterfaces(wiphy_index_, &interfaces_)) {
    330     LOG(ERROR) << "Failed to get interfaces info from kernel";
    331     return false;
    332   }
    333 
    334   for (const auto& iface : interfaces_) {
    335     if (iface.name == iface_name) {
    336       *interface = iface;
    337       return true;
    338     }
    339   }
    340 
    341   LOG(ERROR) << "No usable interface found";
    342   return false;
    343 }
    344 
    345 bool Server::RefreshWiphyIndex() {
    346   if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) {
    347     LOG(ERROR) << "Failed to get wiphy index";
    348     return false;
    349   }
    350   return true;
    351 }
    352 
    353 void Server::OnRegDomainChanged(std::string& country_code) {
    354   if (country_code.empty()) {
    355     LOG(INFO) << "Regulatory domain changed";
    356   } else {
    357     LOG(INFO) << "Regulatory domain changed to country: " << country_code;
    358   }
    359   LogSupportedBands();
    360 }
    361 
    362 void Server::LogSupportedBands() {
    363   BandInfo band_info;
    364   ScanCapabilities scan_capabilities;
    365   WiphyFeatures wiphy_features;
    366   netlink_utils_->GetWiphyInfo(wiphy_index_,
    367                                &band_info,
    368                                &scan_capabilities,
    369                                &wiphy_features);
    370 
    371   stringstream ss;
    372   for (unsigned int i = 0; i < band_info.band_2g.size(); i++) {
    373     ss << " " << band_info.band_2g[i];
    374   }
    375   LOG(INFO) << "2.4Ghz frequencies:"<< ss.str();
    376   ss.str("");
    377 
    378   for (unsigned int i = 0; i < band_info.band_5g.size(); i++) {
    379     ss << " " << band_info.band_5g[i];
    380   }
    381   LOG(INFO) << "5Ghz non-DFS frequencies:"<< ss.str();
    382   ss.str("");
    383 
    384   for (unsigned int i = 0; i < band_info.band_dfs.size(); i++) {
    385     ss << " " << band_info.band_dfs[i];
    386   }
    387   LOG(INFO) << "5Ghz DFS frequencies:"<< ss.str();
    388 }
    389 
    390 void Server::BroadcastClientInterfaceReady(
    391     sp<IClientInterface> network_interface) {
    392   for (auto& it : interface_event_callbacks_) {
    393     it->OnClientInterfaceReady(network_interface);
    394   }
    395 }
    396 
    397 void Server::BroadcastApInterfaceReady(
    398     sp<IApInterface> network_interface) {
    399   for (auto& it : interface_event_callbacks_) {
    400     it->OnApInterfaceReady(network_interface);
    401   }
    402 }
    403 
    404 void Server::BroadcastClientInterfaceTornDown(
    405     sp<IClientInterface> network_interface) {
    406   for (auto& it : interface_event_callbacks_) {
    407     it->OnClientTorndownEvent(network_interface);
    408   }
    409 }
    410 
    411 void Server::BroadcastApInterfaceTornDown(
    412     sp<IApInterface> network_interface) {
    413   for (auto& it : interface_event_callbacks_) {
    414     it->OnApTorndownEvent(network_interface);
    415   }
    416 }
    417 
    418 }  // namespace wificond
    419 }  // namespace android
    420