• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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