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/ap_interface_impl.h"
19 #include <android-base/logging.h>
21 #include "wificond/net/netlink_utils.h"
23 #include "wificond/ap_interface_binder.h"
24 #include "wificond/logging_utils.h"
26 using android::net::wifi::IApInterface;
27 using android::wifi_system::HostapdManager;
28 using android::wifi_system::InterfaceTool;
30 using std::unique_ptr;
33 using EncryptionType = android::wifi_system::HostapdManager::EncryptionType;
35 using namespace std::placeholders;
40 ApInterfaceImpl::ApInterfaceImpl(const string& interface_name,
41 uint32_t interface_index,
42 NetlinkUtils* netlink_utils,
43 InterfaceTool* if_tool,
44 HostapdManager* hostapd_manager)
45 : interface_name_(interface_name),
46 interface_index_(interface_index),
47 netlink_utils_(netlink_utils),
49 hostapd_manager_(hostapd_manager),
50 binder_(new ApInterfaceBinder(this)),
51 number_of_associated_stations_(0) {
52 // This log keeps compiler happy.
53 LOG(DEBUG) << "Created ap interface " << interface_name_
54 << " with index " << interface_index_;
56 netlink_utils_->SubscribeStationEvent(
58 std::bind(&ApInterfaceImpl::OnStationEvent,
63 ApInterfaceImpl::~ApInterfaceImpl() {
64 binder_->NotifyImplDead();
65 if_tool_->SetUpState(interface_name_.c_str(), false);
66 netlink_utils_->UnsubscribeStationEvent(interface_index_);
69 sp<IApInterface> ApInterfaceImpl::GetBinder() const {
73 bool ApInterfaceImpl::StartHostapd() {
74 return hostapd_manager_->StartHostapd();
77 bool ApInterfaceImpl::StopHostapd() {
78 // Drop SIGKILL on hostapd.
79 if (!hostapd_manager_->StopHostapd()) {
80 // Logging was done internally.
84 // Take down the interface.
85 if (!if_tool_->SetUpState(interface_name_.c_str(), false)) {
86 // Logging was done internally.
90 // Since wificond SIGKILLs hostapd, hostapd has no chance to handle
92 // Besides taking down the interface, we also need to set the interface mode
93 // back to station mode for the cleanup.
94 if (!netlink_utils_->SetInterfaceMode(interface_index_,
95 NetlinkUtils::STATION_MODE)) {
96 LOG(ERROR) << "Failed to set interface back to station mode";
103 bool ApInterfaceImpl::WriteHostapdConfig(const vector<uint8_t>& ssid,
106 EncryptionType encryption_type,
107 const vector<uint8_t>& passphrase) {
108 string config = hostapd_manager_->CreateHostapdConfig(
109 interface_name_, ssid, is_hidden, channel, encryption_type, passphrase);
111 if (config.empty()) {
115 return hostapd_manager_->WriteHostapdConfig(config);
118 void ApInterfaceImpl::OnStationEvent(StationEvent event,
119 const vector<uint8_t>& mac_address) {
120 if (event == NEW_STATION) {
121 LOG(INFO) << "New station "
122 << LoggingUtils::GetMacString(mac_address)
123 << " associated with hotspot";
124 number_of_associated_stations_++;
125 } else if (event == DEL_STATION) {
126 LOG(INFO) << "Station "
127 << LoggingUtils::GetMacString(mac_address)
128 << " disassociated from hotspot";
129 if (number_of_associated_stations_ <= 0) {
130 LOG(ERROR) << "Received DEL_STATION event when station counter is: "
131 << number_of_associated_stations_;
133 number_of_associated_stations_--;
138 int ApInterfaceImpl::GetNumberOfAssociatedStations() const {
139 return number_of_associated_stations_;
142 } // namespace wificond
143 } // namespace android