OSDN Git Service

Cleanup p2p0 interface upon tearDownInterfaces().
[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 <sstream>
20
21 #include <android-base/logging.h>
22
23 #include "wificond/net/netlink_utils.h"
24 #include "wificond/scanning/scan_utils.h"
25
26 using android::binder::Status;
27 using android::sp;
28 using android::IBinder;
29 using android::net::wifi::IApInterface;
30 using android::net::wifi::IClientInterface;
31 using android::net::wifi::IInterfaceEventCallback;
32 using android::net::wifi::IRttClient;
33 using android::net::wifi::IRttController;
34 using android::wifi_system::HostapdManager;
35 using android::wifi_system::InterfaceTool;
36 using android::wifi_system::SupplicantManager;
37
38 using std::placeholders::_1;
39 using std::string;
40 using std::stringstream;
41 using std::unique_ptr;
42 using std::vector;
43
44 namespace android {
45 namespace wificond {
46
47 Server::Server(unique_ptr<InterfaceTool> if_tool,
48                unique_ptr<SupplicantManager> supplicant_manager,
49                unique_ptr<HostapdManager> hostapd_manager,
50                NetlinkUtils* netlink_utils,
51                ScanUtils* scan_utils)
52     : if_tool_(std::move(if_tool)),
53       supplicant_manager_(std::move(supplicant_manager)),
54       hostapd_manager_(std::move(hostapd_manager)),
55       netlink_utils_(netlink_utils),
56       scan_utils_(scan_utils) {
57 }
58
59 Status Server::RegisterCallback(const sp<IInterfaceEventCallback>& callback) {
60   for (auto& it : interface_event_callbacks_) {
61     if (IInterface::asBinder(callback) == IInterface::asBinder(it)) {
62       LOG(WARNING) << "Ignore duplicate interface event callback registration";
63       return Status::ok();
64     }
65   }
66   LOG(INFO) << "New interface event callback registered";
67   interface_event_callbacks_.push_back(callback);
68   return Status::ok();
69 }
70
71 Status Server::UnregisterCallback(const sp<IInterfaceEventCallback>& callback) {
72   for (auto it = interface_event_callbacks_.begin();
73        it != interface_event_callbacks_.end();
74        it++) {
75     if (IInterface::asBinder(callback) == IInterface::asBinder(*it)) {
76       interface_event_callbacks_.erase(it);
77       LOG(INFO) << "Unregister interface event callback";
78       return Status::ok();
79     }
80   }
81   LOG(WARNING) << "Failed to find registered interface event callback"
82                << " to unregister";
83   return Status::ok();
84 }
85
86 Status Server::registerRttClient(const sp<IRttClient>& rtt_client,
87                                  sp<IRttController>* out_rtt_controller) {
88   if (rtt_controller_ == nullptr) {
89     rtt_controller_.reset(new RttControllerImpl());
90   }
91   rtt_controller_->RegisterRttClient(rtt_client);
92
93   *out_rtt_controller = rtt_controller_->GetBinder();
94   return Status::ok();
95 }
96
97 Status Server::unregisterRttClient(const sp<IRttClient>& rttClient) {
98   rtt_controller_->UnregisterRttClient(rttClient);
99   if (rtt_controller_->GetClientCount() == 0) {
100     rtt_controller_.reset();
101   }
102   return Status::ok();
103 }
104
105 Status Server::createApInterface(sp<IApInterface>* created_interface) {
106   InterfaceInfo interface;
107   if (!SetupInterface(&interface)) {
108     return Status::ok();  // Logging was done internally
109   }
110
111   unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
112       interface.name,
113       interface.index,
114       netlink_utils_,
115       if_tool_.get(),
116       hostapd_manager_.get()));
117   *created_interface = ap_interface->GetBinder();
118   ap_interfaces_.push_back(std::move(ap_interface));
119   BroadcastApInterfaceReady(ap_interfaces_.back()->GetBinder());
120
121   return Status::ok();
122 }
123
124 Status Server::createClientInterface(sp<IClientInterface>* created_interface) {
125   InterfaceInfo interface;
126   if (!SetupInterface(&interface)) {
127     return Status::ok();  // Logging was done internally
128   }
129
130   unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
131       wiphy_index_,
132       interface.name,
133       interface.index,
134       interface.mac_address,
135       if_tool_.get(),
136       supplicant_manager_.get(),
137       netlink_utils_,
138       scan_utils_));
139   *created_interface = client_interface->GetBinder();
140   client_interfaces_.push_back(std::move(client_interface));
141   BroadcastClientInterfaceReady(client_interfaces_.back()->GetBinder());
142
143   return Status::ok();
144 }
145
146 Status Server::tearDownInterfaces() {
147   for (auto& it : client_interfaces_) {
148     BroadcastClientInterfaceTornDown(it->GetBinder());
149   }
150   client_interfaces_.clear();
151
152   for (auto& it : ap_interfaces_) {
153     BroadcastApInterfaceTornDown(it->GetBinder());
154   }
155   ap_interfaces_.clear();
156
157   MarkDownAllInterfaces();
158
159   netlink_utils_->UnsubscribeRegDomainChange(wiphy_index_);
160
161   return Status::ok();
162 }
163
164 Status Server::GetClientInterfaces(vector<sp<IBinder>>* out_client_interfaces) {
165   vector<sp<android::IBinder>> client_interfaces_binder;
166   for (auto& it : client_interfaces_) {
167     out_client_interfaces->push_back(asBinder(it->GetBinder()));
168   }
169   return binder::Status::ok();
170 }
171
172 Status Server::GetApInterfaces(vector<sp<IBinder>>* out_ap_interfaces) {
173   vector<sp<IBinder>> ap_interfaces_binder;
174   for (auto& it : ap_interfaces_) {
175     out_ap_interfaces->push_back(asBinder(it->GetBinder()));
176   }
177   return binder::Status::ok();
178 }
179
180 void Server::MarkDownAllInterfaces() {
181   uint32_t wiphy_index;
182   vector<InterfaceInfo> interfaces;
183   if (netlink_utils_->GetWiphyIndex(&wiphy_index) &&
184       netlink_utils_->GetInterfaces(wiphy_index, &interfaces)) {
185     for (InterfaceInfo& interface : interfaces) {
186       if_tool_->SetUpState(interface.name.c_str(), false);
187     }
188   }
189 }
190
191 void Server::CleanUpSystemState() {
192   supplicant_manager_->StopSupplicant();
193   hostapd_manager_->StopHostapd();
194   MarkDownAllInterfaces();
195 }
196
197 bool Server::SetupInterface(InterfaceInfo* interface) {
198   if (!ap_interfaces_.empty() || !client_interfaces_.empty()) {
199     // In the future we may support multiple interfaces at once.  However,
200     // today, we support just one.
201     LOG(ERROR) << "Cannot create AP interface when other interfaces exist";
202     return false;
203   }
204
205   if (!RefreshWiphyIndex()) {
206     return false;
207   }
208
209   netlink_utils_->SubscribeRegDomainChange(
210           wiphy_index_,
211           std::bind(&Server::OnRegDomainChanged,
212           this,
213           _1));
214
215   vector<InterfaceInfo> interfaces;
216   if (!netlink_utils_->GetInterfaces(wiphy_index_, &interfaces)) {
217     LOG(ERROR) << "Failed to get interfaces info from kernel";
218     return false;
219   }
220
221   for (InterfaceInfo& iface : interfaces) {
222     // Some kernel/driver uses station type for p2p interface.
223     // In that case we can only rely on hard-coded name to exclude
224     // p2p interface from station interfaces.
225     if (iface.name != "p2p0") {
226       *interface = iface;
227       return true;
228     }
229   }
230
231   LOG(ERROR) << "No usable interface found";
232   return false;
233 }
234
235 bool Server::RefreshWiphyIndex() {
236   if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) {
237     LOG(ERROR) << "Failed to get wiphy index";
238     return false;
239   }
240   return true;
241 }
242
243 void Server::OnRegDomainChanged(std::string& country_code) {
244   if (country_code.empty()) {
245     LOG(INFO) << "Regulatory domain changed";
246   } else {
247     LOG(INFO) << "Regulatory domain changed to country: " << country_code;
248   }
249   LogSupportedBands();
250 }
251
252 void Server::LogSupportedBands() {
253   BandInfo band_info;
254   ScanCapabilities scan_capabilities;
255   WiphyFeatures wiphy_features;
256   netlink_utils_->GetWiphyInfo(wiphy_index_,
257                                &band_info,
258                                &scan_capabilities,
259                                &wiphy_features);
260
261   stringstream ss;
262   for (unsigned int i = 0; i < band_info.band_2g.size(); i++) {
263     ss << " " << band_info.band_2g[i];
264   }
265   LOG(INFO) << "2.4Ghz frequencies:"<< ss.str();
266   ss.str("");
267
268   for (unsigned int i = 0; i < band_info.band_5g.size(); i++) {
269     ss << " " << band_info.band_5g[i];
270   }
271   LOG(INFO) << "5Ghz non-DFS frequencies:"<< ss.str();
272   ss.str("");
273
274   for (unsigned int i = 0; i < band_info.band_dfs.size(); i++) {
275     ss << " " << band_info.band_dfs[i];
276   }
277   LOG(INFO) << "5Ghz DFS frequencies:"<< ss.str();
278 }
279
280 void Server::BroadcastClientInterfaceReady(
281     sp<IClientInterface> network_interface) {
282   for (auto& it : interface_event_callbacks_) {
283     it->OnClientInterfaceReady(network_interface);
284   }
285 }
286
287 void Server::BroadcastApInterfaceReady(
288     sp<IApInterface> network_interface) {
289   for (auto& it : interface_event_callbacks_) {
290     it->OnApInterfaceReady(network_interface);
291   }
292 }
293
294 void Server::BroadcastClientInterfaceTornDown(
295     sp<IClientInterface> network_interface) {
296   for (auto& it : interface_event_callbacks_) {
297     it->OnClientTorndownEvent(network_interface);
298   }
299 }
300
301 void Server::BroadcastApInterfaceTornDown(
302     sp<IApInterface> network_interface) {
303   for (auto& it : interface_event_callbacks_) {
304     it->OnApTorndownEvent(network_interface);
305   }
306 }
307
308 }  // namespace wificond
309 }  // namespace android