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