1 //
2 // Copyright (C) 2015 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 "shill/wifi/tdls_manager.h"
18
19 #include <map>
20 #include <string>
21
22 #if defined(__ANDROID__)
23 #include <dbus/service_constants.h>
24 #else
25 #include <chromeos/dbus/service_constants.h>
26 #endif // __ANDROID__
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29
30 #include "shill/error.h"
31 #include "shill/mock_event_dispatcher.h"
32 #include "shill/supplicant/mock_supplicant_interface_proxy.h"
33 #include "shill/supplicant/wpa_supplicant.h"
34
35 using std::string;
36 using std::vector;
37 using ::testing::_;
38 using ::testing::Mock;
39 using ::testing::Return;
40 using ::testing::SetArgumentPointee;
41 using ::testing::StrEq;
42 using ::testing::StrictMock;
43
44 namespace shill {
45
46 class TDLSManagerTest : public testing::Test {
47 public:
TDLSManagerTest()48 TDLSManagerTest()
49 : tdls_manager_(&event_dispatcher_, &supplicant_interface_proxy_, "") {}
50
SetPeerDiscovering(const string & peer_mac_address)51 void SetPeerDiscovering(const string& peer_mac_address) {
52 tdls_manager_.peer_discovery_state_[peer_mac_address] =
53 TDLSManager::PeerDiscoveryState::kRequestSent;
54 }
IsPeerDiscovering(const string & peer_mac_address)55 bool IsPeerDiscovering(const string& peer_mac_address) {
56 return tdls_manager_.CheckDiscoveryState(peer_mac_address) ==
57 TDLSManager::PeerDiscoveryState::kRequestSent;
58 }
59
SetPeerDiscovered(const string & peer_mac_address)60 void SetPeerDiscovered(const string& peer_mac_address) {
61 tdls_manager_.peer_discovery_state_[peer_mac_address] =
62 TDLSManager::PeerDiscoveryState::kResponseReceived;
63 }
IsPeerDiscovered(const string & peer_mac_address)64 bool IsPeerDiscovered(const string& peer_mac_address) {
65 return tdls_manager_.CheckDiscoveryState(peer_mac_address) ==
66 TDLSManager::PeerDiscoveryState::kResponseReceived;
67 }
68
IsPeerDiscoveryCleanupTimerSetup()69 bool IsPeerDiscoveryCleanupTimerSetup() {
70 return !tdls_manager_.peer_discovery_cleanup_callback_.IsCancelled();
71 }
72
OnPeerDiscoveryCleanup()73 void OnPeerDiscoveryCleanup() {
74 return tdls_manager_.PeerDiscoveryCleanup();
75 }
76
77 protected:
78 StrictMock<MockEventDispatcher> event_dispatcher_;
79 StrictMock<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
80 TDLSManager tdls_manager_;
81 };
82
TEST_F(TDLSManagerTest,DiscoverPeer)83 TEST_F(TDLSManagerTest, DiscoverPeer) {
84 const char kPeer[] = "peer";
85 Error error;
86
87 EXPECT_FALSE(IsPeerDiscovering(kPeer));
88 EXPECT_FALSE(IsPeerDiscoveryCleanupTimerSetup());
89
90 // TDLS discover operation succeed.
91 EXPECT_CALL(supplicant_interface_proxy_, TDLSDiscover(StrEq(kPeer)))
92 .WillOnce(Return(true));
93 // Post delayed task for discover peer cleanup timer.
94 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(1);
95 EXPECT_EQ("",
96 tdls_manager_.PerformOperation(
97 kPeer, kTDLSDiscoverOperation, &error));
98 EXPECT_TRUE(error.IsSuccess());
99 EXPECT_TRUE(IsPeerDiscovering(kPeer));
100 EXPECT_TRUE(IsPeerDiscoveryCleanupTimerSetup());
101 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
102 Mock::VerifyAndClearExpectations(&event_dispatcher_);
103
104 // TDLS discover operation failed.
105 error.Reset();
106 EXPECT_CALL(supplicant_interface_proxy_, TDLSDiscover(StrEq(kPeer)))
107 .WillOnce(Return(false));
108 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(0);
109 EXPECT_EQ("",
110 tdls_manager_.PerformOperation(
111 kPeer, kTDLSDiscoverOperation, &error));
112 EXPECT_EQ(Error::kOperationFailed, error.type());
113 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
114 Mock::VerifyAndClearExpectations(&event_dispatcher_);
115 }
116
TEST_F(TDLSManagerTest,SetupPeer)117 TEST_F(TDLSManagerTest, SetupPeer) {
118 const char kPeer[] = "peer";
119 Error error;
120
121 // TDLS setup operation succeed.
122 EXPECT_CALL(supplicant_interface_proxy_, TDLSSetup(StrEq(kPeer)))
123 .WillOnce(Return(true));
124 EXPECT_EQ("",
125 tdls_manager_.PerformOperation(
126 kPeer, kTDLSSetupOperation, &error));
127 EXPECT_TRUE(error.IsSuccess());
128 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
129
130 // TDLS setup operation failed.
131 error.Reset();
132 EXPECT_CALL(supplicant_interface_proxy_, TDLSSetup(StrEq(kPeer)))
133 .WillOnce(Return(false));
134 EXPECT_EQ("",
135 tdls_manager_.PerformOperation(
136 kPeer, kTDLSSetupOperation, &error));
137 EXPECT_EQ(Error::kOperationFailed, error.type());
138 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
139 }
140
TEST_F(TDLSManagerTest,TeardownPeer)141 TEST_F(TDLSManagerTest, TeardownPeer) {
142 const char kPeer[] = "peer";
143 Error error;
144
145 // TDLS teardown operation succeed.
146 EXPECT_CALL(supplicant_interface_proxy_, TDLSTeardown(StrEq(kPeer)))
147 .WillOnce(Return(true));
148 EXPECT_EQ("",
149 tdls_manager_.PerformOperation(
150 kPeer, kTDLSTeardownOperation, &error));
151 EXPECT_TRUE(error.IsSuccess());
152 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
153
154 // TDLS teardown operation failed.
155 error.Reset();
156 EXPECT_CALL(supplicant_interface_proxy_, TDLSTeardown(StrEq(kPeer)))
157 .WillOnce(Return(false));
158 EXPECT_EQ("",
159 tdls_manager_.PerformOperation(
160 kPeer, kTDLSTeardownOperation, &error));
161 EXPECT_EQ(Error::kOperationFailed, error.type());
162 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
163 }
164
TEST_F(TDLSManagerTest,PeerStatus)165 TEST_F(TDLSManagerTest, PeerStatus) {
166 const char kPeer[] = "peer";
167 Error error;
168
169 // TDLS status operation succeed.
170 const std::map<string, string> kTDLSStatusMap {
171 { "Baby, I don't care", kTDLSUnknownState },
172 { WPASupplicant::kTDLSStateConnected, kTDLSConnectedState },
173 { WPASupplicant::kTDLSStateDisabled, kTDLSDisabledState },
174 { WPASupplicant::kTDLSStatePeerDoesNotExist, kTDLSNonexistentState },
175 { WPASupplicant::kTDLSStatePeerNotConnected, kTDLSDisconnectedState },
176 };
177 for (const auto& it : kTDLSStatusMap) {
178 error.Reset();
179 EXPECT_CALL(supplicant_interface_proxy_, TDLSStatus(StrEq(kPeer), _))
180 .WillOnce(DoAll(SetArgumentPointee<1>(it.first), Return(true)));
181 EXPECT_EQ(it.second,
182 tdls_manager_.PerformOperation(
183 kPeer, kTDLSStatusOperation, &error));
184 EXPECT_TRUE(error.IsSuccess());
185 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
186 }
187
188 // Discovered Peer in non-existent state should return "Disconnected" state.
189 error.Reset();
190 SetPeerDiscovered(kPeer);
191 EXPECT_CALL(supplicant_interface_proxy_, TDLSStatus(StrEq(kPeer), _))
192 .WillOnce(
193 DoAll(SetArgumentPointee<1>(
194 string(WPASupplicant::kTDLSStatePeerDoesNotExist)),
195 Return(true)));
196 EXPECT_EQ(kTDLSDisconnectedState,
197 tdls_manager_.PerformOperation(
198 kPeer, kTDLSStatusOperation, &error));
199 EXPECT_TRUE(error.IsSuccess());
200 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
201
202 // TDLS status operation failed.
203 error.Reset();
204 EXPECT_CALL(supplicant_interface_proxy_, TDLSStatus(StrEq(kPeer), _))
205 .WillOnce(Return(false));
206 EXPECT_EQ("",
207 tdls_manager_.PerformOperation(
208 kPeer, kTDLSStatusOperation, &error));
209 EXPECT_EQ(Error::kOperationFailed, error.type());
210 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
211 }
212
TEST_F(TDLSManagerTest,OnDiscoverResponseReceived)213 TEST_F(TDLSManagerTest, OnDiscoverResponseReceived) {
214 const char kPeer[] = "peer";
215
216 // Received discover response for a peer without discover request.
217 EXPECT_FALSE(IsPeerDiscovering(kPeer));
218 EXPECT_FALSE(IsPeerDiscovered(kPeer));
219 tdls_manager_.OnDiscoverResponseReceived(kPeer);
220 EXPECT_FALSE(IsPeerDiscovering(kPeer));
221 EXPECT_FALSE(IsPeerDiscovered(kPeer));
222
223 // Receive discover response for a peer with discover request.
224 SetPeerDiscovering(kPeer);
225 EXPECT_TRUE(IsPeerDiscovering(kPeer));
226 tdls_manager_.OnDiscoverResponseReceived(kPeer);
227 EXPECT_TRUE(IsPeerDiscovered(kPeer));
228 }
229
TEST_F(TDLSManagerTest,PeerDiscoveryCleanup)230 TEST_F(TDLSManagerTest, PeerDiscoveryCleanup) {
231 const char kPeer[] = "peer";
232
233 // Start TDLS discover for a peer |kPeer|.
234 Error error;
235 EXPECT_CALL(supplicant_interface_proxy_, TDLSDiscover(StrEq(kPeer)))
236 .WillOnce(Return(true));
237 // Post delayed task for discover peer cleanup timer.
238 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(1);
239 EXPECT_EQ("",
240 tdls_manager_.PerformOperation(
241 kPeer, kTDLSDiscoverOperation, &error));
242 EXPECT_TRUE(error.IsSuccess());
243 EXPECT_TRUE(IsPeerDiscovering(kPeer));
244 EXPECT_TRUE(IsPeerDiscoveryCleanupTimerSetup());
245 Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
246 Mock::VerifyAndClearExpectations(&event_dispatcher_);
247
248 // Peer discovery cleanup.
249 OnPeerDiscoveryCleanup();
250 EXPECT_FALSE(IsPeerDiscovering(kPeer));
251 }
252
253 } // namespace shill
254