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 31using android::base::WriteStringToFd; 32using android::binder::Status; 33using android::sp; 34using android::IBinder; 35using android::net::wifi::IApInterface; 36using android::net::wifi::IClientInterface; 37using android::net::wifi::IInterfaceEventCallback; 38using android::wifi_system::HostapdManager; 39using android::wifi_system::InterfaceTool; 40using android::wifi_system::SupplicantManager; 41 42using std::endl; 43using std::placeholders::_1; 44using std::string; 45using std::stringstream; 46using std::unique_ptr; 47using std::vector; 48 49namespace android { 50namespace wificond { 51 52namespace { 53 54constexpr const char* kPermissionDump = "android.permission.DUMP"; 55 56} // namespace 57 58Server::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 70Status 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 82Status 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 97Status Server::createApInterface(sp<IApInterface>* created_interface) { 98 InterfaceInfo interface; 99 if (!SetupInterface(&interface)) { 100 return Status::ok(); // Logging was done internally 101 } 102 103 unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl( 104 interface.name, 105 interface.index, 106 netlink_utils_, 107 if_tool_.get(), 108 hostapd_manager_.get())); 109 *created_interface = ap_interface->GetBinder(); 110 ap_interfaces_.push_back(std::move(ap_interface)); 111 BroadcastApInterfaceReady(ap_interfaces_.back()->GetBinder()); 112 113 return Status::ok(); 114} 115 116Status Server::createClientInterface(sp<IClientInterface>* created_interface) { 117 InterfaceInfo interface; 118 if (!SetupInterface(&interface)) { 119 return Status::ok(); // Logging was done internally 120 } 121 122 unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl( 123 wiphy_index_, 124 interface.name, 125 interface.index, 126 interface.mac_address, 127 if_tool_.get(), 128 supplicant_manager_.get(), 129 netlink_utils_, 130 scan_utils_)); 131 *created_interface = client_interface->GetBinder(); 132 client_interfaces_.push_back(std::move(client_interface)); 133 BroadcastClientInterfaceReady(client_interfaces_.back()->GetBinder()); 134 135 return Status::ok(); 136} 137 138Status Server::tearDownInterfaces() { 139 for (auto& it : client_interfaces_) { 140 BroadcastClientInterfaceTornDown(it->GetBinder()); 141 } 142 client_interfaces_.clear(); 143 144 for (auto& it : ap_interfaces_) { 145 BroadcastApInterfaceTornDown(it->GetBinder()); 146 } 147 ap_interfaces_.clear(); 148 149 MarkDownAllInterfaces(); 150 151 netlink_utils_->UnsubscribeRegDomainChange(wiphy_index_); 152 153 return Status::ok(); 154} 155 156Status Server::GetClientInterfaces(vector<sp<IBinder>>* out_client_interfaces) { 157 vector<sp<android::IBinder>> client_interfaces_binder; 158 for (auto& it : client_interfaces_) { 159 out_client_interfaces->push_back(asBinder(it->GetBinder())); 160 } 161 return binder::Status::ok(); 162} 163 164Status Server::GetApInterfaces(vector<sp<IBinder>>* out_ap_interfaces) { 165 vector<sp<IBinder>> ap_interfaces_binder; 166 for (auto& it : ap_interfaces_) { 167 out_ap_interfaces->push_back(asBinder(it->GetBinder())); 168 } 169 return binder::Status::ok(); 170} 171 172status_t Server::dump(int fd, const Vector<String16>& /*args*/) { 173 if (!PermissionCache::checkCallingPermission(String16(kPermissionDump))) { 174 IPCThreadState* ipc = android::IPCThreadState::self(); 175 LOG(ERROR) << "Caller (uid: " << ipc->getCallingUid() 176 << ") is not permitted to dump wificond state"; 177 return PERMISSION_DENIED; 178 } 179 180 stringstream ss; 181 ss << "Current wiphy index: " << wiphy_index_ << endl; 182 ss << "Cached interfaces list from kernel message: " << endl; 183 for (const auto& iface : interfaces_) { 184 ss << "Interface index: " << iface.index 185 << ", name: " << iface.name 186 << ", mac address: " 187 << LoggingUtils::GetMacString(iface.mac_address) << endl; 188 } 189 190 for (const auto& iface : client_interfaces_) { 191 iface->Dump(&ss); 192 } 193 194 for (const auto& iface : ap_interfaces_) { 195 iface->Dump(&ss); 196 } 197 198 if (!WriteStringToFd(ss.str(), fd)) { 199 PLOG(ERROR) << "Failed to dump state to fd " << fd; 200 return FAILED_TRANSACTION; 201 } 202 203 return OK; 204} 205 206void Server::MarkDownAllInterfaces() { 207 uint32_t wiphy_index; 208 vector<InterfaceInfo> interfaces; 209 if (netlink_utils_->GetWiphyIndex(&wiphy_index) && 210 netlink_utils_->GetInterfaces(wiphy_index, &interfaces)) { 211 for (InterfaceInfo& interface : interfaces) { 212 if_tool_->SetUpState(interface.name.c_str(), false); 213 } 214 } 215} 216 217void Server::CleanUpSystemState() { 218 supplicant_manager_->StopSupplicant(); 219 hostapd_manager_->StopHostapd(); 220 MarkDownAllInterfaces(); 221} 222 223bool Server::SetupInterface(InterfaceInfo* interface) { 224 if (!ap_interfaces_.empty() || !client_interfaces_.empty()) { 225 // In the future we may support multiple interfaces at once. However, 226 // today, we support just one. 227 LOG(ERROR) << "Cannot create AP interface when other interfaces exist"; 228 return false; 229 } 230 231 if (!RefreshWiphyIndex()) { 232 return false; 233 } 234 235 netlink_utils_->SubscribeRegDomainChange( 236 wiphy_index_, 237 std::bind(&Server::OnRegDomainChanged, 238 this, 239 _1)); 240 241 interfaces_.clear(); 242 if (!netlink_utils_->GetInterfaces(wiphy_index_, &interfaces_)) { 243 LOG(ERROR) << "Failed to get interfaces info from kernel"; 244 return false; 245 } 246 247 for (const auto& iface : interfaces_) { 248 // Some kernel/driver uses station type for p2p interface. 249 // In that case we can only rely on hard-coded name to exclude 250 // p2p interface from station interfaces. 251 // Currently NAN interfaces also use station type. 252 // We should blacklist NAN interfaces as well. 253 if (iface.name != "p2p0" && 254 !android::base::StartsWith(iface.name, "aware_data")) { 255 *interface = iface; 256 return true; 257 } 258 } 259 260 LOG(ERROR) << "No usable interface found"; 261 return false; 262} 263 264bool Server::RefreshWiphyIndex() { 265 if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) { 266 LOG(ERROR) << "Failed to get wiphy index"; 267 return false; 268 } 269 return true; 270} 271 272void Server::OnRegDomainChanged(std::string& country_code) { 273 if (country_code.empty()) { 274 LOG(INFO) << "Regulatory domain changed"; 275 } else { 276 LOG(INFO) << "Regulatory domain changed to country: " << country_code; 277 } 278 LogSupportedBands(); 279} 280 281void Server::LogSupportedBands() { 282 BandInfo band_info; 283 ScanCapabilities scan_capabilities; 284 WiphyFeatures wiphy_features; 285 netlink_utils_->GetWiphyInfo(wiphy_index_, 286 &band_info, 287 &scan_capabilities, 288 &wiphy_features); 289 290 stringstream ss; 291 for (unsigned int i = 0; i < band_info.band_2g.size(); i++) { 292 ss << " " << band_info.band_2g[i]; 293 } 294 LOG(INFO) << "2.4Ghz frequencies:"<< ss.str(); 295 ss.str(""); 296 297 for (unsigned int i = 0; i < band_info.band_5g.size(); i++) { 298 ss << " " << band_info.band_5g[i]; 299 } 300 LOG(INFO) << "5Ghz non-DFS frequencies:"<< ss.str(); 301 ss.str(""); 302 303 for (unsigned int i = 0; i < band_info.band_dfs.size(); i++) { 304 ss << " " << band_info.band_dfs[i]; 305 } 306 LOG(INFO) << "5Ghz DFS frequencies:"<< ss.str(); 307} 308 309void Server::BroadcastClientInterfaceReady( 310 sp<IClientInterface> network_interface) { 311 for (auto& it : interface_event_callbacks_) { 312 it->OnClientInterfaceReady(network_interface); 313 } 314} 315 316void Server::BroadcastApInterfaceReady( 317 sp<IApInterface> network_interface) { 318 for (auto& it : interface_event_callbacks_) { 319 it->OnApInterfaceReady(network_interface); 320 } 321} 322 323void Server::BroadcastClientInterfaceTornDown( 324 sp<IClientInterface> network_interface) { 325 for (auto& it : interface_event_callbacks_) { 326 it->OnClientTorndownEvent(network_interface); 327 } 328} 329 330void Server::BroadcastApInterfaceTornDown( 331 sp<IApInterface> network_interface) { 332 for (auto& it : interface_event_callbacks_) { 333 it->OnApTorndownEvent(network_interface); 334 } 335} 336 337} // namespace wificond 338} // namespace android 339