OSDN Git Service

Support fetching packet counters for wificond
[android-x86/system-connectivity-wificond.git] / server.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/server.h"
18
19 #include <android-base/logging.h>
20
21 #include "wificond/net/netlink_utils.h"
22 #include "wificond/scanning/scan_utils.h"
23
24 using android::binder::Status;
25 using android::sp;
26 using android::IBinder;
27 using std::string;
28 using std::vector;
29 using std::unique_ptr;
30 using android::net::wifi::IApInterface;
31 using android::net::wifi::IClientInterface;
32 using android::net::wifi::IInterfaceEventCallback;
33 using android::wifi_hal::DriverTool;
34 using android::wifi_system::HalTool;
35 using android::wifi_system::HostapdManager;
36 using android::wifi_system::InterfaceTool;
37 using android::wifi_system::SupplicantManager;
38
39 namespace android {
40 namespace wificond {
41
42 Server::Server(unique_ptr<HalTool> hal_tool,
43                unique_ptr<InterfaceTool> if_tool,
44                unique_ptr<DriverTool> driver_tool,
45                unique_ptr<SupplicantManager> supplicant_manager,
46                unique_ptr<HostapdManager> hostapd_manager,
47                NetlinkUtils* netlink_utils,
48                ScanUtils* scan_utils)
49     : hal_tool_(std::move(hal_tool)),
50       if_tool_(std::move(if_tool)),
51       driver_tool_(std::move(driver_tool)),
52       supplicant_manager_(std::move(supplicant_manager)),
53       hostapd_manager_(std::move(hostapd_manager)),
54       netlink_utils_(netlink_utils),
55       scan_utils_(scan_utils) {
56 }
57
58 Status Server::RegisterCallback(const sp<IInterfaceEventCallback>& callback) {
59   for (auto& it : interface_event_callbacks_) {
60     if (IInterface::asBinder(callback) == IInterface::asBinder(it)) {
61       LOG(WARNING) << "Ignore duplicate interface event callback registration";
62       return Status::ok();
63     }
64   }
65   LOG(INFO) << "New interface event callback registered";
66   interface_event_callbacks_.push_back(callback);
67   return Status::ok();
68 }
69
70 Status Server::UnregisterCallback(const sp<IInterfaceEventCallback>& callback) {
71   for (auto it = interface_event_callbacks_.begin();
72        it != interface_event_callbacks_.end();
73        it++) {
74     if (IInterface::asBinder(callback) == IInterface::asBinder(*it)) {
75       interface_event_callbacks_.erase(it);
76       LOG(INFO) << "Unregister interface event callback";
77       return Status::ok();
78     }
79   }
80   LOG(WARNING) << "Failed to find registered interface event callback"
81                << " to unregister";
82   return Status::ok();
83 }
84
85
86 Status Server::createApInterface(sp<IApInterface>* created_interface) {
87   string interface_name;
88   uint32_t interface_index;
89   vector<uint8_t> interface_mac_addr;
90   if (!SetupInterfaceForMode(DriverTool::kFirmwareModeAp,
91                              &interface_name,
92                              &interface_index,
93                              &interface_mac_addr)) {
94     return Status::ok();  // Logging was done internally
95   }
96
97   unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
98       interface_name,
99       interface_index,
100       if_tool_.get(),
101       hostapd_manager_.get()));
102   *created_interface = ap_interface->GetBinder();
103   ap_interfaces_.push_back(std::move(ap_interface));
104   BroadcastApInterfaceReady(ap_interfaces_.back()->GetBinder());
105
106   return Status::ok();
107 }
108
109 Status Server::createClientInterface(sp<IClientInterface>* created_interface) {
110   string interface_name;
111   uint32_t interface_index;
112   vector<uint8_t> interface_mac_addr;
113   if (!SetupInterfaceForMode(DriverTool::kFirmwareModeSta,
114                              &interface_name,
115                              &interface_index,
116                              &interface_mac_addr)) {
117     return Status::ok();  // Logging was done internally
118   }
119
120   unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
121       interface_name,
122       interface_index,
123       interface_mac_addr,
124       supplicant_manager_.get(),
125       netlink_utils_,
126       scan_utils_));
127   *created_interface = client_interface->GetBinder();
128   client_interfaces_.push_back(std::move(client_interface));
129   BroadcastClientInterfaceReady(client_interfaces_.back()->GetBinder());
130
131   return Status::ok();
132 }
133
134 Status Server::tearDownInterfaces() {
135   for (auto& it : client_interfaces_) {
136     BroadcastClientInterfaceTornDown(it->GetBinder());
137   }
138   client_interfaces_.clear();
139
140   for (auto& it : ap_interfaces_) {
141     BroadcastApInterfaceTornDown(it->GetBinder());
142   }
143   ap_interfaces_.clear();
144
145   if (!driver_tool_->UnloadDriver()) {
146     LOG(ERROR) << "Failed to unload WiFi driver!";
147   }
148   return Status::ok();
149 }
150
151 Status Server::GetClientInterfaces(vector<sp<IBinder>>* out_client_interfaces) {
152   vector<sp<android::IBinder>> client_interfaces_binder;
153   for (auto& it : client_interfaces_) {
154     out_client_interfaces->push_back(asBinder(it->GetBinder()));
155   }
156   return binder::Status::ok();
157 }
158
159 Status Server::GetApInterfaces(vector<sp<IBinder>>* out_ap_interfaces) {
160   vector<sp<IBinder>> ap_interfaces_binder;
161   for (auto& it : ap_interfaces_) {
162     out_ap_interfaces->push_back(asBinder(it->GetBinder()));
163   }
164   return binder::Status::ok();
165 }
166
167 void Server::CleanUpSystemState() {
168   supplicant_manager_->StopSupplicant();
169   hostapd_manager_->StopHostapd();
170
171   uint32_t phy_index = 0;
172   uint32_t if_index = 0;
173   vector<uint8_t> mac;
174   string if_name;
175   if (netlink_utils_->GetWiphyIndex(&phy_index) &&
176       netlink_utils_->GetInterfaceInfo(phy_index,
177                                        &if_name,
178                                        &if_index,
179                                        &mac)) {
180     // If the kernel knows about a network interface, mark it as down.
181     // This prevents us from beaconing as an AP, or remaining associated
182     // as a client.
183     if_tool_->SetUpState(if_name.c_str(), false);
184   }
185   // "unloading the driver" is frequently a no-op in systems that
186   // don't have kernel modules, but just in case.
187   driver_tool_->UnloadDriver();
188 }
189
190 bool Server::SetupInterfaceForMode(int mode,
191                                    string* interface_name,
192                                    uint32_t* interface_index,
193                                    vector<uint8_t>* interface_mac_addr) {
194   if (!ap_interfaces_.empty() || !client_interfaces_.empty()) {
195     // In the future we may support multiple interfaces at once.  However,
196     // today, we support just one.
197     LOG(ERROR) << "Cannot create AP interface when other interfaces exist";
198     return false;
199   }
200
201   string result;
202   if (!driver_tool_->LoadDriver()) {
203     LOG(ERROR) << "Failed to load WiFi driver!";
204     return false;
205   }
206   if (!driver_tool_->ChangeFirmwareMode(mode)) {
207     LOG(ERROR) << "Failed to change WiFi firmware mode!";
208     return false;
209   }
210
211   if (!RefreshWiphyIndex()) {
212     return false;
213   }
214
215   if (!netlink_utils_->GetInterfaceInfo(wiphy_index_,
216                                         interface_name,
217                                         interface_index,
218                                         interface_mac_addr)) {
219     LOG(ERROR) << "Failed to get interface info from kernel";
220     return false;
221   }
222
223   return true;
224 }
225
226 bool Server::RefreshWiphyIndex() {
227   if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) {
228     LOG(ERROR) << "Failed to get wiphy index";
229     return false;
230   }
231   return true;
232 }
233
234 void Server::BroadcastClientInterfaceReady(
235     sp<IClientInterface> network_interface) {
236   for (auto& it : interface_event_callbacks_) {
237     it->OnClientInterfaceReady(network_interface);
238   }
239 }
240
241 void Server::BroadcastApInterfaceReady(
242     sp<IApInterface> network_interface) {
243   for (auto& it : interface_event_callbacks_) {
244     it->OnApInterfaceReady(network_interface);
245   }
246 }
247
248 void Server::BroadcastClientInterfaceTornDown(
249     sp<IClientInterface> network_interface) {
250   for (auto& it : interface_event_callbacks_) {
251     it->OnClientTorndownEvent(network_interface);
252   }
253 }
254
255 void Server::BroadcastApInterfaceTornDown(
256     sp<IApInterface> network_interface) {
257   for (auto& it : interface_event_callbacks_) {
258     it->OnApTorndownEvent(network_interface);
259   }
260 }
261
262 }  // namespace wificond
263 }  // namespace android