// 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/acl_data_channel.h"

#include <unordered_map>

#include <lib/async/cpp/task.h>
#include <zircon/assert.h>

#include "garnet/drivers/bluetooth/lib/hci/connection.h"
#include "garnet/drivers/bluetooth/lib/hci/defaults.h"
#include "garnet/drivers/bluetooth/lib/hci/transport.h"
#include "garnet/drivers/bluetooth/lib/testing/fake_controller_test.h"
#include "garnet/drivers/bluetooth/lib/testing/test_controller.h"

namespace btlib {
namespace hci {
namespace {

using TestingBase =
    ::btlib::testing::FakeControllerTest<::btlib::testing::TestController>;

class ACLDataChannelTest : public TestingBase {
 public:
  ACLDataChannelTest() = default;
  ~ACLDataChannelTest() override = default;

 protected:
  // TestBase overrides:
  void SetUp() override {
    TestingBase::SetUp();
    StartTestDevice();
  }

 private:
  FXL_DISALLOW_COPY_AND_ASSIGN(ACLDataChannelTest);
};

using HCI_ACLDataChannelTest = ACLDataChannelTest;

TEST_F(HCI_ACLDataChannelTest, VerifyMTUs) {
  const DataBufferInfo kBREDRBufferInfo(1024, 50);
  const DataBufferInfo kLEBufferInfo(64, 16);

  // BR/EDR buffer only.
  InitializeACLDataChannel(kBREDRBufferInfo, DataBufferInfo());
  EXPECT_EQ(kBREDRBufferInfo, acl_data_channel()->GetBufferInfo());
  EXPECT_EQ(kBREDRBufferInfo, acl_data_channel()->GetLEBufferInfo());

  TearDown();
  SetUp();

  // LE buffer only.
  InitializeACLDataChannel(DataBufferInfo(), kLEBufferInfo);
  EXPECT_EQ(DataBufferInfo(), acl_data_channel()->GetBufferInfo());
  EXPECT_EQ(kLEBufferInfo, acl_data_channel()->GetLEBufferInfo());

  TearDown();
  SetUp();

  // Both buffers available.
  InitializeACLDataChannel(kBREDRBufferInfo, kLEBufferInfo);
  EXPECT_EQ(kBREDRBufferInfo, acl_data_channel()->GetBufferInfo());
  EXPECT_EQ(kLEBufferInfo, acl_data_channel()->GetLEBufferInfo());
}

// Test that SendPacket works using only the BR/EDR buffer.
TEST_F(HCI_ACLDataChannelTest, SendPacketBREDRBuffer) {
  constexpr size_t kMaxMTU = 5;
  constexpr size_t kMaxNumPackets = 5;
  constexpr ConnectionHandle kHandle0 = 0x0001;
  constexpr ConnectionHandle kHandle1 = 0x0002;

  InitializeACLDataChannel(DataBufferInfo(kMaxMTU, kMaxNumPackets),
                           DataBufferInfo());

  int handle0_packet_count = 0;
  int handle1_packet_count = 0;

  // Callback invoked by TestDevice when it receive a data packet from us.
  auto data_callback = [&](const common::ByteBuffer& bytes) {
    ZX_DEBUG_ASSERT(bytes.size() >= sizeof(ACLDataHeader));

    common::PacketView<hci::ACLDataHeader> packet(
        &bytes, bytes.size() - sizeof(ACLDataHeader));
    ConnectionHandle connection_handle =
        le16toh(packet.header().handle_and_flags) & 0xFFF;

    if (connection_handle == kHandle0) {
      handle0_packet_count++;
    } else {
      ASSERT_EQ(kHandle1, connection_handle);
      handle1_packet_count++;
    }
  };
  test_device()->SetDataCallback(data_callback, dispatcher());

  // Queue up 10 packets in total, distributed among the two connection handles.
  async::PostTask(dispatcher(), [this, kHandle0, kHandle1] {
    for (int i = 0; i < 10; ++i) {
      ConnectionHandle handle = (i % 2) ? kHandle1 : kHandle0;
      Connection::LinkType ll_type =
          (i % 2) ? Connection::LinkType::kACL : Connection::LinkType::kLE;
      auto packet =
          ACLDataPacket::New(handle, ACLPacketBoundaryFlag::kFirstNonFlushable,
                             ACLBroadcastFlag::kPointToPoint, kMaxMTU);
      EXPECT_TRUE(acl_data_channel()->SendPacket(std::move(packet), ll_type));
    }
  });

  RunLoopUntilIdle();

  // kMaxNumPackets is 5. The controller should have received 3 packets on
  // kHandle0 and 2 on kHandle1
  EXPECT_EQ(3, handle0_packet_count);
  EXPECT_EQ(2, handle1_packet_count);

  // Notify the processed packets with a Number Of Completed Packet HCI event.
  auto event_buffer = common::CreateStaticByteBuffer(
      0x13, 0x09,              // Event header
      0x02,                    // Number of handles
      0x01, 0x00, 0x03, 0x00,  // 3 packets on handle 0x0001
      0x02, 0x00, 0x02, 0x00   // 2 packets on handle 0x0002
  );
  test_device()->SendCommandChannelPacket(event_buffer);

  RunLoopUntilIdle();

  EXPECT_EQ(5, handle0_packet_count);
  EXPECT_EQ(5, handle1_packet_count);
}

// Test that SendPacket works using the LE buffer when no BR/EDR buffer is
// available.
TEST_F(HCI_ACLDataChannelTest, SendPacketLEBuffer) {
  constexpr size_t kMaxMTU = 5;
  constexpr size_t kTotalAttempts = 12;
  constexpr size_t kTotalExpected = 6;
  constexpr size_t kBufferNumPackets = 3;
  constexpr ConnectionHandle kHandle0 = 0x0001;
  constexpr ConnectionHandle kHandle1 = 0x0002;

  InitializeACLDataChannel(DataBufferInfo(),
                           DataBufferInfo(kMaxMTU, kBufferNumPackets));

  // This should fail because the payload exceeds the MTU.
  auto packet =
      ACLDataPacket::New(kHandle1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, kMaxMTU + 1);
  EXPECT_FALSE(acl_data_channel()->SendPacket(std::move(packet),
                                              Connection::LinkType::kACL));

  size_t handle0_packet_count = 0;
  size_t handle1_packet_count = 0;
  auto data_callback = [&](const common::ByteBuffer& bytes) {
    ZX_DEBUG_ASSERT(bytes.size() >= sizeof(ACLDataHeader));

    common::PacketView<hci::ACLDataHeader> packet(
        &bytes, bytes.size() - sizeof(ACLDataHeader));
    ConnectionHandle connection_handle =
        le16toh(packet.header().handle_and_flags) & 0xFFF;

    if (connection_handle == kHandle0) {
      handle0_packet_count++;
    } else {
      ASSERT_EQ(kHandle1, connection_handle);
      handle1_packet_count++;
    }
  };
  test_device()->SetDataCallback(data_callback, dispatcher());

  // Queue up 12 packets in total, distributed among the two connection handles
  // and link types. Since the BR/EDR MTU is zero, we expect to only see LE
  // packets transmitted.
  async::PostTask(dispatcher(), [this, kHandle0, kHandle1] {
    for (size_t i = 0; i < kTotalAttempts; ++i) {
      ConnectionHandle handle = (i % 2) ? kHandle1 : kHandle0;
      auto packet =
          ACLDataPacket::New(handle, ACLPacketBoundaryFlag::kFirstNonFlushable,
                             ACLBroadcastFlag::kPointToPoint, kMaxMTU);
      if (i % 2) {
        // ACL-U packets should fail due to 0 MTU size.
        EXPECT_FALSE(acl_data_channel()->SendPacket(
            std::move(packet), Connection::LinkType::kACL));
      } else {
        EXPECT_TRUE(acl_data_channel()->SendPacket(std::move(packet),
                                                   Connection::LinkType::kLE));
      }
    }
  });

  RunLoopUntilIdle();

  // The controller can buffer 3 packets. Since BR/EDR packets should have
  // failed to go out, the controller should have received 3 packets on handle 0
  // and none on handle 1.
  EXPECT_EQ(kTotalExpected / 2u, handle0_packet_count);
  EXPECT_EQ(0u, handle1_packet_count);

  // Notify the processed packets with a Number Of Completed Packet HCI event.
  auto event_buffer = common::CreateStaticByteBuffer(
      0x13, 0x05,             // Event header
      0x01,                   // Number of handles
      0x01, 0x00, 0x03, 0x00  // 3 packets on handle 0x0001
  );
  test_device()->SendCommandChannelPacket(event_buffer);

  RunLoopUntilIdle();

  EXPECT_EQ(kTotalExpected, handle0_packet_count);
  EXPECT_EQ(0u, handle1_packet_count);
}

// Test that SendPacket works for LE packets when both buffer types are
// available.
TEST_F(HCI_ACLDataChannelTest, SendLEPacketBothBuffers) {
  constexpr size_t kMaxMTU = 200;
  constexpr size_t kMaxNumPackets = 50;
  constexpr size_t kLEMaxMTU = 5;
  constexpr size_t kLEMaxNumPackets = 5;
  constexpr ConnectionHandle kHandle0 = 0x0001;
  constexpr ConnectionHandle kHandle1 = 0x0002;

  InitializeACLDataChannel(DataBufferInfo(kMaxMTU, kMaxNumPackets),
                           DataBufferInfo(kLEMaxMTU, kLEMaxNumPackets));

  // This should fail because the payload exceeds the LE MTU.
  auto packet =
      ACLDataPacket::New(kHandle1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, kMaxMTU);
  EXPECT_FALSE(acl_data_channel()->SendPacket(std::move(packet),
                                              Connection::LinkType::kLE));

  int handle0_packet_count = 0;
  int handle1_packet_count = 0;
  auto data_callback = [&](const common::ByteBuffer& bytes) {
    ZX_DEBUG_ASSERT(bytes.size() >= sizeof(ACLDataHeader));

    common::PacketView<hci::ACLDataHeader> packet(
        &bytes, bytes.size() - sizeof(ACLDataHeader));
    ConnectionHandle connection_handle =
        le16toh(packet.header().handle_and_flags) & 0xFFF;

    if (connection_handle == kHandle0) {
      handle0_packet_count++;
    } else {
      ASSERT_EQ(kHandle1, connection_handle);
      handle1_packet_count++;
    }
  };
  test_device()->SetDataCallback(data_callback, dispatcher());

  // Queue up 10 packets in total, distributed among the two connection handles.
  async::PostTask(dispatcher(), [this, kHandle0, kHandle1] {
    for (int i = 0; i < 10; ++i) {
      ConnectionHandle handle = (i % 2) ? kHandle1 : kHandle0;
      Connection::LinkType ll_type =
          Connection::LinkType::kLE;  // Send LE packets only.
      auto packet =
          ACLDataPacket::New(handle, ACLPacketBoundaryFlag::kFirstNonFlushable,
                             ACLBroadcastFlag::kPointToPoint, kLEMaxMTU);
      EXPECT_TRUE(acl_data_channel()->SendPacket(std::move(packet), ll_type));
    }
  });

  RunLoopUntilIdle();

  // ACLDataChannel should be looking at kLEMaxNumPackets, which is 5. The
  // controller should have received 3 packets on kHandle0 and 2 on kHandle1
  EXPECT_EQ(3, handle0_packet_count);
  EXPECT_EQ(2, handle1_packet_count);

  // Notify the processed packets with a Number Of Completed Packet HCI event.
  auto event_buffer = common::CreateStaticByteBuffer(
      0x13, 0x09,              // Event header
      0x02,                    // Number of handles
      0x01, 0x00, 0x03, 0x00,  // 3 packets on handle 0x0001
      0x02, 0x00, 0x02, 0x00   // 2 packets on handle 0x0002
  );
  test_device()->SendCommandChannelPacket(event_buffer);

  RunLoopUntilIdle();

  EXPECT_EQ(5, handle0_packet_count);
  EXPECT_EQ(5, handle1_packet_count);
}

// Test that SendPacket works for BR/EDR packets when both buffer types are
// available.
TEST_F(HCI_ACLDataChannelTest, SendBREDRPacketBothBuffers) {
  constexpr size_t kLEMaxMTU = 200;
  constexpr size_t kLEMaxNumPackets = 50;
  constexpr size_t kMaxMTU = 5;
  constexpr size_t kMaxNumPackets = 5;
  constexpr ConnectionHandle kHandle0 = 0x0001;
  constexpr ConnectionHandle kHandle1 = 0x0002;

  InitializeACLDataChannel(DataBufferInfo(kMaxMTU, kMaxNumPackets),
                           DataBufferInfo(kLEMaxMTU, kLEMaxNumPackets));

  // This should fail because the payload exceeds the ACL MTU.
  auto packet =
      ACLDataPacket::New(kHandle1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, kLEMaxMTU);
  EXPECT_FALSE(acl_data_channel()->SendPacket(std::move(packet),
                                              Connection::LinkType::kACL));

  int handle0_packet_count = 0;
  int handle1_packet_count = 0;
  auto data_callback = [&](const common::ByteBuffer& bytes) {
    ZX_DEBUG_ASSERT(bytes.size() >= sizeof(ACLDataHeader));

    common::PacketView<hci::ACLDataHeader> packet(
        &bytes, bytes.size() - sizeof(ACLDataHeader));
    ConnectionHandle connection_handle =
        le16toh(packet.header().handle_and_flags) & 0xFFF;

    if (connection_handle == kHandle0) {
      handle0_packet_count++;
    } else {
      ASSERT_EQ(kHandle1, connection_handle);
      handle1_packet_count++;
    }
  };
  test_device()->SetDataCallback(data_callback, dispatcher());

  // Queue up 10 packets in total, distributed among the two connection handles.
  async::PostTask(dispatcher(), [this, kHandle0, kHandle1] {
    for (int i = 0; i < 10; ++i) {
      ConnectionHandle handle = (i % 2) ? kHandle1 : kHandle0;
      Connection::LinkType ll_type =
          Connection::LinkType::kACL;  // Send BR/EDR packets only.
      auto packet =
          ACLDataPacket::New(handle, ACLPacketBoundaryFlag::kFirstNonFlushable,
                             ACLBroadcastFlag::kPointToPoint, kMaxMTU);
      EXPECT_TRUE(acl_data_channel()->SendPacket(std::move(packet), ll_type));
    }
  });

  RunLoopUntilIdle();

  // ACLDataChannel should be looking at kLEMaxNumPackets, which is 5. The
  // controller should have received 3 packets on kHandle0 and 2 on kHandle1
  EXPECT_EQ(3, handle0_packet_count);
  EXPECT_EQ(2, handle1_packet_count);

  // Notify the processed packets with a Number Of Completed Packet HCI event.
  auto event_buffer = common::CreateStaticByteBuffer(
      0x13, 0x09,              // Event header
      0x02,                    // Number of handles
      0x01, 0x00, 0x03, 0x00,  // 3 packets on handle 0x0001
      0x02, 0x00, 0x02, 0x00   // 2 packets on handle 0x0002
  );
  test_device()->SendCommandChannelPacket(event_buffer);

  RunLoopUntilIdle();

  EXPECT_EQ(5, handle0_packet_count);
  EXPECT_EQ(5, handle1_packet_count);
}

TEST_F(HCI_ACLDataChannelTest, SendPacketFromMultipleThreads) {
  constexpr size_t kMaxMTU = 1;
  constexpr size_t kMaxNumPackets = 1;
  constexpr size_t kLEMaxMTU = 5;
  constexpr size_t kLEMaxNumPackets = 5;

  constexpr ConnectionHandle kHandle0 = 0x0001;
  constexpr ConnectionHandle kHandle1 = 0x0002;
  constexpr ConnectionHandle kHandle2 = 0x0003;

  constexpr int kExpectedTotalPacketCount = 18;

  int handle0_total_packet_count = 0;
  int handle1_total_packet_count = 0;
  int handle2_total_packet_count = 0;
  int handle0_processed_count = 0;
  int handle1_processed_count = 0;
  int handle2_processed_count = 0;
  int total_packet_count = 0;
  auto data_cb = [&](const common::ByteBuffer& bytes) {
    ZX_DEBUG_ASSERT(bytes.size() >= sizeof(ACLDataHeader));

    common::PacketView<hci::ACLDataHeader> packet(
        &bytes, bytes.size() - sizeof(ACLDataHeader));
    ConnectionHandle connection_handle =
        le16toh(packet.header().handle_and_flags) & 0xFFF;

    if (connection_handle == kHandle0) {
      handle0_total_packet_count++;
      handle0_processed_count++;
    } else if (connection_handle == kHandle1) {
      handle1_total_packet_count++;
      handle1_processed_count++;
    } else {
      ASSERT_EQ(kHandle2, connection_handle);
      handle2_total_packet_count++;
      handle2_processed_count++;
    }
    total_packet_count++;

    // For every kLEMaxNumPackets packets processed, we notify the host.
    if ((total_packet_count % kLEMaxNumPackets) == 0) {
      // NOTE(armansito): Here we include handles even when the processed-count
      // is 0. This is OK; ACLDataChannel should ignore those.
      auto event_buffer = common::CreateStaticByteBuffer(
          0x13, 0x0D,  // Event header
          0x03,        // Number of handles

          // handle 0x0001
          0x01, 0x00, static_cast<uint8_t>(handle0_processed_count), 0x00,
          // handle 0x0002
          0x02, 0x00, static_cast<uint8_t>(handle1_processed_count), 0x00,
          // handle 0x0003
          0x03, 0x00, static_cast<uint8_t>(handle2_processed_count), 0x00);
      handle0_processed_count = 0;
      handle1_processed_count = 0;
      handle2_processed_count = 0;
      test_device()->SendCommandChannelPacket(event_buffer);
    }
  };
  test_device()->SetDataCallback(data_cb, dispatcher());

  InitializeACLDataChannel(DataBufferInfo(kMaxMTU, kMaxNumPackets),
                           DataBufferInfo(kLEMaxMTU, kLEMaxNumPackets));

  // On 3 threads (for each connection handle) we each send 6 packets up to a
  // total of 18.
  auto thread_func = [this](ConnectionHandle handle) {
    for (int i = 0; i < kExpectedTotalPacketCount / 3; ++i) {
      auto packet =
          ACLDataPacket::New(handle, ACLPacketBoundaryFlag::kFirstNonFlushable,
                             ACLBroadcastFlag::kPointToPoint, kLEMaxMTU);
      EXPECT_TRUE(acl_data_channel()->SendPacket(std::move(packet),
                                                 Connection::LinkType::kLE));
    }
  };

  auto t1 = std::thread(thread_func, kHandle0);
  auto t2 = std::thread(thread_func, kHandle1);
  auto t3 = std::thread(thread_func, kHandle2);

  if (t1.joinable())
    t1.join();
  if (t2.joinable())
    t2.join();
  if (t3.joinable())
    t3.join();

  // Messages are sent on another thread, so wait here until they arrive.
  RunLoopUntilIdle();

  EXPECT_EQ(kExpectedTotalPacketCount / 3, handle0_total_packet_count);
  EXPECT_EQ(kExpectedTotalPacketCount / 3, handle1_total_packet_count);
  EXPECT_EQ(kExpectedTotalPacketCount / 3, handle2_total_packet_count);
  EXPECT_EQ(kExpectedTotalPacketCount, total_packet_count);
}

TEST_F(HCI_ACLDataChannelTest, SendPacketsFailure) {
  constexpr size_t kMaxMTU = 5;
  InitializeACLDataChannel(DataBufferInfo(kMaxMTU, 100), DataBufferInfo());

  // Empty packet list.
  EXPECT_FALSE(acl_data_channel()->SendPackets(
      common::LinkedList<ACLDataPacket>(), Connection::LinkType::kACL));

  // Packet exceeds MTU
  common::LinkedList<ACLDataPacket> packets;
  packets.push_back(
      ACLDataPacket::New(0x0001, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, kMaxMTU + 1));
  EXPECT_FALSE(acl_data_channel()->SendPackets(std::move(packets),
                                               Connection::LinkType::kACL));
}

// Tests sending multiple packets in a single call.
TEST_F(HCI_ACLDataChannelTest, SendPackets) {
  constexpr int kExpectedPacketCount = 5;
  InitializeACLDataChannel(DataBufferInfo(1024, 100), DataBufferInfo());

  bool pass = true;
  int seq_no = 0;
  auto data_cb = [&pass, &seq_no](const common::ByteBuffer& bytes) {
    ZX_DEBUG_ASSERT(bytes.size() >= sizeof(ACLDataHeader));
    common::PacketView<hci::ACLDataHeader> packet(
        &bytes, bytes.size() - sizeof(ACLDataHeader));
    EXPECT_EQ(1u, packet.payload_size());

    int cur_no = packet.payload_bytes()[0];
    if (cur_no != seq_no + 1) {
      pass = false;
      return;
    }

    seq_no = cur_no;
  };
  test_device()->SetDataCallback(data_cb, dispatcher());

  common::LinkedList<ACLDataPacket> packets;
  for (int i = 1; i <= kExpectedPacketCount; ++i) {
    auto packet =
        ACLDataPacket::New(1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                           ACLBroadcastFlag::kPointToPoint, 1);
    packet->mutable_view()->mutable_payload_bytes()[0] = i;
    packets.push_back(std::move(packet));
  }

  EXPECT_TRUE(acl_data_channel()->SendPackets(std::move(packets),
                                              Connection::LinkType::kLE));

  RunLoopUntilIdle();

  EXPECT_TRUE(pass);
  EXPECT_EQ(kExpectedPacketCount, seq_no);
}

// Test sending batches of packets atomically across multiple threads.
TEST_F(HCI_ACLDataChannelTest, SendPacketsAtomically) {
  constexpr size_t kThreadCount = 10;
  constexpr size_t kPacketsPerThread = 10;
  constexpr size_t kExpectedPacketCount = kThreadCount * kPacketsPerThread;

  InitializeACLDataChannel(DataBufferInfo(1024, 100), DataBufferInfo());

  std::vector<std::unique_ptr<common::ByteBuffer>> received;
  auto data_cb = [&received](const common::ByteBuffer& bytes) {
    ZX_DEBUG_ASSERT(bytes.size() >= sizeof(ACLDataHeader));
    received.push_back(std::make_unique<common::DynamicByteBuffer>(bytes));
  };
  test_device()->SetDataCallback(data_cb, dispatcher());

  // Each thread will send a sequence of kPacketsPerThread packets. The payload
  // of each packet encodes an integer
  common::LinkedList<ACLDataPacket> packets[kThreadCount];
  for (size_t i = 0; i < kThreadCount; ++i) {
    for (size_t j = 1; j <= kPacketsPerThread; ++j) {
      auto packet =
          ACLDataPacket::New(1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                             ACLBroadcastFlag::kPointToPoint, 1);
      packet->mutable_view()->mutable_payload_bytes()[0] = j;
      packets[i].push_back(std::move(packet));
    }
  }

  // Send each packet sequence on a different thread and make sure that each
  // sequence arrives atomically.
  std::thread threads[kThreadCount];
  auto thread_func = [&packets, this](size_t i) {
    EXPECT_TRUE(acl_data_channel()->SendPackets(std::move(packets[i]),
                                                Connection::LinkType::kLE));
  };

  for (size_t i = 0; i < kThreadCount; ++i) {
    threads[i] = std::thread(thread_func, i);
  }

  // Wait until all threads have queued their packets.
  for (size_t i = 0; i < kThreadCount; ++i) {
    if (threads[i].joinable())
      threads[i].join();
  }

  // Messages are sent on another thread, so wait here until they arrive.
  RunLoopUntilIdle();

  ASSERT_EQ(kExpectedPacketCount, received.size());

  // Verify that the contents of |received| are in the correct sequence.
  for (size_t i = 0; i < kExpectedPacketCount; ++i) {
    common::PacketView<hci::ACLDataHeader> packet(
        received[i].get(), received[i]->size() - sizeof(ACLDataHeader));
    EXPECT_EQ(1u, packet.payload_size());
    EXPECT_EQ((i % kPacketsPerThread) + 1, packet.payload_bytes()[0]);
  }
}

TEST_F(HCI_ACLDataChannelTest, ClearLinkState) {
  constexpr size_t kMaxMTU = 1024;
  constexpr size_t kMaxNumPackets = 2;
  constexpr ConnectionHandle kHandle1 = 1;
  constexpr ConnectionHandle kHandle2 = 2;

  InitializeACLDataChannel(DataBufferInfo(kMaxMTU, kMaxNumPackets),
                           DataBufferInfo());

  int packet_count = 0;
  test_device()->SetDataCallback([&](const auto&) { packet_count++; },
                                 dispatcher());

  // Send 3 packets on two links. This is enough to fill up the data buffers.
  ASSERT_TRUE(acl_data_channel()->SendPacket(
      ACLDataPacket::New(kHandle1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, 1),
      Connection::LinkType::kLE));
  ASSERT_TRUE(acl_data_channel()->SendPacket(
      ACLDataPacket::New(kHandle2, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, 1),
      Connection::LinkType::kLE));
  ASSERT_TRUE(acl_data_channel()->SendPacket(
      ACLDataPacket::New(kHandle1, ACLPacketBoundaryFlag::kFirstNonFlushable,
                         ACLBroadcastFlag::kPointToPoint, 1),
      Connection::LinkType::kLE));

  RunLoopUntilIdle();

  // The third packet should have been queued.
  ASSERT_EQ(2, packet_count);

  // Clear the packet count for |kHandle2|. The next packet should go out.
  acl_data_channel()->ClearLinkState(kHandle2);
  RunLoopUntilIdle();
  ASSERT_EQ(3, packet_count);
}

TEST_F(HCI_ACLDataChannelTest, ReceiveData) {
  constexpr size_t kMaxMTU = 5;
  constexpr size_t kMaxNumPackets = 5;

  // It doesn't matter what we set the buffer values to since we're testing
  // incoming packets.
  InitializeACLDataChannel(DataBufferInfo(kMaxMTU, kMaxNumPackets),
                           DataBufferInfo());

  constexpr size_t kExpectedPacketCount = 2u;
  size_t num_rx_packets = 0u;
  ConnectionHandle packet0_handle;
  ConnectionHandle packet1_handle;
  auto data_rx_cb = [&](ACLDataPacketPtr packet) {
    num_rx_packets++;
    if (num_rx_packets == 1) {
      packet0_handle = packet->connection_handle();
    } else if (num_rx_packets == 2) {
      packet1_handle = packet->connection_handle();
    } else {
      ZX_PANIC("|num_rx_packets| has unexpected value: %zu", num_rx_packets);
    }
  };
  set_data_received_callback(std::move(data_rx_cb));

  // Malformed packet: smaller than the ACL header.
  auto invalid0 = common::CreateStaticByteBuffer(0x01, 0x00, 0x00);

  // Malformed packet: the payload size given in the header doesn't match the
  // actual payload size.
  auto invalid1 = common::CreateStaticByteBuffer(0x01, 0x00, 0x02, 0x00, 0x00);

  // Valid packet on handle 1.
  auto valid0 = common::CreateStaticByteBuffer(0x01, 0x00, 0x01, 0x00, 0x00);

  // Valid packet on handle 2.
  auto valid1 = common::CreateStaticByteBuffer(0x02, 0x00, 0x01, 0x00, 0x00);

  async::PostTask(dispatcher(), [&, this] {
    test_device()->SendACLDataChannelPacket(invalid0);
    test_device()->SendACLDataChannelPacket(invalid1);
    test_device()->SendACLDataChannelPacket(valid0);
    test_device()->SendACLDataChannelPacket(valid1);
  });

  RunLoopUntilIdle();

  EXPECT_EQ(kExpectedPacketCount, num_rx_packets);
  EXPECT_EQ(0x0001, packet0_handle);
  EXPECT_EQ(0x0002, packet1_handle);
}

TEST_F(HCI_ACLDataChannelTest, TransportClosedCallback) {
  InitializeACLDataChannel(DataBufferInfo(1u, 1u), DataBufferInfo(1u, 1u));

  bool closed_cb_called = false;
  auto closed_cb = [&closed_cb_called, this] { closed_cb_called = true; };
  transport()->SetTransportClosedCallback(closed_cb,
                                          dispatcher());

  async::PostTask(dispatcher(),
                  [this] { test_device()->CloseACLDataChannel(); });
  RunLoopUntilIdle();
  EXPECT_TRUE(closed_cb_called);
}

TEST_F(HCI_ACLDataChannelTest, TransportClosedCallbackBothChannels) {
  InitializeACLDataChannel(DataBufferInfo(1u, 1u), DataBufferInfo(1u, 1u));

  int closed_cb_count = 0;
  auto closed_cb = [&closed_cb_count] { closed_cb_count++; };
  transport()->SetTransportClosedCallback(closed_cb,
                                          dispatcher());

  // We'll send closed events for both channels. The closed callback should get
  // invoked only once.
  async::PostTask(dispatcher(), [this] {
    test_device()->CloseACLDataChannel();
    test_device()->CloseCommandChannel();
  });

  RunLoopUntilIdle();
  EXPECT_EQ(1, closed_cb_count);
}

}  // namespace
}  // namespace hci
}  // namespace btlib
