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

#include <memory>

#include "garnet/drivers/bluetooth/lib/common/test_helpers.h"
#include "garnet/drivers/bluetooth/lib/hci/connection.h"
#include "garnet/drivers/bluetooth/lib/testing/fake_controller_test.h"
#include "garnet/drivers/bluetooth/lib/testing/test_controller.h"
#include "lib/fxl/macros.h"

namespace btlib {
namespace l2cap {
namespace {

constexpr hci::ConnectionHandle kTestHandle1 = 0x0001;
constexpr hci::ConnectionHandle kTestHandle2 = 0x0002;

using ::btlib::testing::TestController;

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

void DoNothing() {}
void NopRxCallback(const SDU&) {}

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

  void SetUp() override {
    SetUp(hci::DataBufferInfo(hci::kMaxACLPayloadSize, 10),
          hci::DataBufferInfo());
  }

  void SetUp(const hci::DataBufferInfo& acl_info,
             const hci::DataBufferInfo& le_info) {
    TestingBase::SetUp();
    TestingBase::InitializeACLDataChannel(acl_info, le_info);

    // FakeControllerTest's ACL data callbacks will no longer work after this
    // call, as it overwrites ACLDataChannel's data rx handler. This is intended
    // as the L2CAP layer takes ownership of ACL data traffic.
    chanmgr_ = std::make_unique<ChannelManager>(transport(), dispatcher());

    test_device()->StartCmdChannel(test_cmd_chan());
    test_device()->StartAclChannel(test_acl_chan());
  }

  void TearDown() override {
    chanmgr_ = nullptr;
    TestingBase::TearDown();
  }

  fbl::RefPtr<Channel> ActivateNewFixedChannel(
      ChannelId id, hci::ConnectionHandle conn_handle = kTestHandle1,
      Channel::ClosedCallback closed_cb = DoNothing,
      Channel::RxCallback rx_cb = NopRxCallback) {
    auto chan = chanmgr()->OpenFixedChannel(conn_handle, id);
    if (!chan ||
        !chan->Activate(std::move(rx_cb), std::move(closed_cb), dispatcher())) {
      return nullptr;
    }

    return chan;
  }

  ChannelManager* chanmgr() const { return chanmgr_.get(); }

 private:
  std::unique_ptr<ChannelManager> chanmgr_;

  FXL_DISALLOW_COPY_AND_ASSIGN(L2CAP_ChannelManagerTest);
};

TEST_F(L2CAP_ChannelManagerTest, OpenFixedChannelErrorNoConn) {
  // This should fail as the ChannelManager has no entry for |kTestHandle1|.
  EXPECT_EQ(nullptr, ActivateNewFixedChannel(kATTChannelId));

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  // This should fail as the ChannelManager has no entry for |kTestHandle2|.
  EXPECT_EQ(nullptr, ActivateNewFixedChannel(kATTChannelId, kTestHandle2));
}

TEST_F(L2CAP_ChannelManagerTest, OpenFixedChannelErrorDisallowedId) {
  // LE-U link
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  // ACL-U link
  chanmgr()->RegisterACL(kTestHandle2, hci::Connection::Role::kMaster,
                         DoNothing, dispatcher());

  // This should fail as kSMPChannelId is ACL-U only.
  EXPECT_EQ(nullptr, ActivateNewFixedChannel(kSMPChannelId, kTestHandle1));

  // This should fail as kATTChannelId is LE-U only.
  EXPECT_EQ(nullptr, ActivateNewFixedChannel(kATTChannelId, kTestHandle2));
}

TEST_F(L2CAP_ChannelManagerTest, ActivateFailsAfterDeactivate) {
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());
  auto chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1);
  ASSERT_TRUE(chan);

  chan->Deactivate();

  // Activate should fail.
  EXPECT_FALSE(chan->Activate(NopRxCallback, DoNothing, dispatcher()));
}

TEST_F(L2CAP_ChannelManagerTest, OpenFixedChannelAndUnregisterLink) {
  // LE-U link
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  bool closed_called = false;
  auto closed_cb = [&closed_called] { closed_called = true; };

  auto chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1, closed_cb);
  ASSERT_TRUE(chan);
  EXPECT_EQ(kTestHandle1, chan->link_handle());

  // This should notify the channel.
  chanmgr()->Unregister(kTestHandle1);

  RunLoopUntilIdle();

  // |closed_cb| will be called synchronously since it was registered using the
  // current thread's task runner.
  EXPECT_TRUE(closed_called);
}

TEST_F(L2CAP_ChannelManagerTest, OpenFixedChannelAndCloseChannel) {
  // LE-U link
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  bool closed_called = false;
  auto closed_cb = [&closed_called] { closed_called = true; };

  auto chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1, closed_cb);
  ASSERT_TRUE(chan);

  // Close the channel before unregistering the link. |closed_cb| should not get
  // called.
  chan->Deactivate();
  chanmgr()->Unregister(kTestHandle1);

  RunLoopUntilIdle();

  EXPECT_FALSE(closed_called);
}

TEST_F(L2CAP_ChannelManagerTest, OpenAndCloseMultipleFixedChannels) {
  // LE-U link
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  bool att_closed = false;
  auto att_closed_cb = [&att_closed] { att_closed = true; };

  bool smp_closed = false;
  auto smp_closed_cb = [&smp_closed] { smp_closed = true; };

  auto att_chan =
      ActivateNewFixedChannel(kATTChannelId, kTestHandle1, att_closed_cb);
  ASSERT_TRUE(att_chan);

  auto smp_chan =
      ActivateNewFixedChannel(kLESMPChannelId, kTestHandle1, smp_closed_cb);
  ASSERT_TRUE(smp_chan);

  smp_chan->Deactivate();
  chanmgr()->Unregister(kTestHandle1);

  RunLoopUntilIdle();

  EXPECT_TRUE(att_closed);
  EXPECT_FALSE(smp_closed);
}

TEST_F(L2CAP_ChannelManagerTest,
       CallingDeactivateFromClosedCallbackDoesNotCrashOrHang) {
  chanmgr()->RegisterACL(kTestHandle1, hci::Connection::Role::kMaster,
                         DoNothing, dispatcher());
  auto chan = chanmgr()->OpenFixedChannel(kTestHandle1, kSMPChannelId);
  chan->Activate(NopRxCallback, [chan] { chan->Deactivate(); }, dispatcher());
  chanmgr()->Unregister(kTestHandle1);  // Triggers ClosedCallback.
  RunLoopUntilIdle();
}

TEST_F(L2CAP_ChannelManagerTest, ReceiveData) {
  // LE-U link
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  common::StaticByteBuffer<255> buffer;

  // We use the ATT channel to control incoming packets and the SMP channel to
  // quit the message loop.
  std::vector<std::string> sdus;
  auto att_rx_cb = [&sdus, &buffer](const SDU& sdu) {
    size_t size = sdu.Copy(&buffer);
    sdus.push_back(buffer.view(0, size).ToString());
  };

  bool smp_cb_called = false;
  auto smp_rx_cb = [&smp_cb_called, this](const SDU& sdu) {
    EXPECT_EQ(0u, sdu.length());
    smp_cb_called = true;
  };

  auto att_chan =
      ActivateNewFixedChannel(kATTChannelId, kTestHandle1, [] {}, att_rx_cb);
  auto smp_chan =
      ActivateNewFixedChannel(kLESMPChannelId, kTestHandle1, [] {}, smp_rx_cb);
  ASSERT_TRUE(att_chan);
  ASSERT_TRUE(smp_chan);

  // ATT channel
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (starting fragment)
      0x01, 0x00, 0x09, 0x00,

      // L2CAP B-frame
      0x05, 0x00, 0x04, 0x00, 'h', 'e', 'l', 'l', 'o'));
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (starting fragment)
      0x01, 0x00, 0x09, 0x00,

      // L2CAP B-frame (partial)
      0x0C, 0x00, 0x04, 0x00, 'h', 'o', 'w', ' ', 'a'));
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (continuing fragment)
      0x01, 0x10, 0x07, 0x00,

      // L2CAP B-frame (partial)
      'r', 'e', ' ', 'y', 'o', 'u', '?'));

  // SMP channel
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (starting fragment)
      0x01, 0x00, 0x04, 0x00,

      // L2CAP B-frame (empty)
      0x00, 0x00, 0x06, 0x00));

  RunLoopUntilIdle();

  EXPECT_TRUE(smp_cb_called);
  ASSERT_EQ(2u, sdus.size());
  EXPECT_EQ("hello", sdus[0]);
  EXPECT_EQ("how are you?", sdus[1]);
}

TEST_F(L2CAP_ChannelManagerTest, ReceiveDataBeforeRegisteringLink) {
  constexpr size_t kPacketCount = 10;

  common::StaticByteBuffer<255> buffer;

  // We use the ATT channel to control incoming packets and the SMP channel to
  // quit the message loop.
  size_t packet_count = 0;
  auto att_rx_cb = [&packet_count](const SDU& sdu) { packet_count++; };

  bool smp_cb_called = false;
  auto smp_rx_cb = [&smp_cb_called, this](const SDU& sdu) {
    EXPECT_EQ(0u, sdu.length());
    smp_cb_called = true;
  };

  // ATT channel
  for (size_t i = 0u; i < kPacketCount; i++) {
    test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
        // ACL data header (starting fragment)
        0x01, 0x00, 0x04, 0x00,

        // L2CAP B-frame
        0x00, 0x00, 0x04, 0x00));
  }

  // SMP channel
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (starting fragment)
      0x01, 0x00, 0x04, 0x00,

      // L2CAP B-frame (empty)
      0x00, 0x00, 0x06, 0x00));

  fbl::RefPtr<Channel> att_chan, smp_chan;

  // Run the loop so all packets are received.
  RunLoopUntilIdle();

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  att_chan =
      ActivateNewFixedChannel(kATTChannelId, kTestHandle1, [] {}, att_rx_cb);
  FXL_DCHECK(att_chan);

  smp_chan =
      ActivateNewFixedChannel(kLESMPChannelId, kTestHandle1, [] {}, smp_rx_cb);
  FXL_DCHECK(smp_chan);

  RunLoopUntilIdle();
  EXPECT_TRUE(smp_cb_called);
  EXPECT_EQ(kPacketCount, packet_count);
}

// Receive data after registering the link but before creating the channel.
TEST_F(L2CAP_ChannelManagerTest, ReceiveDataBeforeCreatingChannel) {
  constexpr size_t kPacketCount = 10;

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  common::StaticByteBuffer<255> buffer;

  // We use the ATT channel to control incoming packets and the SMP channel to
  // quit the message loop.
  size_t packet_count = 0;
  auto att_rx_cb = [&packet_count](const SDU& sdu) { packet_count++; };

  bool smp_cb_called = false;
  auto smp_rx_cb = [&smp_cb_called, this](const SDU& sdu) {
    EXPECT_EQ(0u, sdu.length());
    smp_cb_called = true;
  };

  // ATT channel
  for (size_t i = 0u; i < kPacketCount; i++) {
    test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
        // ACL data header (starting fragment)
        0x01, 0x00, 0x04, 0x00,

        // L2CAP B-frame
        0x00, 0x00, 0x04, 0x00));
  }

  // SMP channel
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (starting fragment)
      0x01, 0x00, 0x04, 0x00,

      // L2CAP B-frame (empty)
      0x00, 0x00, 0x06, 0x00));

  fbl::RefPtr<Channel> att_chan, smp_chan;

  // Run the loop so all packets are received.
  RunLoopUntilIdle();

  att_chan =
      ActivateNewFixedChannel(kATTChannelId, kTestHandle1, [] {}, att_rx_cb);
  FXL_DCHECK(att_chan);

  smp_chan =
      ActivateNewFixedChannel(kLESMPChannelId, kTestHandle1, [] {}, smp_rx_cb);
  FXL_DCHECK(smp_chan);

  RunLoopUntilIdle();

  EXPECT_TRUE(smp_cb_called);
  EXPECT_EQ(kPacketCount, packet_count);
}

// Receive data after registering the link and creating the channel but before
// setting the rx handler.
TEST_F(L2CAP_ChannelManagerTest, ReceiveDataBeforeSettingRxHandler) {
  constexpr size_t kPacketCount = 10;

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());
  auto att_chan = chanmgr()->OpenFixedChannel(kTestHandle1, kATTChannelId);
  FXL_DCHECK(att_chan);

  auto smp_chan = chanmgr()->OpenFixedChannel(kTestHandle1, kLESMPChannelId);
  FXL_DCHECK(smp_chan);

  common::StaticByteBuffer<255> buffer;

  // We use the ATT channel to control incoming packets and the SMP channel to
  // quit the message loop.
  size_t packet_count = 0;
  auto att_rx_cb = [&packet_count](const SDU& sdu) { packet_count++; };

  bool smp_cb_called = false;
  auto smp_rx_cb = [&smp_cb_called, this](const SDU& sdu) {
    EXPECT_EQ(0u, sdu.length());
    smp_cb_called = true;
  };

  // ATT channel
  for (size_t i = 0u; i < kPacketCount; i++) {
    test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
        // ACL data header (starting fragment)
        0x01, 0x00, 0x04, 0x00,

        // L2CAP B-frame
        0x00, 0x00, 0x04, 0x00));
  }

  // SMP channel
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (starting fragment)
      0x01, 0x00, 0x04, 0x00,

      // L2CAP B-frame (empty)
      0x00, 0x00, 0x06, 0x00));

  // Run the loop so all packets are received.
  RunLoopUntilIdle();

  att_chan->Activate(att_rx_cb, DoNothing, dispatcher());
  smp_chan->Activate(smp_rx_cb, DoNothing, dispatcher());

  RunLoopUntilIdle();

  EXPECT_TRUE(smp_cb_called);
  EXPECT_EQ(kPacketCount, packet_count);
}

TEST_F(L2CAP_ChannelManagerTest, SendOnClosedLink) {
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());
  auto att_chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1);
  FXL_DCHECK(att_chan);

  chanmgr()->Unregister(kTestHandle1);

  EXPECT_FALSE(att_chan->Send(common::NewBuffer('T', 'e', 's', 't')));
}

TEST_F(L2CAP_ChannelManagerTest, SendBasicSdu) {
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());
  auto att_chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1);
  FXL_DCHECK(att_chan);

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

  EXPECT_TRUE(att_chan->Send(common::NewBuffer('T', 'e', 's', 't')));

  RunLoopUntilIdle();
  ASSERT_TRUE(received);

  auto expected = common::CreateStaticByteBuffer(
      // ACL data header (handle: 1, length 7)
      0x01, 0x00, 0x08, 0x00,

      // L2CAP B-frame: (length: 3, channel-id: 4)
      0x04, 0x00, 0x04, 0x00, 'T', 'e', 's', 't');

  EXPECT_TRUE(common::ContainersEqual(expected, *received));
}

TEST_F(L2CAP_ChannelManagerTest, SendDynamicChannelSdu) {
  constexpr ChannelId kLocalId = 0x0040;
  constexpr ChannelId kRemoteId = 0x9042;

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());

  // For testing how the SDU is encoded, open a "fixed" channel then assign it
  // different local and remote channel IDs in the dynamic channels range (as
  // would be likely in production).
  // TODO(xow): Fix this test after dynamic channels are implemented for
  // ChannelManager
  auto dyn_chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1);
  FXL_DCHECK(dyn_chan);
  dyn_chan->set_id_for_testing(kLocalId);
  dyn_chan->set_remote_id_for_testing(kRemoteId);

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

  EXPECT_TRUE(dyn_chan->Send(common::NewBuffer('T', 'e', 's', 't')));

  RunLoopUntilIdle();
  ASSERT_TRUE(received);

  auto expected = common::CreateStaticByteBuffer(
      // ACL data header (handle: 1, length 7)
      0x01, 0x00, 0x08, 0x00,

      // L2CAP B-frame: (length: 3, channel-id: 0x9042)
      0x04, 0x00, 0x42, 0x90, 'T', 'e', 's', 't');

  EXPECT_TRUE(common::ContainersEqual(expected, *received));
}

// Tests that fragmentation of LE vs BR/EDR packets is based on the same
// fragment size.
TEST_F(L2CAP_ChannelManagerTest, SendFragmentedSdus) {
  constexpr size_t kMaxNumPackets =
      100;  // Make this large to avoid simulating flow-control.
  constexpr size_t kMaxDataSize = 5;
  // constexpr size_t kExpectedNumFragments = 5;

  // No LE buffers.
  TearDown();
  SetUp(hci::DataBufferInfo(kMaxDataSize, kMaxNumPackets),
        hci::DataBufferInfo());

  std::vector<std::unique_ptr<common::ByteBuffer>> le_fragments, acl_fragments;
  auto data_cb = [&le_fragments,
                  &acl_fragments](const common::ByteBuffer& bytes) {
    FXL_DCHECK(bytes.size() >= sizeof(hci::ACLDataHeader));

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

    if (handle == kTestHandle1)
      le_fragments.push_back(
          std::make_unique<common::DynamicByteBuffer>(bytes));
    else if (handle == kTestHandle2)
      acl_fragments.push_back(
          std::make_unique<common::DynamicByteBuffer>(bytes));
  };
  test_device()->SetDataCallback(data_cb, dispatcher());

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());
  chanmgr()->RegisterACL(kTestHandle2, hci::Connection::Role::kMaster,
                         DoNothing, dispatcher());

  // We use the ATT fixed-channel for LE and the SM fixed-channel for ACL.
  auto att_chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1);
  auto sm_chan = ActivateNewFixedChannel(kSMPChannelId, kTestHandle2);
  ASSERT_TRUE(att_chan);
  ASSERT_TRUE(sm_chan);

  // SDU of length 5 corresponds to a 9-octet B-frame which should be sent over
  // 2 fragments.
  EXPECT_TRUE(att_chan->Send(common::NewBuffer('H', 'e', 'l', 'l', 'o')));

  // SDU of length 7 corresponds to a 11-octet B-frame which should be sent over
  // 3 fragments.
  EXPECT_TRUE(
      sm_chan->Send(common::NewBuffer('G', 'o', 'o', 'd', 'b', 'y', 'e')));

  RunLoopUntilIdle();

  EXPECT_EQ(2u, le_fragments.size());
  ASSERT_EQ(3u, acl_fragments.size());

  auto expected_le_0 = common::CreateStaticByteBuffer(
      // ACL data header (handle: 1, length: 5)
      0x01, 0x00, 0x05, 0x00,

      // L2CAP B-frame: (length: 5, channel-id: 4, partial payload)
      0x05, 0x00, 0x04, 0x00, 'H');

  auto expected_le_1 = common::CreateStaticByteBuffer(
      // ACL data header (handle: 1, pbf: continuing fr., length: 4)
      0x01, 0x10, 0x04, 0x00,

      // Continuing payload
      'e', 'l', 'l', 'o');

  auto expected_acl_0 = common::CreateStaticByteBuffer(
      // ACL data header (handle: 2, length: 5)
      0x02, 0x00, 0x05, 0x00,

      // l2cap b-frame: (length: 7, channel-id: 7, partial payload)
      0x07, 0x00, 0x07, 0x00, 'G');

  auto expected_acl_1 = common::CreateStaticByteBuffer(
      // ACL data header (handle: 2, pbf: continuing fr., length: 5)
      0x02, 0x10, 0x05, 0x00,

      // continuing payload
      'o', 'o', 'd', 'b', 'y');

  auto expected_acl_2 = common::CreateStaticByteBuffer(
      // ACL data header (handle: 2, pbf: continuing fr., length: 1)
      0x02, 0x10, 0x01, 0x00,

      // Continuing payload
      'e');

  EXPECT_TRUE(common::ContainersEqual(expected_le_0, *le_fragments[0]));
  EXPECT_TRUE(common::ContainersEqual(expected_le_1, *le_fragments[1]));

  EXPECT_TRUE(common::ContainersEqual(expected_acl_0, *acl_fragments[0]));
  EXPECT_TRUE(common::ContainersEqual(expected_acl_1, *acl_fragments[1]));
  EXPECT_TRUE(common::ContainersEqual(expected_acl_2, *acl_fragments[2]));
}

// Tests that fragmentation of LE and BR/EDR packets use the corresponding
// buffer size.
TEST_F(L2CAP_ChannelManagerTest, SendFragmentedSdusDifferentBuffers) {
  constexpr size_t kMaxNumPackets =
      100;  // This is large to avoid having to simulate flow-control
  constexpr size_t kMaxACLDataSize = 6;
  constexpr size_t kMaxLEDataSize = 10;
  // constexpr size_t kExpectedNumFragments = 3;

  TearDown();
  SetUp(hci::DataBufferInfo(kMaxACLDataSize, kMaxNumPackets),
        hci::DataBufferInfo(kMaxLEDataSize, kMaxNumPackets));

  std::vector<std::unique_ptr<common::ByteBuffer>> le_fragments, acl_fragments;
  auto data_cb = [&le_fragments,
                  &acl_fragments](const common::ByteBuffer& bytes) {
    FXL_DCHECK(bytes.size() >= sizeof(hci::ACLDataHeader));

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

    if (handle == kTestHandle1)
      le_fragments.push_back(
          std::make_unique<common::DynamicByteBuffer>(bytes));
    else if (handle == kTestHandle2)
      acl_fragments.push_back(
          std::make_unique<common::DynamicByteBuffer>(bytes));
  };
  test_device()->SetDataCallback(data_cb, dispatcher());

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, DoNothing, dispatcher());
  chanmgr()->RegisterACL(kTestHandle2, hci::Connection::Role::kMaster,
                         DoNothing, dispatcher());

  // We use the ATT fixed-channel for LE and the SM fixed-channel for ACL.
  auto att_chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1);
  auto sm_chan = ActivateNewFixedChannel(kSMPChannelId, kTestHandle2);
  ASSERT_TRUE(att_chan);
  ASSERT_TRUE(sm_chan);

  // SDU of length 5 corresponds to a 9-octet B-frame. The LE buffer size is
  // large enough for this to be sent over a single fragment.
  EXPECT_TRUE(att_chan->Send(common::NewBuffer('H', 'e', 'l', 'l', 'o')));

  // SDU of length 7 corresponds to a 11-octet B-frame. Due to the BR/EDR buffer
  // size, this should be sent over 2 fragments.
  EXPECT_TRUE(
      sm_chan->Send(common::NewBuffer('G', 'o', 'o', 'd', 'b', 'y', 'e')));

  RunLoopUntilIdle();

  EXPECT_EQ(1u, le_fragments.size());
  ASSERT_EQ(2u, acl_fragments.size());

  auto expected_le = common::CreateStaticByteBuffer(
      // ACL data header (handle: 1, length: 9)
      0x01, 0x00, 0x09, 0x00,

      // L2CAP B-frame: (length: 5, channel-id: 4)
      0x05, 0x00, 0x04, 0x00, 'H', 'e', 'l', 'l', 'o');

  auto expected_acl_0 = common::CreateStaticByteBuffer(
      // ACL data header (handle: 2, length: 6)
      0x02, 0x00, 0x06, 0x00,

      // l2cap b-frame: (length: 7, channel-id: 7, partial payload)
      0x07, 0x00, 0x07, 0x00, 'G', 'o');

  auto expected_acl_1 = common::CreateStaticByteBuffer(
      // ACL data header (handle: 2, pbf: continuing fr., length: 5)
      0x02, 0x10, 0x05, 0x00,

      // continuing payload
      'o', 'd', 'b', 'y', 'e');

  EXPECT_TRUE(common::ContainersEqual(expected_le, *le_fragments[0]));

  EXPECT_TRUE(common::ContainersEqual(expected_acl_0, *acl_fragments[0]));
  EXPECT_TRUE(common::ContainersEqual(expected_acl_1, *acl_fragments[1]));
}

TEST_F(L2CAP_ChannelManagerTest, LEChannelSignalLinkError) {
  bool link_error = false;
  auto link_error_cb = [&link_error, this] { link_error = true; };
  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        [](auto) {}, link_error_cb, dispatcher());

  // Activate a new Attribute channel to signal the error.
  auto chan = ActivateNewFixedChannel(kATTChannelId, kTestHandle1);
  chan->SignalLinkError();

  // The event will run asynchronously.
  EXPECT_FALSE(link_error);

  RunLoopUntilIdle();
  EXPECT_TRUE(link_error);
}

TEST_F(L2CAP_ChannelManagerTest, ACLChannelSignalLinkError) {
  bool link_error = false;
  auto link_error_cb = [&link_error, this] { link_error = true; };
  chanmgr()->RegisterACL(kTestHandle1, hci::Connection::Role::kMaster,
                         link_error_cb, dispatcher());

  // Activate a new Security Manager channel to signal the error.
  auto chan = ActivateNewFixedChannel(kSMPChannelId, kTestHandle1);
  chan->SignalLinkError();

  // The event will run asynchronously.
  EXPECT_FALSE(link_error);

  RunLoopUntilIdle();
  EXPECT_TRUE(link_error);
}

TEST_F(L2CAP_ChannelManagerTest, LEConnectionParameterUpdateRequest) {
  bool conn_param_cb_called = false;
  auto conn_param_cb = [&conn_param_cb_called, this](const auto& params) {
    // The parameters should match the payload of the HCI packet seen below.
    EXPECT_EQ(0x0006, params.min_interval());
    EXPECT_EQ(0x0C80, params.max_interval());
    EXPECT_EQ(0x01F3, params.max_latency());
    EXPECT_EQ(0x0C80, params.supervision_timeout());
    conn_param_cb_called = true;
  };

  chanmgr()->RegisterLE(kTestHandle1, hci::Connection::Role::kMaster,
                        conn_param_cb, DoNothing, dispatcher());

  // clang-format off
  test_device()->SendACLDataChannelPacket(common::CreateStaticByteBuffer(
      // ACL data header (handle: 0x0001, length: 16 bytes)
      0x01, 0x00, 0x10, 0x00,

      // L2CAP B-frame header (length: 12 bytes, channel-id: 0x0005 (LE sig))
      0x0C, 0x00, 0x05, 0x00,

      // L2CAP C-frame header
      // (LE conn. param. update request, id: 1, length: 8 bytes)
      0x12, 0x01, 0x08, 0x00,

      // Connection parameters (hardcoded to match the expections in
      // |conn_param_cb|).
      0x06, 0x00,
      0x80, 0x0C,
      0xF3, 0x01,
      0x80, 0x0C));
  // clang-format on

  RunLoopUntilIdle();
  EXPECT_TRUE(conn_param_cb_called);
}

}  // namespace
}  // namespace l2cap
}  // namespace btlib
