blob: 00f4a41e533f2fc39b3a226cdea8605cb44b92d0 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/connectivity/bluetooth/core/bt-host/fidl/low_energy_central_server.h"
#include <cstddef>
#include <gmock/gmock.h>
#include "adapter_test_fixture.h"
#include "fuchsia/bluetooth/gatt/cpp/fidl.h"
#include "fuchsia/bluetooth/le/cpp/fidl.h"
#include "lib/fidl/cpp/interface_request.h"
#include "src/connectivity/bluetooth/core/bt-host/common/status.h"
#include "src/connectivity/bluetooth/core/bt-host/fidl/helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/types.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_peer.h"
namespace bthost {
namespace {
namespace fble = fuchsia::bluetooth::le;
const bt::DeviceAddress kTestAddr(bt::DeviceAddress::Type::kLEPublic, {0x01, 0, 0, 0, 0, 0});
const size_t kLEMaxNumPackets = 10;
const bt::hci::DataBufferInfo kLEDataBufferInfo(bt::hci::kMaxACLPayloadSize, kLEMaxNumPackets);
using TestingBase = bthost::testing::AdapterTestFixture;
class FIDL_LowEnergyCentralServerTest : public TestingBase {
public:
FIDL_LowEnergyCentralServerTest() = default;
~FIDL_LowEnergyCentralServerTest() override = default;
void SetUp() override {
AdapterTestFixture::SetUp();
// Create a LowEnergyCentralServer and bind it to a local client.
fidl::InterfaceHandle<fble::Central> handle;
gatt_host_ = GattHost::CreateForTesting(dispatcher(), gatt());
server_ = std::make_unique<LowEnergyCentralServer>(adapter(), handle.NewRequest(), gatt_host_);
proxy_.Bind(std::move(handle));
bt::testing::FakeController::Settings settings;
settings.ApplyLegacyLEConfig();
test_device()->set_settings(settings);
}
void TearDown() override {
RunLoopUntilIdle();
proxy_ = nullptr;
server_ = nullptr;
gatt_host_->ShutDown();
gatt_host_ = nullptr;
RunLoopUntilIdle();
AdapterTestFixture::TearDown();
}
protected:
LowEnergyCentralServer* server() const { return server_.get(); }
fuchsia::bluetooth::le::Central* central_proxy() const { return proxy_.get(); }
private:
std::unique_ptr<LowEnergyCentralServer> server_;
fble::CentralPtr proxy_;
fbl::RefPtr<GattHost> gatt_host_;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FIDL_LowEnergyCentralServerTest);
};
// Tests that connecting to a peripheral with ConnectionOptions.bondable_mode unset results in a
// bondable connection ref being stored in LowEnergyConnectionManager
TEST_F(FIDL_LowEnergyCentralServerTest, ConnectDefaultResultsBondableConnectionRef) {
auto* const peer = adapter()->peer_cache()->NewPeer(kTestAddr, /*connectable=*/true);
ASSERT_TRUE(peer);
test_device()->AddPeer(std::make_unique<bt::testing::FakePeer>(kTestAddr));
fble::ConnectionOptions options;
fidl::InterfaceHandle<fuchsia::bluetooth::gatt::Client> gatt_client;
fidl::InterfaceRequest<fuchsia::bluetooth::gatt::Client> gatt_client_req =
gatt_client.NewRequest();
auto status =
fidl_helpers::NewFidlError(fuchsia::bluetooth::ErrorCode::BAD_STATE, "this should change");
auto callback = [&status](::fuchsia::bluetooth::Status cb_status) {
ASSERT_EQ(cb_status.error, nullptr);
status = std::move(cb_status);
};
central_proxy()->ConnectPeripheral(peer->identifier().ToString(), std::move(options),
std::move(gatt_client_req), callback);
ASSERT_FALSE(server()->FindConnectionForTesting(peer->identifier()));
RunLoopUntilIdle();
auto conn_ref_ptr = server()->FindConnectionForTesting(peer->identifier());
ASSERT_EQ(status.error, nullptr);
ASSERT_TRUE(conn_ref_ptr);
ASSERT_EQ(conn_ref_ptr->bondable_mode(), bt::sm::BondableMode::Bondable);
}
// Tests that setting ConnectionOptions.bondable_mode to true and connecting to a peer in bondable
// mode results in a bondable connection ref being stored in LowEnergyConnectionManager
TEST_F(FIDL_LowEnergyCentralServerTest, ConnectBondableResultsBondableConnectionRef) {
auto* const peer = adapter()->peer_cache()->NewPeer(kTestAddr, /*connectable=*/true);
ASSERT_TRUE(peer);
test_device()->AddPeer(std::make_unique<bt::testing::FakePeer>(kTestAddr));
fble::ConnectionOptions options;
options.set_bondable_mode(true);
fidl::InterfaceHandle<fuchsia::bluetooth::gatt::Client> gatt_client;
fidl::InterfaceRequest<fuchsia::bluetooth::gatt::Client> gatt_client_req =
gatt_client.NewRequest();
auto status =
fidl_helpers::NewFidlError(fuchsia::bluetooth::ErrorCode::BAD_STATE, "this should change");
auto callback = [&status](::fuchsia::bluetooth::Status cb_status) {
ASSERT_EQ(cb_status.error, nullptr);
status = std::move(cb_status);
};
central_proxy()->ConnectPeripheral(peer->identifier().ToString(), std::move(options),
std::move(gatt_client_req), callback);
ASSERT_FALSE(server()->FindConnectionForTesting(peer->identifier()));
RunLoopUntilIdle();
auto conn_ref_ptr = server()->FindConnectionForTesting(peer->identifier());
ASSERT_EQ(status.error, nullptr);
ASSERT_TRUE(conn_ref_ptr);
ASSERT_EQ(conn_ref_ptr->bondable_mode(), bt::sm::BondableMode::Bondable);
}
// Tests that setting ConnectionOptions.bondable_mode to false and connecting to a peer results in
// a non-bondable connection ref being stored in LowEnergyConnectionManager.
TEST_F(FIDL_LowEnergyCentralServerTest, ConnectNonBondableResultsNonBondableConnectionRef) {
auto* const peer = adapter()->peer_cache()->NewPeer(kTestAddr, /*connectable=*/true);
ASSERT_TRUE(peer);
test_device()->AddPeer(std::make_unique<bt::testing::FakePeer>(kTestAddr));
fble::ConnectionOptions options;
options.set_bondable_mode(false);
fidl::InterfaceHandle<fuchsia::bluetooth::gatt::Client> gatt_client;
fidl::InterfaceRequest<fuchsia::bluetooth::gatt::Client> gatt_client_req =
gatt_client.NewRequest();
auto status =
fidl_helpers::NewFidlError(fuchsia::bluetooth::ErrorCode::BAD_STATE, "this should change");
auto callback = [&status](::fuchsia::bluetooth::Status cb_status) {
ASSERT_EQ(cb_status.error, nullptr);
status = std::move(cb_status);
};
central_proxy()->ConnectPeripheral(peer->identifier().ToString(), std::move(options),
std::move(gatt_client_req), callback);
ASSERT_FALSE(server()->FindConnectionForTesting(peer->identifier()));
RunLoopUntilIdle();
auto conn_ref_ptr = server()->FindConnectionForTesting(peer->identifier());
ASSERT_EQ(status.error, nullptr);
ASSERT_TRUE(conn_ref_ptr);
ASSERT_EQ(conn_ref_ptr->bondable_mode(), bt::sm::BondableMode::NonBondable);
}
} // namespace
} // namespace bthost