253 lines
8.7 KiB
C++
253 lines
8.7 KiB
C++
//
|
|
// Copyright (C) 2015 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
#include "shill/wifi/tdls_manager.h"
|
|
|
|
#include <map>
|
|
#include <string>
|
|
|
|
#if defined(__ANDROID__)
|
|
#include <dbus/service_constants.h>
|
|
#else
|
|
#include <chromeos/dbus/service_constants.h>
|
|
#endif // __ANDROID__
|
|
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "shill/error.h"
|
|
#include "shill/mock_event_dispatcher.h"
|
|
#include "shill/supplicant/mock_supplicant_interface_proxy.h"
|
|
#include "shill/supplicant/wpa_supplicant.h"
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
using ::testing::_;
|
|
using ::testing::Mock;
|
|
using ::testing::Return;
|
|
using ::testing::SetArgumentPointee;
|
|
using ::testing::StrEq;
|
|
using ::testing::StrictMock;
|
|
|
|
namespace shill {
|
|
|
|
class TDLSManagerTest : public testing::Test {
|
|
public:
|
|
TDLSManagerTest()
|
|
: tdls_manager_(&event_dispatcher_, &supplicant_interface_proxy_, "") {}
|
|
|
|
void SetPeerDiscovering(const string& peer_mac_address) {
|
|
tdls_manager_.peer_discovery_state_[peer_mac_address] =
|
|
TDLSManager::PeerDiscoveryState::kRequestSent;
|
|
}
|
|
bool IsPeerDiscovering(const string& peer_mac_address) {
|
|
return tdls_manager_.CheckDiscoveryState(peer_mac_address) ==
|
|
TDLSManager::PeerDiscoveryState::kRequestSent;
|
|
}
|
|
|
|
void SetPeerDiscovered(const string& peer_mac_address) {
|
|
tdls_manager_.peer_discovery_state_[peer_mac_address] =
|
|
TDLSManager::PeerDiscoveryState::kResponseReceived;
|
|
}
|
|
bool IsPeerDiscovered(const string& peer_mac_address) {
|
|
return tdls_manager_.CheckDiscoveryState(peer_mac_address) ==
|
|
TDLSManager::PeerDiscoveryState::kResponseReceived;
|
|
}
|
|
|
|
bool IsPeerDiscoveryCleanupTimerSetup() {
|
|
return !tdls_manager_.peer_discovery_cleanup_callback_.IsCancelled();
|
|
}
|
|
|
|
void OnPeerDiscoveryCleanup() {
|
|
return tdls_manager_.PeerDiscoveryCleanup();
|
|
}
|
|
|
|
protected:
|
|
StrictMock<MockEventDispatcher> event_dispatcher_;
|
|
StrictMock<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
|
|
TDLSManager tdls_manager_;
|
|
};
|
|
|
|
TEST_F(TDLSManagerTest, DiscoverPeer) {
|
|
const char kPeer[] = "peer";
|
|
Error error;
|
|
|
|
EXPECT_FALSE(IsPeerDiscovering(kPeer));
|
|
EXPECT_FALSE(IsPeerDiscoveryCleanupTimerSetup());
|
|
|
|
// TDLS discover operation succeed.
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSDiscover(StrEq(kPeer)))
|
|
.WillOnce(Return(true));
|
|
// Post delayed task for discover peer cleanup timer.
|
|
EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(1);
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSDiscoverOperation, &error));
|
|
EXPECT_TRUE(error.IsSuccess());
|
|
EXPECT_TRUE(IsPeerDiscovering(kPeer));
|
|
EXPECT_TRUE(IsPeerDiscoveryCleanupTimerSetup());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
Mock::VerifyAndClearExpectations(&event_dispatcher_);
|
|
|
|
// TDLS discover operation failed.
|
|
error.Reset();
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSDiscover(StrEq(kPeer)))
|
|
.WillOnce(Return(false));
|
|
EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(0);
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSDiscoverOperation, &error));
|
|
EXPECT_EQ(Error::kOperationFailed, error.type());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
Mock::VerifyAndClearExpectations(&event_dispatcher_);
|
|
}
|
|
|
|
TEST_F(TDLSManagerTest, SetupPeer) {
|
|
const char kPeer[] = "peer";
|
|
Error error;
|
|
|
|
// TDLS setup operation succeed.
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSSetup(StrEq(kPeer)))
|
|
.WillOnce(Return(true));
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSSetupOperation, &error));
|
|
EXPECT_TRUE(error.IsSuccess());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
|
|
// TDLS setup operation failed.
|
|
error.Reset();
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSSetup(StrEq(kPeer)))
|
|
.WillOnce(Return(false));
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSSetupOperation, &error));
|
|
EXPECT_EQ(Error::kOperationFailed, error.type());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
}
|
|
|
|
TEST_F(TDLSManagerTest, TeardownPeer) {
|
|
const char kPeer[] = "peer";
|
|
Error error;
|
|
|
|
// TDLS teardown operation succeed.
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSTeardown(StrEq(kPeer)))
|
|
.WillOnce(Return(true));
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSTeardownOperation, &error));
|
|
EXPECT_TRUE(error.IsSuccess());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
|
|
// TDLS teardown operation failed.
|
|
error.Reset();
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSTeardown(StrEq(kPeer)))
|
|
.WillOnce(Return(false));
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSTeardownOperation, &error));
|
|
EXPECT_EQ(Error::kOperationFailed, error.type());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
}
|
|
|
|
TEST_F(TDLSManagerTest, PeerStatus) {
|
|
const char kPeer[] = "peer";
|
|
Error error;
|
|
|
|
// TDLS status operation succeed.
|
|
const std::map<string, string> kTDLSStatusMap {
|
|
{ "Baby, I don't care", kTDLSUnknownState },
|
|
{ WPASupplicant::kTDLSStateConnected, kTDLSConnectedState },
|
|
{ WPASupplicant::kTDLSStateDisabled, kTDLSDisabledState },
|
|
{ WPASupplicant::kTDLSStatePeerDoesNotExist, kTDLSNonexistentState },
|
|
{ WPASupplicant::kTDLSStatePeerNotConnected, kTDLSDisconnectedState },
|
|
};
|
|
for (const auto& it : kTDLSStatusMap) {
|
|
error.Reset();
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSStatus(StrEq(kPeer), _))
|
|
.WillOnce(DoAll(SetArgumentPointee<1>(it.first), Return(true)));
|
|
EXPECT_EQ(it.second,
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSStatusOperation, &error));
|
|
EXPECT_TRUE(error.IsSuccess());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
}
|
|
|
|
// Discovered Peer in non-existent state should return "Disconnected" state.
|
|
error.Reset();
|
|
SetPeerDiscovered(kPeer);
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSStatus(StrEq(kPeer), _))
|
|
.WillOnce(
|
|
DoAll(SetArgumentPointee<1>(
|
|
string(WPASupplicant::kTDLSStatePeerDoesNotExist)),
|
|
Return(true)));
|
|
EXPECT_EQ(kTDLSDisconnectedState,
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSStatusOperation, &error));
|
|
EXPECT_TRUE(error.IsSuccess());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
|
|
// TDLS status operation failed.
|
|
error.Reset();
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSStatus(StrEq(kPeer), _))
|
|
.WillOnce(Return(false));
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSStatusOperation, &error));
|
|
EXPECT_EQ(Error::kOperationFailed, error.type());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
}
|
|
|
|
TEST_F(TDLSManagerTest, OnDiscoverResponseReceived) {
|
|
const char kPeer[] = "peer";
|
|
|
|
// Received discover response for a peer without discover request.
|
|
EXPECT_FALSE(IsPeerDiscovering(kPeer));
|
|
EXPECT_FALSE(IsPeerDiscovered(kPeer));
|
|
tdls_manager_.OnDiscoverResponseReceived(kPeer);
|
|
EXPECT_FALSE(IsPeerDiscovering(kPeer));
|
|
EXPECT_FALSE(IsPeerDiscovered(kPeer));
|
|
|
|
// Receive discover response for a peer with discover request.
|
|
SetPeerDiscovering(kPeer);
|
|
EXPECT_TRUE(IsPeerDiscovering(kPeer));
|
|
tdls_manager_.OnDiscoverResponseReceived(kPeer);
|
|
EXPECT_TRUE(IsPeerDiscovered(kPeer));
|
|
}
|
|
|
|
TEST_F(TDLSManagerTest, PeerDiscoveryCleanup) {
|
|
const char kPeer[] = "peer";
|
|
|
|
// Start TDLS discover for a peer |kPeer|.
|
|
Error error;
|
|
EXPECT_CALL(supplicant_interface_proxy_, TDLSDiscover(StrEq(kPeer)))
|
|
.WillOnce(Return(true));
|
|
// Post delayed task for discover peer cleanup timer.
|
|
EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(1);
|
|
EXPECT_EQ("",
|
|
tdls_manager_.PerformOperation(
|
|
kPeer, kTDLSDiscoverOperation, &error));
|
|
EXPECT_TRUE(error.IsSuccess());
|
|
EXPECT_TRUE(IsPeerDiscovering(kPeer));
|
|
EXPECT_TRUE(IsPeerDiscoveryCleanupTimerSetup());
|
|
Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
|
|
Mock::VerifyAndClearExpectations(&event_dispatcher_);
|
|
|
|
// Peer discovery cleanup.
|
|
OnPeerDiscoveryCleanup();
|
|
EXPECT_FALSE(IsPeerDiscovering(kPeer));
|
|
}
|
|
|
|
} // namespace shill
|