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, &current_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