OSDN Git Service

Monitor station events for hotspot mode
[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   // This log keeps compiler happy.
52   LOG(DEBUG) << "Created ap interface " << interface_name_
53              << " with index " << interface_index_;
54
55   netlink_utils_->SubscribeStationEvent(
56       interface_index_,
57       std::bind(&ApInterfaceImpl::OnStationEvent,
58                 this,
59                 _1, _2));
60 }
61
62 ApInterfaceImpl::~ApInterfaceImpl() {
63   binder_->NotifyImplDead();
64   if_tool_->SetUpState(interface_name_.c_str(), false);
65   netlink_utils_->UnsubscribeStationEvent(interface_index_);
66 }
67
68 sp<IApInterface> ApInterfaceImpl::GetBinder() const {
69   return binder_;
70 }
71
72 bool ApInterfaceImpl::StartHostapd() {
73   return hostapd_manager_->StartHostapd();
74 }
75
76 bool ApInterfaceImpl::StopHostapd() {
77   // Drop SIGKILL on hostapd.
78   if (!hostapd_manager_->StopHostapd()) {
79     // Logging was done internally.
80     return false;
81   }
82
83   // Take down the interface.
84   if (!if_tool_->SetUpState(interface_name_.c_str(), false)) {
85     // Logging was done internally.
86     return false;
87   }
88
89   // Since wificond SIGKILLs hostapd, hostapd has no chance to handle
90   // the cleanup.
91   // Besides taking down the interface, we also need to set the interface mode
92   // back to station mode for the cleanup.
93   if (!netlink_utils_->SetInterfaceMode(interface_index_,
94                                         NetlinkUtils::STATION_MODE)) {
95     LOG(ERROR) << "Failed to set interface back to station mode";
96     return false;
97   }
98
99   return true;
100 }
101
102 bool ApInterfaceImpl::WriteHostapdConfig(const vector<uint8_t>& ssid,
103                                          bool is_hidden,
104                                          int32_t channel,
105                                          EncryptionType encryption_type,
106                                          const vector<uint8_t>& passphrase) {
107   string config = hostapd_manager_->CreateHostapdConfig(
108       interface_name_, ssid, is_hidden, channel, encryption_type, passphrase);
109
110   if (config.empty()) {
111     return false;
112   }
113
114   return hostapd_manager_->WriteHostapdConfig(config);
115 }
116
117 void ApInterfaceImpl::OnStationEvent(StationEvent event,
118                                      const vector<uint8_t>& mac_address) {
119   if (event == NEW_STATION) {
120     LOG(INFO) << "New station "
121               << LoggingUtils::GetMacString(mac_address)
122               << " associated with hotspot";
123   } else if (event == DEL_STATION) {
124     LOG(INFO) << "Station "
125               << LoggingUtils::GetMacString(mac_address)
126               << " disassociated from hotspot";
127   }
128 }
129
130 }  // namespace wificond
131 }  // namespace android