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