2 * Copyright (C) 2016 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "wificond/server.h"
19 #include <android-base/logging.h>
21 #include "wificond/net/netlink_utils.h"
22 #include "wificond/scanning/scan_utils.h"
24 using android::binder::Status;
26 using android::IBinder;
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;
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) {
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,
64 &interface_mac_addr)) {
65 return Status::ok(); // Logging was done internally
68 unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
72 hostapd_manager_.get()));
73 *created_interface = ap_interface->GetBinder();
74 ap_interfaces_.push_back(std::move(ap_interface));
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,
85 &interface_mac_addr)) {
86 return Status::ok(); // Logging was done internally
89 unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
93 supplicant_manager_.get(),
95 *created_interface = client_interface->GetBinder();
96 client_interfaces_.push_back(std::move(client_interface));
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!";
109 void Server::CleanUpSystemState() {
110 supplicant_manager_->StopSupplicant();
111 hostapd_manager_->StopHostapd();
113 uint32_t phy_index = 0;
114 uint32_t if_index = 0;
117 if (netlink_utils_->GetWiphyIndex(&phy_index) &&
118 netlink_utils_->GetInterfaceInfo(phy_index,
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
125 if_tool_->SetUpState(if_name.c_str(), false);
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();
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";
144 if (!driver_tool_->LoadDriver()) {
145 LOG(ERROR) << "Failed to load WiFi driver!";
148 if (!driver_tool_->ChangeFirmwareMode(mode)) {
149 LOG(ERROR) << "Failed to change WiFi firmware mode!";
153 if (!RefreshWiphyIndex()) {
157 if (!netlink_utils_->GetInterfaceInfo(wiphy_index_,
160 interface_mac_addr)) {
167 bool Server::RefreshWiphyIndex() {
168 if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) {
169 LOG(ERROR) << "Failed to get wiphy index";
175 } // namespace wificond
176 } // namespace android