OSDN Git Service

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