OSDN Git Service

Support abortScan am: 77732670f1 am: 36889eb2d7
[android-x86/system-connectivity-wificond.git] / client_interface_impl.cpp
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/client_interface_impl.h"
18
19 #include <vector>
20
21 #include <android-base/logging.h>
22 #include <wifi_system/supplicant_manager.h>
23
24 #include "wificond/client_interface_binder.h"
25 #include "wificond/net/mlme_event.h"
26 #include "wificond/net/netlink_utils.h"
27 #include "wificond/scanning/scan_result.h"
28 #include "wificond/scanning/scan_utils.h"
29 #include "wificond/scanning/scanner_impl.h"
30
31 using android::net::wifi::IClientInterface;
32 using com::android::server::wifi::wificond::NativeScanResult;
33 using android::sp;
34 using android::wifi_system::InterfaceTool;
35 using android::wifi_system::SupplicantManager;
36
37 using std::string;
38 using std::unique_ptr;
39 using std::vector;
40
41 namespace android {
42 namespace wificond {
43
44 MlmeEventHandlerImpl::MlmeEventHandlerImpl(ClientInterfaceImpl* client_interface)
45     : client_interface_(client_interface) {
46 }
47
48 MlmeEventHandlerImpl::~MlmeEventHandlerImpl() {
49 }
50
51 void MlmeEventHandlerImpl::OnConnect(unique_ptr<MlmeConnectEvent> event) {
52   if (!event->IsTimeout() && event->GetStatusCode() == 0) {
53     client_interface_->is_associated_ = true;
54     client_interface_->RefreshAssociateFreq();
55     client_interface_->bssid_ = event->GetBSSID();
56   } else {
57     if (event->IsTimeout()) {
58       LOG(INFO) << "Connect timeout";
59     }
60     client_interface_->is_associated_ = false;
61     client_interface_->bssid_.clear();
62   }
63 }
64
65 void MlmeEventHandlerImpl::OnRoam(unique_ptr<MlmeRoamEvent> event) {
66   if (event->GetStatusCode() == 0) {
67     client_interface_->is_associated_ = true;
68     client_interface_->RefreshAssociateFreq();
69     client_interface_->bssid_ = event->GetBSSID();
70   } else {
71     client_interface_->is_associated_ = false;
72     client_interface_->bssid_.clear();
73   }
74 }
75
76 void MlmeEventHandlerImpl::OnAssociate(unique_ptr<MlmeAssociateEvent> event) {
77   if (!event->IsTimeout() && event->GetStatusCode() == 0) {
78     client_interface_->is_associated_ = true;
79     client_interface_->RefreshAssociateFreq();
80     client_interface_->bssid_ = event->GetBSSID();
81   } else {
82     if (event->IsTimeout()) {
83       LOG(INFO) << "Associate timeout";
84     }
85     client_interface_->is_associated_ = false;
86     client_interface_->bssid_.clear();
87   }
88 }
89
90 void MlmeEventHandlerImpl::OnDisconnect(unique_ptr<MlmeDisconnectEvent> event) {
91   client_interface_->is_associated_ = false;
92   client_interface_->bssid_.clear();
93 }
94
95 void MlmeEventHandlerImpl::OnDisassociate(unique_ptr<MlmeDisassociateEvent> event) {
96   client_interface_->is_associated_ = false;
97   client_interface_->bssid_.clear();
98 }
99
100
101 ClientInterfaceImpl::ClientInterfaceImpl(
102     uint32_t wiphy_index,
103     const std::string& interface_name,
104     uint32_t interface_index,
105     const std::vector<uint8_t>& interface_mac_addr,
106     InterfaceTool* if_tool,
107     SupplicantManager* supplicant_manager,
108     NetlinkUtils* netlink_utils,
109     ScanUtils* scan_utils)
110     : wiphy_index_(wiphy_index),
111       interface_name_(interface_name),
112       interface_index_(interface_index),
113       interface_mac_addr_(interface_mac_addr),
114       if_tool_(if_tool),
115       supplicant_manager_(supplicant_manager),
116       netlink_utils_(netlink_utils),
117       scan_utils_(scan_utils),
118       mlme_event_handler_(new MlmeEventHandlerImpl(this)),
119       binder_(new ClientInterfaceBinder(this)),
120       is_associated_(false) {
121   netlink_utils_->SubscribeMlmeEvent(
122       interface_index_,
123       mlme_event_handler_.get());
124   if (!netlink_utils_->GetWiphyInfo(wiphy_index_,
125                                &band_info_,
126                                &scan_capabilities_,
127                                &wiphy_features_)) {
128     LOG(ERROR) << "Failed to get wiphy info from kernel";
129   }
130   LOG(INFO) << "create scanner for interface with index: "
131             << (int)interface_index_;
132   scanner_ = new ScannerImpl(wiphy_index,
133                              interface_index_,
134                              scan_capabilities_,
135                              wiphy_features_,
136                              this,
137                              netlink_utils_,
138                              scan_utils_);
139 }
140
141 ClientInterfaceImpl::~ClientInterfaceImpl() {
142   binder_->NotifyImplDead();
143   scanner_->Invalidate();
144   DisableSupplicant();
145   netlink_utils_->UnsubscribeMlmeEvent(interface_index_);
146   if_tool_->SetUpState(interface_name_.c_str(), false);
147 }
148
149 sp<android::net::wifi::IClientInterface> ClientInterfaceImpl::GetBinder() const {
150   return binder_;
151 }
152
153 bool ClientInterfaceImpl::EnableSupplicant() {
154   return supplicant_manager_->StartSupplicant();
155 }
156
157 bool ClientInterfaceImpl::DisableSupplicant() {
158   return supplicant_manager_->StopSupplicant();
159 }
160
161 bool ClientInterfaceImpl::GetPacketCounters(vector<int32_t>* out_packet_counters) {
162   StationInfo station_info;
163   if (!netlink_utils_->GetStationInfo(interface_index_,
164                                       interface_mac_addr_,
165                                       &station_info)) {
166     return false;
167   }
168   out_packet_counters->push_back(station_info.station_tx_packets);
169   out_packet_counters->push_back(station_info.station_tx_failed);
170
171   return true;
172 }
173
174 bool ClientInterfaceImpl::SignalPoll(vector<int32_t>* out_signal_poll_results) {
175   StationInfo station_info;
176   if (!netlink_utils_->GetStationInfo(interface_index_,
177                                       bssid_,
178                                       &station_info)) {
179     return false;
180   }
181   out_signal_poll_results->push_back(
182       static_cast<int32_t>(station_info.current_rssi));
183   // Convert from 100kbit/s to Mbps.
184   out_signal_poll_results->push_back(
185       static_cast<int32_t>(station_info.station_tx_bitrate/10));
186   // Association frequency.
187   out_signal_poll_results->push_back(
188       static_cast<int32_t>(associate_freq_));
189
190   return true;
191 }
192
193 const vector<uint8_t>& ClientInterfaceImpl::GetMacAddress() {
194   return interface_mac_addr_;
195 }
196
197 bool ClientInterfaceImpl::requestANQP(
198       const ::std::vector<uint8_t>& bssid,
199       const ::android::sp<::android::net::wifi::IANQPDoneCallback>& callback) {
200   // TODO(nywang): query ANQP information from wpa_supplicant.
201   return true;
202 }
203
204 bool ClientInterfaceImpl::RefreshAssociateFreq() {
205   // wpa_supplicant fetches associate frequency using the latest scan result.
206   // We should follow the same method here before we find a better solution.
207   std::vector<NativeScanResult> scan_results;
208   if (!scan_utils_->GetScanResult(interface_index_, &scan_results)) {
209     return false;
210   }
211   for (auto& scan_result : scan_results) {
212     if (scan_result.associated) {
213       associate_freq_ = scan_result.frequency;
214     }
215   }
216   return false;
217 }
218
219 bool ClientInterfaceImpl::IsAssociated() {
220   return is_associated_;
221 }
222
223 }  // namespace wificond
224 }  // namespace android