blob: e64214e675628d898ea766822e0ca1c778fb2e4b [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 "transport.h"
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/protocol.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"
namespace bt::hci {
namespace {
using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
class HCI_TransportTest : public TestingBase {
public:
HCI_TransportTest() = default;
~HCI_TransportTest() override = default;
};
TEST_F(HCI_TransportTest, CommandChannelTimeoutShutsDownChannelAndNotifiesClosedCallback) {
size_t closed_cb_count = 0;
transport()->SetTransportClosedCallback([&] { closed_cb_count++; });
constexpr zx::duration kCommandTimeout = zx::sec(12);
auto req_reset = StaticByteBuffer(LowerBits(kReset), UpperBits(kReset), // HCI_Reset opcode
0x00 // parameter_total_size
);
// Expect the HCI_Reset command but dont send a reply back to make the command
// time out.
EXPECT_CMD_PACKET_OUT(test_device(), req_reset);
StartTestDevice();
size_t cb_count = 0;
CommandChannel::TransactionId id1, id2;
auto cb = [&cb_count, &id1, &id2](CommandChannel::TransactionId callback_id,
const EventPacket& event) {
cb_count++;
EXPECT_TRUE(callback_id == id1 || callback_id == id2);
EXPECT_EQ(kCommandStatusEventCode, event.event_code());
const auto params = event.params<CommandStatusEventParams>();
EXPECT_EQ(StatusCode::kUnspecifiedError, params.status);
EXPECT_EQ(kReset, params.command_opcode);
};
auto packet = CommandPacket::New(kReset);
id1 = cmd_channel()->SendCommand(std::move(packet), cb);
ASSERT_NE(0u, id1);
packet = CommandPacket::New(kReset);
id2 = cmd_channel()->SendCommand(std::move(packet), cb);
ASSERT_NE(0u, id2);
// Run the loop until the command timeout task gets scheduled.
RunLoopUntilIdle();
ASSERT_EQ(0u, cb_count);
EXPECT_EQ(0u, closed_cb_count);
RunLoopFor(kCommandTimeout);
EXPECT_EQ(2u, cb_count);
EXPECT_EQ(1u, closed_cb_count);
}
} // namespace
} // namespace bt::hci