OSDN Git Service

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