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