OSDN Git Service

Add wificond API to expose number of associated stations
[android-x86/system-connectivity-wificond.git] / ap_interface_impl.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/ap_interface_impl.h"
18
19 #include <android-base/logging.h>
20
21 #include "wificond/net/netlink_utils.h"
22
23 #include "wificond/ap_interface_binder.h"
24 #include "wificond/logging_utils.h"
25
26 using android::net::wifi::IApInterface;
27 using android::wifi_system::HostapdManager;
28 using android::wifi_system::InterfaceTool;
29 using std::string;
30 using std::unique_ptr;
31 using std::vector;
32
33 using EncryptionType = android::wifi_system::HostapdManager::EncryptionType;
34
35 using namespace std::placeholders;
36
37 namespace android {
38 namespace wificond {
39
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),
48       if_tool_(if_tool),
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_;
55
56   netlink_utils_->SubscribeStationEvent(
57       interface_index_,
58       std::bind(&ApInterfaceImpl::OnStationEvent,
59                 this,
60                 _1, _2));
61 }
62
63 ApInterfaceImpl::~ApInterfaceImpl() {
64   binder_->NotifyImplDead();
65   if_tool_->SetUpState(interface_name_.c_str(), false);
66   netlink_utils_->UnsubscribeStationEvent(interface_index_);
67 }
68
69 sp<IApInterface> ApInterfaceImpl::GetBinder() const {
70   return binder_;
71 }
72
73 bool ApInterfaceImpl::StartHostapd() {
74   return hostapd_manager_->StartHostapd();
75 }
76
77 bool ApInterfaceImpl::StopHostapd() {
78   // Drop SIGKILL on hostapd.
79   if (!hostapd_manager_->StopHostapd()) {
80     // Logging was done internally.
81     return false;
82   }
83
84   // Take down the interface.
85   if (!if_tool_->SetUpState(interface_name_.c_str(), false)) {
86     // Logging was done internally.
87     return false;
88   }
89
90   // Since wificond SIGKILLs hostapd, hostapd has no chance to handle
91   // the cleanup.
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";
97     return false;
98   }
99
100   return true;
101 }
102
103 bool ApInterfaceImpl::WriteHostapdConfig(const vector<uint8_t>& ssid,
104                                          bool is_hidden,
105                                          int32_t channel,
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);
110
111   if (config.empty()) {
112     return false;
113   }
114
115   return hostapd_manager_->WriteHostapdConfig(config);
116 }
117
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_;
132     } else {
133       number_of_associated_stations_--;
134     }
135   }
136 }
137
138 int ApInterfaceImpl::GetNumberOfAssociatedStations() const {
139   return number_of_associated_stations_;
140 }
141
142 }  // namespace wificond
143 }  // namespace android