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