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: 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 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 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 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 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 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 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