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