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