OSDN Git Service

Merge branch 'stage-aosp-master' into nyc-dev-plus-aosp
[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::wifi_hal::DriverTool;
33 using android::wifi_system::HalTool;
34 using android::wifi_system::HostapdManager;
35 using android::wifi_system::InterfaceTool;
36 using android::wifi_system::SupplicantManager;
37
38 namespace android {
39 namespace wificond {
40
41 Server::Server(unique_ptr<HalTool> hal_tool,
42                unique_ptr<InterfaceTool> if_tool,
43                unique_ptr<DriverTool> driver_tool,
44                unique_ptr<SupplicantManager> supplicant_manager,
45                unique_ptr<HostapdManager> hostapd_manager,
46                NetlinkUtils* netlink_utils,
47                ScanUtils* scan_utils)
48     : hal_tool_(std::move(hal_tool)),
49       if_tool_(std::move(if_tool)),
50       driver_tool_(std::move(driver_tool)),
51       supplicant_manager_(std::move(supplicant_manager)),
52       hostapd_manager_(std::move(hostapd_manager)),
53       netlink_utils_(netlink_utils),
54       scan_utils_(scan_utils) {
55 }
56
57 Status Server::createApInterface(sp<IApInterface>* created_interface) {
58   string interface_name;
59   uint32_t interface_index;
60   vector<uint8_t> interface_mac_addr;
61   if (!SetupInterfaceForMode(DriverTool::kFirmwareModeAp,
62                              &interface_name,
63                              &interface_index,
64                              &interface_mac_addr)) {
65     return Status::ok();  // Logging was done internally
66   }
67
68   unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
69       interface_name,
70       interface_index,
71       if_tool_.get(),
72       hostapd_manager_.get()));
73   *created_interface = ap_interface->GetBinder();
74   ap_interfaces_.push_back(std::move(ap_interface));
75   return Status::ok();
76 }
77
78 Status Server::createClientInterface(sp<IClientInterface>* created_interface) {
79   string interface_name;
80   uint32_t interface_index;
81   vector<uint8_t> interface_mac_addr;
82   if (!SetupInterfaceForMode(DriverTool::kFirmwareModeSta,
83                              &interface_name,
84                              &interface_index,
85                              &interface_mac_addr)) {
86     return Status::ok();  // Logging was done internally
87   }
88
89   unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
90       interface_name,
91       interface_index,
92       interface_mac_addr,
93       supplicant_manager_.get(),
94       scan_utils_));
95   *created_interface = client_interface->GetBinder();
96   client_interfaces_.push_back(std::move(client_interface));
97   return Status::ok();
98 }
99
100 Status Server::tearDownInterfaces() {
101   ap_interfaces_.clear();
102   client_interfaces_.clear();
103   if (!driver_tool_->UnloadDriver()) {
104     LOG(ERROR) << "Failed to unload WiFi driver!";
105   }
106   return Status::ok();
107 }
108
109 void Server::CleanUpSystemState() {
110   supplicant_manager_->StopSupplicant();
111   hostapd_manager_->StopHostapd();
112
113   uint32_t phy_index = 0;
114   uint32_t if_index = 0;
115   vector<uint8_t> mac;
116   string if_name;
117   if (netlink_utils_->GetWiphyIndex(&phy_index) &&
118       netlink_utils_->GetInterfaceInfo(phy_index,
119                                        &if_name,
120                                        &if_index,
121                                        &mac)) {
122     // If the kernel knows about a network interface, mark it as down.
123     // This prevents us from beaconing as an AP, or remaining associated
124     // as a client.
125     if_tool_->SetUpState(if_name.c_str(), false);
126   }
127   // "unloading the driver" is frequently a no-op in systems that
128   // don't have kernel modules, but just in case.
129   driver_tool_->UnloadDriver();
130 }
131
132 bool Server::SetupInterfaceForMode(int mode,
133                                    string* interface_name,
134                                    uint32_t* interface_index,
135                                    vector<uint8_t>* interface_mac_addr) {
136   if (!ap_interfaces_.empty() || !client_interfaces_.empty()) {
137     // In the future we may support multiple interfaces at once.  However,
138     // today, we support just one.
139     LOG(ERROR) << "Cannot create AP interface when other interfaces exist";
140     return false;
141   }
142
143   string result;
144   if (!driver_tool_->LoadDriver()) {
145     LOG(ERROR) << "Failed to load WiFi driver!";
146     return false;
147   }
148   if (!driver_tool_->ChangeFirmwareMode(mode)) {
149     LOG(ERROR) << "Failed to change WiFi firmware mode!";
150     return false;
151   }
152
153   if (!RefreshWiphyIndex()) {
154     return false;
155   }
156
157   if (!netlink_utils_->GetInterfaceInfo(wiphy_index_,
158                                         interface_name,
159                                         interface_index,
160                                         interface_mac_addr)) {
161     return false;
162   }
163
164   return true;
165 }
166
167 bool Server::RefreshWiphyIndex() {
168   if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) {
169     LOG(ERROR) << "Failed to get wiphy index";
170     return false;
171   }
172   return true;
173 }
174
175 }  // namespace wificond
176 }  // namespace android