blob: d82a01a035836ade893bab21c97540b5940becc1 [file] [log] [blame]
// Copyright 2017 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 "garnet/drivers/bluetooth/lib/hci/connection.h"
#include "gtest/gtest.h"
#include "garnet/drivers/bluetooth/lib/hci/hci.h"
#include "garnet/drivers/bluetooth/lib/testing/fake_controller_test.h"
#include "garnet/drivers/bluetooth/lib/testing/test_controller.h"
namespace bluetooth {
namespace hci {
namespace {
constexpr ConnectionHandle kTestHandle = 0x0001;
constexpr Connection::Role kTestRole = Connection::Role::kMaster;
const LEConnectionParameters kTestParams(1, 1, 1);
const common::DeviceAddress kTestAddress(common::DeviceAddress::Type::kLEPublic,
"00:00:00:00:00:01");
using ::bluetooth::testing::CommandTransaction;
using TestingBase = ::bluetooth::testing::FakeControllerTest<
::bluetooth::testing::TestController>;
class ConnectionTest : public TestingBase {
public:
ConnectionTest() = default;
~ConnectionTest() override = default;
};
using HCI_ConnectionTest = ConnectionTest;
TEST_F(HCI_ConnectionTest, TestGetters) {
Connection connection(kTestHandle, kTestRole, kTestAddress, kTestParams,
transport());
EXPECT_EQ(Connection::LinkType::kLE, connection.ll_type());
EXPECT_EQ(kTestHandle, connection.handle());
EXPECT_EQ(kTestRole, connection.role());
EXPECT_EQ(kTestParams, connection.low_energy_parameters());
EXPECT_EQ(kTestAddress, connection.peer_address());
EXPECT_TRUE(connection.is_open());
}
TEST_F(HCI_ConnectionTest, Close) {
// clang-format off
// HCI_Disconnect (handle: 0x0001, reason: RemoteUserTerminatedConnection)
auto req_bytes = common::CreateStaticByteBuffer(
0x06, 0x04, 0x03, 0x01, 0x00, Status::kRemoteUserTerminatedConnection);
// Respond with Command Status and Disconnection Complete.
auto cmd_status_bytes = common::CreateStaticByteBuffer(
kCommandStatusEventCode, 0x04, Status::kSuccess, 1, 0x06, 0x04);
auto disc_cmpl_bytes = common::CreateStaticByteBuffer(
kDisconnectionCompleteEventCode, 0x04,
Status::kSuccess, 0x01, 0x00, Status::kConnectionTerminatedByLocalHost);
// clang-format on
test_device()->QueueCommandTransaction(
CommandTransaction({req_bytes, {&cmd_status_bytes, &disc_cmpl_bytes}}));
test_device()->Start();
bool callback_called = false;
test_device()->SetTransactionCallback(
[&callback_called, this] {
callback_called = true;
message_loop()->QuitNow();
},
message_loop()->task_runner());
Connection connection(kTestHandle, kTestRole, kTestAddress, kTestParams,
transport());
EXPECT_TRUE(connection.is_open());
connection.Close(Status::kRemoteUserTerminatedConnection);
EXPECT_FALSE(connection.is_open());
RunMessageLoop();
EXPECT_TRUE(callback_called);
}
TEST_F(HCI_ConnectionTest, CloseError) {
// clang-format off
// HCI_Disconnect (handle: 0x0001, reason: RemoteUserTerminatedConnection)
auto req_bytes = common::CreateStaticByteBuffer(
0x06, 0x04, 0x03, 0x01, 0x00, Status::kRemoteUserTerminatedConnection);
// Respond with Command Status and Disconnection Complete.
auto cmd_status_bytes = common::CreateStaticByteBuffer(
kCommandStatusEventCode, 0x04, Status::kSuccess, 1, 0x06, 0x04);
auto disc_cmpl_bytes = common::CreateStaticByteBuffer(
kDisconnectionCompleteEventCode, 0x04,
Status::kCommandDisallowed, 0x01, 0x00, Status::kConnectionTerminatedByLocalHost);
// clang-format on
test_device()->QueueCommandTransaction(
CommandTransaction({req_bytes, {&cmd_status_bytes, &disc_cmpl_bytes}}));
test_device()->Start();
// The callback should get called regardless of the procedure status.
bool callback_called = false;
test_device()->SetTransactionCallback(
[&callback_called, this] {
callback_called = true;
message_loop()->QuitNow();
},
message_loop()->task_runner());
Connection connection(kTestHandle, kTestRole, kTestAddress, kTestParams,
transport());
EXPECT_TRUE(connection.is_open());
connection.Close(Status::kRemoteUserTerminatedConnection);
EXPECT_FALSE(connection.is_open());
RunMessageLoop();
EXPECT_TRUE(callback_called);
}
} // namespace
} // namespace hci
} // namespace bluetooth