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 35using std::string; 36using std::vector; 37using ::testing::_; 38using ::testing::Mock; 39using ::testing::Return; 40using ::testing::SetArgumentPointee; 41using ::testing::StrEq; 42using ::testing::StrictMock; 43 44namespace shill { 45 46class TDLSManagerTest : public testing::Test { 47 public: 48 TDLSManagerTest() 49 : tdls_manager_(&event_dispatcher_, &supplicant_interface_proxy_, "") {} 50 51 void SetPeerDiscovering(const string& peer_mac_address) { 52 tdls_manager_.peer_discovery_state_[peer_mac_address] = 53 TDLSManager::PeerDiscoveryState::kRequestSent; 54 } 55 bool IsPeerDiscovering(const string& peer_mac_address) { 56 return tdls_manager_.CheckDiscoveryState(peer_mac_address) == 57 TDLSManager::PeerDiscoveryState::kRequestSent; 58 } 59 60 void SetPeerDiscovered(const string& peer_mac_address) { 61 tdls_manager_.peer_discovery_state_[peer_mac_address] = 62 TDLSManager::PeerDiscoveryState::kResponseReceived; 63 } 64 bool IsPeerDiscovered(const string& peer_mac_address) { 65 return tdls_manager_.CheckDiscoveryState(peer_mac_address) == 66 TDLSManager::PeerDiscoveryState::kResponseReceived; 67 } 68 69 bool IsPeerDiscoveryCleanupTimerSetup() { 70 return !tdls_manager_.peer_discovery_cleanup_callback_.IsCancelled(); 71 } 72 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 83TEST_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 117TEST_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 141TEST_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 165TEST_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 213TEST_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 230TEST_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