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 <algorithm> // for std::find_if
20 #include <sstream>
21 #include <set>
22
23 #include <android-base/file.h>
24 #include <android-base/logging.h>
25 #include <android-base/strings.h>
26 #include <binder/IPCThreadState.h>
27 #include <binder/PermissionCache.h>
28
29 #include "wificond/logging_utils.h"
30 #include "wificond/net/netlink_utils.h"
31 #include "wificond/scanning/scan_utils.h"
32
33 using android::base::WriteStringToFd;
34 using android::binder::Status;
35 using android::sp;
36 using android::IBinder;
37 using android::net::wifi::nl80211::IApInterface;
38 using android::net::wifi::nl80211::IClientInterface;
39 using android::net::wifi::nl80211::IInterfaceEventCallback;
40 using android::net::wifi::nl80211::DeviceWiphyCapabilities;
41 using android::net::wifi::nl80211::IWificondEventCallback;
42 using android::wifi_system::InterfaceTool;
43
44 using std::endl;
45 using std::optional;
46 using std::placeholders::_1;
47 using std::placeholders::_2;
48 using std::set;
49 using std::string;
50 using std::stringstream;
51 using std::unique_ptr;
52 using std::vector;
53
54 namespace android {
55 namespace wificond {
56
57 namespace {
58
59 constexpr const char* kPermissionDump = "android.permission.DUMP";
60
61 } // namespace
62
Server(unique_ptr<InterfaceTool> if_tool,NetlinkUtils * netlink_utils,ScanUtils * scan_utils)63 Server::Server(unique_ptr<InterfaceTool> if_tool,
64 NetlinkUtils* netlink_utils,
65 ScanUtils* scan_utils)
66 : if_tool_(std::move(if_tool)),
67 netlink_utils_(netlink_utils),
68 scan_utils_(scan_utils) {
69 }
70
registerWificondEventCallback(const sp<IWificondEventCallback> & callback)71 Status Server::registerWificondEventCallback(const sp<IWificondEventCallback>& callback) {
72 for (const auto& it : wificond_event_callbacks_) {
73 if (IInterface::asBinder(callback) == IInterface::asBinder(it)) {
74 LOG(WARNING) << "Ignore duplicate wificond event callback registration";
75 return Status::ok();
76 }
77 }
78 LOG(INFO) << "New wificond event callback registered";
79 wificond_event_callbacks_.push_back(callback);
80 return Status::ok();
81 }
82
unregisterWificondEventCallback(const sp<IWificondEventCallback> & callback)83 Status Server::unregisterWificondEventCallback(const sp<IWificondEventCallback>& callback) {
84 for (auto it = wificond_event_callbacks_.begin();
85 it != wificond_event_callbacks_.end();
86 it++) {
87 if (IInterface::asBinder(callback) == IInterface::asBinder(*it)) {
88 wificond_event_callbacks_.erase(it);
89 LOG(INFO) << "Unregister interface event callback";
90 return Status::ok();
91 }
92 }
93 LOG(WARNING) << "Failed to find registered wificond event callback"
94 << " to unregister";
95 return Status::ok();
96 }
97
RegisterCallback(const sp<IInterfaceEventCallback> & callback)98 Status Server::RegisterCallback(const sp<IInterfaceEventCallback>& callback) {
99 for (auto& it : interface_event_callbacks_) {
100 if (IInterface::asBinder(callback) == IInterface::asBinder(it)) {
101 LOG(WARNING) << "Ignore duplicate interface event callback registration";
102 return Status::ok();
103 }
104 }
105 LOG(INFO) << "New interface event callback registered";
106 interface_event_callbacks_.push_back(callback);
107 return Status::ok();
108 }
109
UnregisterCallback(const sp<IInterfaceEventCallback> & callback)110 Status Server::UnregisterCallback(const sp<IInterfaceEventCallback>& callback) {
111 for (auto it = interface_event_callbacks_.begin();
112 it != interface_event_callbacks_.end();
113 it++) {
114 if (IInterface::asBinder(callback) == IInterface::asBinder(*it)) {
115 interface_event_callbacks_.erase(it);
116 LOG(INFO) << "Unregister interface event callback";
117 return Status::ok();
118 }
119 }
120 LOG(WARNING) << "Failed to find registered interface event callback"
121 << " to unregister";
122 return Status::ok();
123 }
124
createApInterface(const std::string & iface_name,sp<IApInterface> * created_interface)125 Status Server::createApInterface(const std::string& iface_name,
126 sp<IApInterface>* created_interface) {
127 InterfaceInfo interface;
128 uint32_t wiphy_index;
129
130 if (!SetupInterface(iface_name, &interface, &wiphy_index)) {
131 return Status::ok(); // Logging was done internally
132 }
133
134 LOG(INFO) << "createApInterface: wiphy_index " << wiphy_index << " iface_name " << iface_name;
135
136 unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
137 interface.name,
138 interface.if_index,
139 netlink_utils_,
140 if_tool_.get()));
141 *created_interface = ap_interface->GetBinder();
142 BroadcastApInterfaceReady(ap_interface->GetBinder());
143 ap_interfaces_[iface_name] = std::move(ap_interface);
144 if (hasNoIfaceForWiphyIndex(wiphy_index)) {
145 UpdateBandWiphyIndexMap(wiphy_index);
146 } else {
147 LOG(INFO) << "Band info for wiphy_index " << wiphy_index << " already available";
148 }
149 iface_to_wiphy_index_map_[iface_name] = wiphy_index;
150 return Status::ok();
151 }
152
tearDownApInterface(const std::string & iface_name,bool * out_success)153 Status Server::tearDownApInterface(const std::string& iface_name,
154 bool* out_success) {
155 *out_success = false;
156 const auto iter = ap_interfaces_.find(iface_name);
157 if (iter != ap_interfaces_.end()) {
158 BroadcastApInterfaceTornDown(iter->second->GetBinder());
159 ap_interfaces_.erase(iter);
160 *out_success = true;
161 }
162
163 const auto iter_wi = iface_to_wiphy_index_map_.find(iface_name);
164 if (iter_wi != iface_to_wiphy_index_map_.end()) {
165 int wiphy_index = iter_wi->second;
166 LOG(INFO) << "tearDownApInterface: erasing wiphy_index for iface_name " << iface_name;
167 iface_to_wiphy_index_map_.erase(iter_wi);
168 if (hasNoIfaceForWiphyIndex(wiphy_index)) {
169 EraseBandWiphyIndexMap(wiphy_index);
170 } else {
171 LOG(INFO) << "Band info for wiphy_index " << wiphy_index << " retained";
172 }
173 }
174
175 return Status::ok();
176 }
177
hasNoIfaceForWiphyIndex(int wiphy_index)178 bool Server::hasNoIfaceForWiphyIndex(int wiphy_index) {
179 return std::find_if(
180 iface_to_wiphy_index_map_.begin(),
181 iface_to_wiphy_index_map_.end(),
182 [wiphy_index](const auto& kv) { return kv.second == wiphy_index; })
183 == iface_to_wiphy_index_map_.end();
184 }
185
createClientInterface(const std::string & iface_name,sp<IClientInterface> * created_interface)186 Status Server::createClientInterface(const std::string& iface_name,
187 sp<IClientInterface>* created_interface) {
188 InterfaceInfo interface;
189 uint32_t wiphy_index;
190
191 if (!SetupInterface(iface_name, &interface, &wiphy_index)) {
192 return Status::ok(); // Logging was done internally
193 }
194
195 LOG(INFO) << "createClientInterface: wiphy_index " << wiphy_index << " iface_name " << iface_name;
196
197 unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
198 wiphy_index,
199 interface.name,
200 interface.if_index,
201 interface.mac_address,
202 if_tool_.get(),
203 netlink_utils_,
204 scan_utils_));
205 *created_interface = client_interface->GetBinder();
206 BroadcastClientInterfaceReady(client_interface->GetBinder());
207 client_interfaces_[iface_name] = std::move(client_interface);
208 if (hasNoIfaceForWiphyIndex(wiphy_index)) {
209 UpdateBandWiphyIndexMap(wiphy_index);
210 } else {
211 LOG(INFO) << "Band info for wiphy_index " << wiphy_index << " already available";
212 }
213 iface_to_wiphy_index_map_[iface_name] = wiphy_index;
214
215 return Status::ok();
216 }
217
tearDownClientInterface(const std::string & iface_name,bool * out_success)218 Status Server::tearDownClientInterface(const std::string& iface_name,
219 bool* out_success) {
220 *out_success = false;
221 const auto iter = client_interfaces_.find(iface_name);
222 if (iter != client_interfaces_.end()) {
223 BroadcastClientInterfaceTornDown(iter->second->GetBinder());
224 client_interfaces_.erase(iter);
225 *out_success = true;
226 }
227
228 const auto iter_wi = iface_to_wiphy_index_map_.find(iface_name);
229 if (iter_wi != iface_to_wiphy_index_map_.end()) {
230 int wiphy_index = iter_wi->second;
231 LOG(INFO) << "tearDownClientInterface: erasing wiphy_index for iface_name " << iface_name;
232 iface_to_wiphy_index_map_.erase(iter_wi);
233 if (hasNoIfaceForWiphyIndex(wiphy_index)) {
234 EraseBandWiphyIndexMap(wiphy_index);
235 } else {
236 LOG(INFO) << "Band info for wiphy_index " << wiphy_index << " retained";
237 }
238 }
239
240 return Status::ok();
241 }
242
tearDownInterfaces()243 Status Server::tearDownInterfaces() {
244 for (auto& it : client_interfaces_) {
245 BroadcastClientInterfaceTornDown(it.second->GetBinder());
246 }
247 client_interfaces_.clear();
248
249 for (auto& it : ap_interfaces_) {
250 BroadcastApInterfaceTornDown(it.second->GetBinder());
251 }
252 ap_interfaces_.clear();
253
254 MarkDownAllInterfaces();
255
256 for (auto& it : iface_to_wiphy_index_map_) {
257 netlink_utils_->UnsubscribeRegDomainChange(it.second);
258 EraseBandWiphyIndexMap(it.second);
259 }
260 iface_to_wiphy_index_map_.clear();
261
262 return Status::ok();
263 }
264
GetClientInterfaces(vector<sp<IBinder>> * out_client_interfaces)265 Status Server::GetClientInterfaces(vector<sp<IBinder>>* out_client_interfaces) {
266 vector<sp<android::IBinder>> client_interfaces_binder;
267 for (auto& it : client_interfaces_) {
268 out_client_interfaces->push_back(asBinder(it.second->GetBinder()));
269 }
270 return binder::Status::ok();
271 }
272
GetApInterfaces(vector<sp<IBinder>> * out_ap_interfaces)273 Status Server::GetApInterfaces(vector<sp<IBinder>>* out_ap_interfaces) {
274 vector<sp<IBinder>> ap_interfaces_binder;
275 for (auto& it : ap_interfaces_) {
276 out_ap_interfaces->push_back(asBinder(it.second->GetBinder()));
277 }
278 return binder::Status::ok();
279 }
280
dump(int fd,const Vector<String16> &)281 status_t Server::dump(int fd, const Vector<String16>& /*args*/) {
282 if (!PermissionCache::checkCallingPermission(String16(kPermissionDump))) {
283 IPCThreadState* ipc = android::IPCThreadState::self();
284 LOG(ERROR) << "Caller (uid: " << ipc->getCallingUid()
285 << ") is not permitted to dump wificond state";
286 return PERMISSION_DENIED;
287 }
288
289 stringstream ss;
290 ss << "Cached interfaces list from kernel message: " << endl;
291 for (const auto& iface : debug_interfaces_) {
292 ss << "Interface index: " << iface.if_index
293 << ", name: " << iface.name
294 << ", wiphy index: " << iface.wiphy_index
295 << ", mac address: "
296 << LoggingUtils::GetMacString(iface.mac_address) << endl;
297 }
298
299 string country_code;
300 if (netlink_utils_->GetCountryCode(&country_code)) {
301 ss << "Current country code from kernel: " << country_code << endl;
302 } else {
303 ss << "Failed to get country code from kernel." << endl;
304 }
305
306 for (const auto& iface : client_interfaces_) {
307 iface.second->Dump(&ss);
308 }
309
310 for (const auto& iface : ap_interfaces_) {
311 iface.second->Dump(&ss);
312 }
313
314 ss << "Channel Type / Wiphy Index Mapping:" << endl;
315 for (const auto& it : band_to_wiphy_index_map_) {
316 ss << "Channel type " << it.first << ": " << it.second << endl;
317 }
318
319 if (!WriteStringToFd(ss.str(), fd)) {
320 PLOG(ERROR) << "Failed to dump state to fd " << fd;
321 return FAILED_TRANSACTION;
322 }
323
324 return OK;
325 }
326
MarkDownAllInterfaces()327 void Server::MarkDownAllInterfaces() {
328 std::string iface_name;
329
330 for (auto& it : iface_to_wiphy_index_map_) {
331 iface_name = it.first;
332 if_tool_->SetUpState(iface_name.c_str(), false);
333 }
334 }
335
getAvailable2gChannels(std::optional<vector<int32_t>> * out_frequencies)336 Status Server::getAvailable2gChannels(
337 std::optional<vector<int32_t>>* out_frequencies) {
338
339 int wiphy_index = GetWiphyIndexFromBand(NL80211_BAND_2GHZ);
340 BandInfo band_info;
341
342 if (!GetBandInfo(wiphy_index, &band_info)) {
343 out_frequencies->reset();
344 return Status::ok();
345 }
346
347 if (band_info.band_2g.size() == 0)
348 out_frequencies->reset();
349 else
350 out_frequencies->emplace(band_info.band_2g.begin(), band_info.band_2g.end());
351 return Status::ok();
352 }
353
getAvailable5gNonDFSChannels(std::optional<vector<int32_t>> * out_frequencies)354 Status Server::getAvailable5gNonDFSChannels(
355 std::optional<vector<int32_t>>* out_frequencies) {
356 int wiphy_index = GetWiphyIndexFromBand(NL80211_BAND_5GHZ);
357 BandInfo band_info;
358 if (!GetBandInfo(wiphy_index, &band_info)) {
359 out_frequencies->reset();
360 return Status::ok();
361 }
362
363 if (band_info.band_5g.size() == 0)
364 out_frequencies->reset();
365 else
366 out_frequencies->emplace(band_info.band_5g.begin(), band_info.band_5g.end());
367 return Status::ok();
368 }
369
getAvailableDFSChannels(std::optional<vector<int32_t>> * out_frequencies)370 Status Server::getAvailableDFSChannels(
371 std::optional<vector<int32_t>>* out_frequencies) {
372 int wiphy_index = GetWiphyIndexFromBand(NL80211_BAND_5GHZ);
373 BandInfo band_info;
374 if (!GetBandInfo(wiphy_index, &band_info)) {
375 out_frequencies->reset();
376 return Status::ok();
377 }
378
379 if (band_info.band_dfs.size() == 0)
380 out_frequencies->reset();
381 else
382 out_frequencies->emplace(band_info.band_dfs.begin(),
383 band_info.band_dfs.end());
384 return Status::ok();
385 }
386
getAvailable6gChannels(std::optional<vector<int32_t>> * out_frequencies)387 Status Server::getAvailable6gChannels(
388 std::optional<vector<int32_t>>* out_frequencies) {
389 int wiphy_index = GetWiphyIndexFromBand(NL80211_BAND_6GHZ);
390 BandInfo band_info;
391 if (!GetBandInfo(wiphy_index, &band_info)) {
392 out_frequencies->reset();
393 return Status::ok();
394 }
395
396 if (band_info.band_6g.size() == 0)
397 out_frequencies->reset();
398 else
399 out_frequencies->emplace(band_info.band_6g.begin(), band_info.band_6g.end());
400 return Status::ok();
401 }
402
getAvailable60gChannels(std::optional<vector<int32_t>> * out_frequencies)403 Status Server::getAvailable60gChannels(
404 std::optional<vector<int32_t>>* out_frequencies) {
405 int wiphy_index = GetWiphyIndexFromBand(NL80211_BAND_60GHZ);
406 BandInfo band_info;
407 if (!GetBandInfo(wiphy_index, &band_info)) {
408 out_frequencies->reset();
409 return Status::ok();
410 }
411
412 if (band_info.band_60g.size() == 0)
413 out_frequencies->reset();
414 else
415 out_frequencies->emplace(
416 band_info.band_60g.begin(), band_info.band_60g.end());
417
418 return Status::ok();
419 }
420
getDeviceWiphyCapabilities(const std::string & iface_name,std::optional<DeviceWiphyCapabilities> * capabilities)421 Status Server::getDeviceWiphyCapabilities(
422 const std::string& iface_name,
423 std::optional<DeviceWiphyCapabilities>* capabilities) {
424 int wiphy_index = FindWiphyIndex(iface_name);
425
426 if (wiphy_index == -1) {
427 LOG(ERROR) << "Failed to find iface_name " << iface_name;
428 capabilities = nullptr;
429 return Status::ok();
430 }
431
432 BandInfo band_info;
433 ScanCapabilities scan_capabilities_ignored;
434 WiphyFeatures wiphy_features_ignored;
435
436 if (!netlink_utils_->GetWiphyInfo(wiphy_index, &band_info,
437 &scan_capabilities_ignored,
438 &wiphy_features_ignored)) {
439 LOG(ERROR) << "Failed to get wiphy info from kernel";
440 capabilities = nullptr;
441 return Status::ok();
442 }
443
444 capabilities->emplace();
445
446 capabilities->value().is80211nSupported_ = band_info.is_80211n_supported;
447 capabilities->value().is80211acSupported_ = band_info.is_80211ac_supported;
448 capabilities->value().is80211axSupported_ = band_info.is_80211ax_supported;
449 capabilities->value().is80211beSupported_ = band_info.is_80211be_supported;
450 capabilities->value().is160MhzSupported_ = band_info.is_160_mhz_supported;
451 capabilities->value().is80p80MhzSupported_ = band_info.is_80p80_mhz_supported;
452 capabilities->value().is320MhzSupported_ = band_info.is_320_mhz_supported;
453 capabilities->value().maxTxStreams_ = band_info.max_tx_streams;
454 capabilities->value().maxRxStreams_ = band_info.max_rx_streams;
455
456 return Status::ok();
457 }
458
SetupInterface(const std::string & iface_name,InterfaceInfo * interface,uint32_t * wiphy_index)459 bool Server::SetupInterface(const std::string& iface_name,
460 InterfaceInfo* interface,
461 uint32_t *wiphy_index) {
462 if (!netlink_utils_->GetWiphyIndex(wiphy_index, iface_name)) {
463 LOG(ERROR) << "Failed to get wiphy index";
464 return false;
465 }
466 // TODO: It may need to handle multi-chips case to get multi-wiphy index and
467 // register corresponding callback.
468 netlink_utils_->SubscribeRegDomainChange(
469 *wiphy_index,
470 std::bind(&Server::OnRegDomainChanged,
471 this,
472 _1,
473 _2));
474
475 debug_interfaces_.clear();
476 if (!netlink_utils_->GetInterfaces(*wiphy_index, &debug_interfaces_)) {
477 LOG(ERROR) << "Failed to get interfaces info from kernel for iface_name " << iface_name << " wiphy_index " << *wiphy_index;
478 return false;
479 }
480
481 for (const auto& iface : debug_interfaces_) {
482 if (iface.name == iface_name) {
483 *interface = iface;
484 return true;
485 }
486 }
487
488 LOG(ERROR) << "No usable interface found";
489 return false;
490 }
491
handleCountryCodeChanged()492 void Server::handleCountryCodeChanged() {
493 uint32_t wiphy_index;
494 set<uint32_t> handled_wiphy_index;
495 for (auto& it : client_interfaces_) {
496 it.second->UpdateBandInfo();
497 if (netlink_utils_->GetWiphyIndex(&wiphy_index, it.first)) {
498 if (handled_wiphy_index.find(wiphy_index) == handled_wiphy_index.end()) {
499 UpdateBandWiphyIndexMap(wiphy_index);
500 LogSupportedBands(wiphy_index);
501 handled_wiphy_index.insert(wiphy_index);
502 }
503 }
504 }
505 for (auto& it : ap_interfaces_) {
506 if (netlink_utils_->GetWiphyIndex(&wiphy_index, it.first)) {
507 if (handled_wiphy_index.find(wiphy_index) == handled_wiphy_index.end()) {
508 UpdateBandWiphyIndexMap(wiphy_index);
509 LogSupportedBands(wiphy_index);
510 handled_wiphy_index.insert(wiphy_index);
511 }
512 }
513 }
514 }
515
OnRegDomainChanged(uint32_t wiphy_index,std::string & country_code)516 void Server::OnRegDomainChanged(uint32_t wiphy_index, std::string& country_code) {
517 string current_country_code;
518 if (country_code.empty()) {
519 LOG(DEBUG) << "Regulatory domain changed with empty country code (world mode?)";
520 if (!netlink_utils_->GetCountryCode(¤t_country_code)) {
521 LOG(ERROR) << "Fail to get country code on wiphy_index:" << wiphy_index;
522 }
523 } else {
524 current_country_code = country_code;
525 }
526 if (!current_country_code.empty()) {
527 LOG(INFO) << "Regulatory domain changed to country: " << current_country_code
528 << " on wiphy_index: " << wiphy_index;
529 BroadcastRegDomainChanged(current_country_code);
530 }
531 // Sometimes lower layer sends stale wiphy index when there are no
532 // interfaces. So update band - wiphy index mapping only if an
533 // interface exists
534 if (!hasNoIfaceForWiphyIndex(wiphy_index)) {
535 handleCountryCodeChanged();
536 }
537 }
538
notifyCountryCodeChanged()539 android::binder::Status Server::notifyCountryCodeChanged() {
540 LOG(INFO) << "Receive notifyCountryCodeChanged";
541 handleCountryCodeChanged();
542 return Status::ok();
543 }
544
LogSupportedBands(uint32_t wiphy_index)545 void Server::LogSupportedBands(uint32_t wiphy_index) {
546 BandInfo band_info;
547 ScanCapabilities scan_capabilities;
548 WiphyFeatures wiphy_features;
549 netlink_utils_->GetWiphyInfo(wiphy_index,
550 &band_info,
551 &scan_capabilities,
552 &wiphy_features);
553
554 stringstream ss;
555 for (unsigned int i = 0; i < band_info.band_2g.size(); i++) {
556 ss << " " << band_info.band_2g[i];
557 }
558 LOG(INFO) << "2.4Ghz frequencies:"<< ss.str();
559 ss.str("");
560
561 for (unsigned int i = 0; i < band_info.band_5g.size(); i++) {
562 ss << " " << band_info.band_5g[i];
563 }
564 LOG(INFO) << "5Ghz non-DFS frequencies:"<< ss.str();
565 ss.str("");
566
567 for (unsigned int i = 0; i < band_info.band_dfs.size(); i++) {
568 ss << " " << band_info.band_dfs[i];
569 }
570 LOG(INFO) << "5Ghz DFS frequencies:"<< ss.str();
571 ss.str("");
572
573 for (unsigned int i = 0; i < band_info.band_6g.size(); i++) {
574 ss << " " << band_info.band_6g[i];
575 }
576 LOG(INFO) << "6Ghz frequencies:"<< ss.str();
577 ss.str("");
578
579 for (unsigned int i = 0; i < band_info.band_60g.size(); i++) {
580 ss << " " << band_info.band_60g[i];
581 }
582 LOG(INFO) << "60Ghz frequencies:"<< ss.str();
583 }
584
BroadcastClientInterfaceReady(sp<IClientInterface> network_interface)585 void Server::BroadcastClientInterfaceReady(
586 sp<IClientInterface> network_interface) {
587 for (auto& it : interface_event_callbacks_) {
588 it->OnClientInterfaceReady(network_interface);
589 }
590 }
591
BroadcastApInterfaceReady(sp<IApInterface> network_interface)592 void Server::BroadcastApInterfaceReady(
593 sp<IApInterface> network_interface) {
594 for (auto& it : interface_event_callbacks_) {
595 it->OnApInterfaceReady(network_interface);
596 }
597 }
598
BroadcastClientInterfaceTornDown(sp<IClientInterface> network_interface)599 void Server::BroadcastClientInterfaceTornDown(
600 sp<IClientInterface> network_interface) {
601 for (auto& it : interface_event_callbacks_) {
602 it->OnClientTorndownEvent(network_interface);
603 }
604 }
605
BroadcastApInterfaceTornDown(sp<IApInterface> network_interface)606 void Server::BroadcastApInterfaceTornDown(
607 sp<IApInterface> network_interface) {
608 for (auto& it : interface_event_callbacks_) {
609 it->OnApTorndownEvent(network_interface);
610 }
611 }
612
BroadcastRegDomainChanged(std::string country_code)613 void Server::BroadcastRegDomainChanged(
614 std::string country_code) {
615 for (const auto& it : wificond_event_callbacks_) {
616 it->OnRegDomainChanged(country_code);
617 }
618 }
619
FindWiphyIndex(const std::string & iface_name)620 int Server::FindWiphyIndex(
621 const std::string& iface_name) {
622 int wiphy_index = -1;
623
624 for (auto& it : iface_to_wiphy_index_map_) {
625 if (it.first == iface_name) {
626 wiphy_index = it.second;
627 break;
628 }
629 }
630
631 return wiphy_index;
632 }
633
GetBandInfo(int wiphy_index,BandInfo * band_info)634 bool Server::GetBandInfo(
635 int wiphy_index,
636 BandInfo* band_info) {
637
638 if (wiphy_index == -1) return false;
639
640 ScanCapabilities scan_capabilities_ignored;
641 WiphyFeatures wiphy_features_ignored;
642
643 if (!netlink_utils_->GetWiphyInfo(wiphy_index, band_info,
644 &scan_capabilities_ignored,
645 &wiphy_features_ignored)) {
646 LOG(ERROR) << "Failed to get wiphy index " << wiphy_index << " info from kernel";
647 return false;
648 }
649
650 return true;
651 }
652
GetWiphyIndexFromBand(int band)653 int Server::GetWiphyIndexFromBand(int band) {
654 auto iter = band_to_wiphy_index_map_.find(band);
655 return (iter != band_to_wiphy_index_map_.end()) ? iter->second : -1;
656 }
657
UpdateBandWiphyIndexMap(int wiphy_index)658 void Server::UpdateBandWiphyIndexMap(int wiphy_index) {
659 LOG(DEBUG) << "UpdateBandWiphyIndexMap for wiphy_index " << wiphy_index;
660 BandInfo band_info;
661 if (!GetBandInfo(wiphy_index, &band_info)) return;
662
663 if (band_info.band_2g.size() != 0
664 && band_to_wiphy_index_map_.find(NL80211_BAND_2GHZ) == band_to_wiphy_index_map_.end()) {
665 band_to_wiphy_index_map_[NL80211_BAND_2GHZ] = wiphy_index;
666 LOG(INFO) << "add channel type " << NL80211_BAND_2GHZ
667 << " support at wiphy index: " << wiphy_index;
668 }
669 if (band_info.band_5g.size() != 0
670 && band_to_wiphy_index_map_.find(NL80211_BAND_5GHZ) == band_to_wiphy_index_map_.end()) {
671 band_to_wiphy_index_map_[NL80211_BAND_5GHZ] = wiphy_index;
672 LOG(INFO) << "add channel type " << NL80211_BAND_5GHZ
673 << " support at wiphy index: " << wiphy_index;
674 }
675 if (band_info.band_dfs.size() != 0
676 && band_to_wiphy_index_map_.find(NL80211_BAND_5GHZ) == band_to_wiphy_index_map_.end()) {
677 band_to_wiphy_index_map_[NL80211_BAND_5GHZ] = wiphy_index;
678 LOG(INFO) << "add channel type " << NL80211_BAND_5GHZ
679 << " support at wiphy index: " << wiphy_index;
680 }
681 if (band_info.band_6g.size() != 0
682 && band_to_wiphy_index_map_.find(NL80211_BAND_6GHZ) == band_to_wiphy_index_map_.end()) {
683 band_to_wiphy_index_map_[NL80211_BAND_6GHZ] = wiphy_index;
684 LOG(INFO) << "add channel type " << NL80211_BAND_6GHZ
685 << " support at wiphy index: " << wiphy_index;
686 }
687 if (band_info.band_60g.size() != 0
688 && band_to_wiphy_index_map_.find(NL80211_BAND_60GHZ) == band_to_wiphy_index_map_.end()) {
689 band_to_wiphy_index_map_[NL80211_BAND_60GHZ] = wiphy_index;
690 LOG(INFO) << "add channel type " << NL80211_BAND_60GHZ
691 << " support at wiphy index: " << wiphy_index;
692 }
693 }
694
EraseBandWiphyIndexMap(int wiphy_index)695 void Server::EraseBandWiphyIndexMap(int wiphy_index) {
696 LOG(DEBUG) << "EraseBandWiphyIndexMap for wiphy_index " << wiphy_index;
697 for (auto it = band_to_wiphy_index_map_.begin();
698 // end() is computed every iteration since erase() could invalidate it
699 it != band_to_wiphy_index_map_.end();
700 /* no increment */ ) {
701 if (it->second == wiphy_index) {
702 LOG(INFO) << "remove channel type " << it->first
703 << " support at wiphy index " << it->second;
704 // erase returns iterator to element following erased element, or end() if the last element
705 // was erased
706 it = band_to_wiphy_index_map_.erase(it);
707 } else {
708 ++it;
709 }
710 }
711 }
712 } // namespace wificond
713 } // namespace android
714