// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "pw_bluetooth_proxy/proxy_host.h"

#include <sys/types.h>

#include <array>
#include <cstdint>
#include <mutex>
#include <span>

#include "pw_allocator/libc_allocator.h"
#include "pw_allocator/testing.h"
#include "pw_assert/check.h"
#include "pw_bluetooth/emboss_util.h"
#include "pw_bluetooth/hci_commands.emb.h"
#include "pw_bluetooth/hci_common.emb.h"
#include "pw_bluetooth/hci_data.emb.h"
#include "pw_bluetooth/hci_events.emb.h"
#include "pw_bluetooth/hci_h4.emb.h"
#include "pw_bluetooth/l2cap_frames.emb.h"
#include "pw_bluetooth_proxy/direction.h"
#include "pw_bluetooth_proxy/h4_packet.h"
#include "pw_bluetooth_proxy/internal/logical_transport.h"
#include "pw_bluetooth_proxy/l2cap_channel_common.h"
#include "pw_bluetooth_proxy/l2cap_status_delegate.h"
#include "pw_bluetooth_proxy_private/test_utils.h"
#include "pw_containers/flat_map.h"
#include "pw_function/function.h"
#include "pw_log/log.h"
#include "pw_multibuf/from_span.h"
#include "pw_multibuf/multibuf.h"
#include "pw_span/cast.h"
#include "pw_span/span.h"
#include "pw_status/status.h"
#include "pw_sync/mutex.h"
#include "pw_thread/test_thread_context.h"
#include "pw_thread/thread.h"
#include "pw_unit_test/framework.h"
#include "pw_unit_test/status_macros.h"

namespace pw::bluetooth::proxy {
namespace {

constexpr uint16_t kConnectionHandle = 0x123;
constexpr uint16_t kConnectionHandle2 = 0x456;
constexpr uint16_t kConnectionHandle3 = 0xABC;

// Return a populated H4 command buffer of a type that proxy host doesn't
// interact with.
Status PopulateNoninteractingToControllerBuffer(H4PacketWithH4& h4_packet) {
  return CreateAndPopulateToControllerView<emboss::InquiryCommandWriter>(
             h4_packet,
             emboss::OpCode::LINK_KEY_REQUEST_REPLY,
             /*parameter_total_size=*/0)
      .status();
}

// Return a populated H4 event buffer of a type that proxy host doesn't interact
// with.
Status CreateNonInteractingToHostBuffer(H4PacketWithHci& h4_packet) {
  return CreateAndPopulateToHostEventWriter<emboss::InquiryCompleteEventWriter>(
             h4_packet, emboss::EventCode::INQUIRY_COMPLETE)
      .status();
}

// ########## Examples

// Example for docs.rst.
// Skip when using async mode.
#if PW_BLUETOOTH_PROXY_ASYNC == 0
TEST(Example, ExampleUsage) {
  pw::allocator::test::AllocatorForTest<4096> allocator;

  // Populate H4 buffer to send towards controller.
  std::array<uint8_t, emboss::InquiryCommandView::SizeInBytes() + 1>
      h4_array_from_host{};
  H4PacketWithH4 h4_packet_from_host{emboss::H4PacketType::UNKNOWN,
                                     h4_array_from_host};
  PW_TEST_EXPECT_OK(
      PopulateNoninteractingToControllerBuffer(h4_packet_from_host));

  // Populate H4 buffer to send towards host.
  std::array<uint8_t, emboss::InquiryCompleteEventView::SizeInBytes() + 1>
      hci_array_from_controller{};
  H4PacketWithHci h4_packet_from_controller{emboss::H4PacketType::UNKNOWN,
                                            hci_array_from_controller};

  PW_TEST_EXPECT_OK(
      CreateNonInteractingToHostBuffer(h4_packet_from_controller));

  pw::Function<void(H4PacketWithHci && packet)> container_send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  pw::Function<void(H4PacketWithH4 && packet)> container_send_to_controller_fn(
      ([]([[maybe_unused]] H4PacketWithH4&& packet) {}));

  // DOCSTAG: [pw_bluetooth_proxy-examples-basic]

#include "pw_bluetooth_proxy/proxy_host.h"

  // Container creates ProxyHost .
  ProxyHost proxy = ProxyHost(std::move(container_send_to_host_fn),
                              std::move(container_send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              &allocator);

  // Container passes H4 packets from host through proxy. Proxy will in turn
  // call the container-provided `container_send_to_controller_fn` to pass them
  // on to the controller. Some packets may be modified, added, or removed.
  proxy.HandleH4HciFromHost(std::move(h4_packet_from_host));

  // Container passes H4 packets from controller through proxy. Proxy will in
  // turn call the container-provided `container_send_to_host_fn` to pass them
  // on to the controller. Some packets may be modified, added, or removed.
  proxy.HandleH4HciFromController(std::move(h4_packet_from_controller));

  // DOCSTAG: [pw_bluetooth_proxy-examples-basic]
}
#endif  // PW_BLUETOOTH_PROXY_ASYNC

// ########## PassthroughTest

class PassthroughTest : public ProxyHostTest {};

// Verify buffer is properly passed (contents unaltered and zero-copy).
TEST_F(PassthroughTest, ToControllerPassesEqualBuffer) {
  std::array<uint8_t, emboss::InquiryCommandView::SizeInBytes() + 1> h4_arr{};
  H4PacketWithH4 h4_packet{emboss::H4PacketType::UNKNOWN, h4_arr};
  PW_TEST_EXPECT_OK(PopulateNoninteractingToControllerBuffer(h4_packet));

  // Struct for capturing because `pw::Function` can't fit multiple captures.
  struct {
    // Use a copy for comparison to catch if proxy incorrectly changes the
    // passed buffer.
    std::array<uint8_t, emboss::InquiryCommandView::SizeInBytes() + 1> h4_arr;
    H4PacketWithH4* h4_packet;
    uint8_t sends_called;
  } send_capture = {h4_arr, &h4_packet, 0};

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&send_capture](H4PacketWithH4&& packet) {
        send_capture.sends_called++;
        EXPECT_EQ(packet.GetH4Type(),
                  emboss::H4PacketType(send_capture.h4_arr[0]));
        EXPECT_TRUE(std::equal(send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end(),
                               send_capture.h4_arr.begin() + 1,
                               send_capture.h4_arr.end()));
        // Verify no copy by verifying buffer is at the same memory location.
        EXPECT_EQ(packet.GetHciSpan().data(),
                  send_capture.h4_packet->GetHciSpan().data());
      });

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromHost(std::move(h4_packet));

  // Verify to controller callback was called.
  EXPECT_EQ(send_capture.sends_called, 1);
}

// Verify buffer is properly passed (contents unaltered and zero-copy).
TEST_F(PassthroughTest, ToHostPassesEqualBuffer) {
  std::array<uint8_t, emboss::InquiryCompleteEventView::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_EXPECT_OK(CreateNonInteractingToHostBuffer(h4_packet));

  // Struct for capturing because `pw::Function` can't fit multiple captures.
  struct {
    // Use a copy for comparison to catch if proxy incorrectly changes the
    // passed buffer.
    std::array<uint8_t, emboss::InquiryCompleteEventView::SizeInBytes()>
        hci_arr;
    H4PacketWithHci* h4_packet;
    uint8_t sends_called;
  } send_capture = {hci_arr, &h4_packet, 0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture](H4PacketWithHci&& packet) {
        send_capture.sends_called++;
        EXPECT_EQ(packet.GetH4Type(), send_capture.h4_packet->GetH4Type());
        EXPECT_TRUE(std::equal(send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end(),
                               send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end()));
        // Verify no copy by verifying buffer is at the same memory location.
        EXPECT_EQ(packet.GetHciSpan().data(),
                  send_capture.h4_packet->GetHciSpan().data());
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  // Verify to controller callback was called.
  EXPECT_EQ(send_capture.sends_called, 1);
}

// Verify a command complete event (of a type that proxy doesn't act on) is
// properly passed (contents unaltered and zero-copy).
TEST_F(PassthroughTest, ToHostPassesEqualCommandComplete) {
  std::array<
      uint8_t,
      emboss::ReadLocalVersionInfoCommandCompleteEventWriter::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::ReadLocalVersionInfoCommandCompleteEventWriter>(
          h4_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::READ_LOCAL_VERSION_INFO);

  // Struct for capturing because `pw::Function` can't fit multiple captures.
  struct {
    std::array<
        uint8_t,
        emboss::ReadLocalVersionInfoCommandCompleteEventWriter::SizeInBytes()>
        hci_arr;
    H4PacketWithHci* h4_packet;
    uint8_t sends_called;
  } send_capture = {hci_arr, &h4_packet, 0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture](H4PacketWithHci&& packet) {
        send_capture.sends_called++;
        EXPECT_EQ(packet.GetH4Type(), send_capture.h4_packet->GetH4Type());
        EXPECT_TRUE(std::equal(send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end(),
                               send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end()));
        // Verify no copy by verifying buffer is at the same memory location.
        EXPECT_EQ(packet.GetHciSpan().data(),
                  send_capture.h4_packet->GetHciSpan().data());
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  // Verify to controller callback was called.
  EXPECT_EQ(send_capture.sends_called, 1);
}

TEST_F(PassthroughTest, BlockEvent) {
  std::array<uint8_t, emboss::InquiryCompleteEventView::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_EXPECT_OK(CreateNonInteractingToHostBuffer(h4_packet));

  struct {
    uint8_t sends_called;
  } send_capture = {0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture]([[maybe_unused]] H4PacketWithHci&& packet) {
        send_capture.sends_called++;
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  // 1. Block the event.
  proxy.SetEventBlocked(emboss::EventCode::INQUIRY_COMPLETE, true);
  EXPECT_TRUE(proxy.IsEventBlocked(emboss::EventCode::INQUIRY_COMPLETE));

  // 2. Send the event.
  proxy.HandleH4HciFromController(std::move(h4_packet));

  // 3. Verify it was NOT forwarded.
  EXPECT_EQ(send_capture.sends_called, 0);

  // 4. Unblock the event.
  proxy.SetEventBlocked(emboss::EventCode::INQUIRY_COMPLETE, false);
  EXPECT_FALSE(proxy.IsEventBlocked(emboss::EventCode::INQUIRY_COMPLETE));

  // 5. Send it again.
  H4PacketWithHci h4_packet2{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_EXPECT_OK(CreateNonInteractingToHostBuffer(h4_packet2));

  proxy.HandleH4HciFromController(std::move(h4_packet2));

  // 6. Verify it WAS forwarded.
  EXPECT_EQ(send_capture.sends_called, 1);
}

TEST_F(PassthroughTest, BlockLeSubevent) {
  struct {
    uint8_t sends_called;
  } send_capture = {0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture]([[maybe_unused]] H4PacketWithHci&& packet) {
        send_capture.sends_called++;
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  emboss::LeSubEventCode subevent_code =
      emboss::LeSubEventCode::DATA_LENGTH_CHANGE;

  // 1. Block the subevent.
  proxy.SetLeSubeventBlocked(subevent_code, true);
  EXPECT_TRUE(proxy.IsLeSubeventBlocked(subevent_code));

  // 2. Send the subevent.
  PW_TEST_ASSERT_OK(SendLeMetaEvent(proxy, subevent_code));

  // 3. Verify it was NOT forwarded.
  EXPECT_EQ(send_capture.sends_called, 0);

  // 4. Unblock the subevent.
  proxy.SetLeSubeventBlocked(subevent_code, false);
  EXPECT_FALSE(proxy.IsLeSubeventBlocked(subevent_code));

  // 5. Send it again.
  PW_TEST_ASSERT_OK(SendLeMetaEvent(proxy, subevent_code));

  // 6. Verify it WAS forwarded.
  EXPECT_EQ(send_capture.sends_called, 1);
}

TEST_F(PassthroughTest, BlockParentLeMetaEventBlocksSubevents) {
  struct {
    uint8_t sends_called;
  } send_capture = {0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture]([[maybe_unused]] H4PacketWithHci&& packet) {
        send_capture.sends_called++;
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  emboss::LeSubEventCode subevent_code =
      emboss::LeSubEventCode::DATA_LENGTH_CHANGE;

  // 1. Block the parent LE_META_EVENT.
  proxy.SetEventBlocked(emboss::EventCode::LE_META_EVENT, true);
  EXPECT_TRUE(proxy.IsEventBlocked(emboss::EventCode::LE_META_EVENT));

  // 2. Send a subevent (which is NOT individually blocked).
  proxy.SetLeSubeventBlocked(subevent_code, false);
  PW_TEST_ASSERT_OK(SendLeMetaEvent(proxy, subevent_code));

  // 3. Verify it was NOT forwarded because parent is blocked.
  EXPECT_EQ(send_capture.sends_called, 0);
}

TEST_F(PassthroughTest, BlockParentLeMetaEventBlocksMalformed) {
  struct {
    uint8_t sends_called;
  } send_capture = {0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture]([[maybe_unused]] H4PacketWithHci&& packet) {
        send_capture.sends_called++;
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  // 1. Block the parent LE_META_EVENT.
  proxy.SetEventBlocked(emboss::EventCode::LE_META_EVENT, true);
  EXPECT_TRUE(proxy.IsEventBlocked(emboss::EventCode::LE_META_EVENT));

  // 2. Create a too-short LE_META_EVENT packet.
  // The minimum size to contain an event code and a subevent code is 3 bytes
  // (EventHeader + 1 byte for subevent).
  std::array<uint8_t, emboss::EventHeader::IntrinsicSizeInBytes()> hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::EVENT, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto event_view,
      MakeEmbossWriter<emboss::EventHeaderWriter>(h4_packet.GetHciSpan()));
  event_view.event_code().Write(emboss::EventCode::LE_META_EVENT);
  event_view.parameter_total_size().Write(0);

  // 3. Send the malformed LE_META_EVENT.
  proxy.HandleH4HciFromController(std::move(h4_packet));

  // 4. Verify it was NOT forwarded because the parent event is blocked, even
  // though it's malformed.
  EXPECT_EQ(send_capture.sends_called, 0);
}

TEST_F(PassthroughTest, BlockEventANotB) {
  struct {
    uint8_t sends_called;
    emboss::EventCode last_sent_code;
  } send_capture = {0, emboss::EventCode::INQUIRY_COMPLETE};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture](H4PacketWithHci&& packet) {
        send_capture.sends_called++;
        auto event =
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan());
        if (event.ok()) {
          send_capture.last_sent_code = event->event_code().Read();
        }
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  emboss::EventCode event_a = emboss::EventCode::INQUIRY_COMPLETE;
  emboss::EventCode event_b = emboss::EventCode::HARDWARE_ERROR;

  // 1. Block Event A.
  proxy.SetEventBlocked(event_a, true);
  EXPECT_TRUE(proxy.IsEventBlocked(event_a));
  EXPECT_FALSE(proxy.IsEventBlocked(event_b));

  // 2. Send Event A (should be blocked).
  std::array<uint8_t, emboss::EventHeader::IntrinsicSizeInBytes()> hci_arr_a{};
  H4PacketWithHci h4_packet_a{emboss::H4PacketType::EVENT, hci_arr_a};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto event_view_a,
      MakeEmbossWriter<emboss::EventHeaderWriter>(h4_packet_a.GetHciSpan()));
  event_view_a.event_code().Write(event_a);
  event_view_a.parameter_total_size().Write(0);

  proxy.HandleH4HciFromController(std::move(h4_packet_a));
  EXPECT_EQ(send_capture.sends_called, 0);

  // 3. Send Event B (should NOT be blocked).
  std::array<uint8_t, emboss::EventHeader::IntrinsicSizeInBytes()> hci_arr_b{};
  H4PacketWithHci h4_packet_b{emboss::H4PacketType::EVENT, hci_arr_b};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto event_view_b,
      MakeEmbossWriter<emboss::EventHeaderWriter>(h4_packet_b.GetHciSpan()));
  event_view_b.event_code().Write(event_b);
  event_view_b.parameter_total_size().Write(0);

  proxy.HandleH4HciFromController(std::move(h4_packet_b));
  EXPECT_EQ(send_capture.sends_called, 1);
  EXPECT_EQ(send_capture.last_sent_code, event_b);
}

TEST_F(PassthroughTest, BlockLeSubeventANotB) {
  struct {
    uint8_t sends_called;
    emboss::LeSubEventCode last_sent_subevent;
  } send_capture = {0, emboss::LeSubEventCode::CONNECTION_COMPLETE};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture](H4PacketWithHci&& packet) {
        send_capture.sends_called++;
        auto event =
            MakeEmbossView<emboss::LEMetaEventView>(packet.GetHciSpan());
        if (event.ok()) {
          send_capture.last_sent_subevent = event->subevent_code_enum().Read();
        }
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  emboss::LeSubEventCode subevent_a =
      emboss::LeSubEventCode::DATA_LENGTH_CHANGE;
  emboss::LeSubEventCode subevent_b =
      emboss::LeSubEventCode::PHY_UPDATE_COMPLETE;

  // 1. Block Subevent A.
  proxy.SetLeSubeventBlocked(subevent_a, true);
  EXPECT_TRUE(proxy.IsLeSubeventBlocked(subevent_a));
  EXPECT_FALSE(proxy.IsLeSubeventBlocked(subevent_b));

  // 2. Send Subevent A (should be blocked).
  PW_TEST_ASSERT_OK(SendLeMetaEvent(proxy, subevent_a));
  EXPECT_EQ(send_capture.sends_called, 0);

  // 3. Send Subevent B (should NOT be blocked).
  PW_TEST_ASSERT_OK(SendLeMetaEvent(proxy, subevent_b));
  EXPECT_EQ(send_capture.sends_called, 1);
  EXPECT_EQ(send_capture.last_sent_subevent, subevent_b);
}

TEST_F(PassthroughTest, ResetFilters) {
  struct {
    uint8_t sends_called;
  } send_capture = {0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture]([[maybe_unused]] H4PacketWithHci&& packet) {
        send_capture.sends_called++;
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  // 1. Block all possible events and subevents (0-255).
  for (uint16_t i = 0; i < 256; ++i) {
    proxy.SetEventBlocked(static_cast<emboss::EventCode>(i), true);
    proxy.SetLeSubeventBlocked(static_cast<emboss::LeSubEventCode>(i), true);
  }

  // Verify they are blocked.
  for (uint16_t i = 0; i < 256; ++i) {
    EXPECT_TRUE(proxy.IsEventBlocked(static_cast<emboss::EventCode>(i)));
    EXPECT_TRUE(
        proxy.IsLeSubeventBlocked(static_cast<emboss::LeSubEventCode>(i)));
  }

  // 2. Reset filters.
  proxy.ResetFilters();

  // Verify they are all unblocked.
  for (uint16_t i = 0; i < 256; ++i) {
    EXPECT_FALSE(proxy.IsEventBlocked(static_cast<emboss::EventCode>(i)));
    EXPECT_FALSE(
        proxy.IsLeSubeventBlocked(static_cast<emboss::LeSubEventCode>(i)));
  }

  // 3. Send one event and one subevent and verify they are forwarded.
  emboss::EventCode event_code = emboss::EventCode::INQUIRY_COMPLETE;
  emboss::LeSubEventCode subevent_code =
      emboss::LeSubEventCode::DATA_LENGTH_CHANGE;

  std::array<uint8_t, emboss::EventHeader::IntrinsicSizeInBytes()> hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::EVENT, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto event_view,
      MakeEmbossWriter<emboss::EventHeaderWriter>(h4_packet.GetHciSpan()));
  event_view.event_code().Write(event_code);
  event_view.parameter_total_size().Write(0);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  PW_TEST_ASSERT_OK(SendLeMetaEvent(proxy, subevent_code));

  EXPECT_EQ(send_capture.sends_called, 2);
}

// ########## BadPacketTest
// The proxy should not affect buffers it can't process (it should just pass
// them on).

class BadPacketTest : public ProxyHostTest {};

TEST_F(BadPacketTest, BadH4TypeToControllerIsPassedOn) {
  std::array<uint8_t, emboss::InquiryCommandView::SizeInBytes() + 1> h4_arr{};
  H4PacketWithH4 h4_packet{emboss::H4PacketType::UNKNOWN, h4_arr};
  PW_TEST_EXPECT_OK(PopulateNoninteractingToControllerBuffer(h4_packet));
  // Set back to an invalid type (after
  // PopulateNoninteractingToControllerBuffer).
  h4_packet.SetH4Type(emboss::H4PacketType::UNKNOWN);

  // Struct for capturing because `pw::Function` can't fit multiple captures.
  struct {
    // Use a copy for comparison to catch if proxy incorrectly changes the
    // passed buffer.
    std::array<uint8_t, emboss::InquiryCommandView::SizeInBytes() + 1> h4_arr;
    H4PacketWithH4* h4_packet;
    uint8_t sends_called;
  } send_capture = {h4_arr, &h4_packet, 0};

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&send_capture](H4PacketWithH4&& packet) {
        send_capture.sends_called++;
        EXPECT_EQ(packet.GetH4Type(),
                  emboss::H4PacketType(send_capture.h4_arr[0]));
        EXPECT_TRUE(std::equal(send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end(),
                               send_capture.h4_arr.begin() + 1,
                               send_capture.h4_arr.end()));
        // Verify no copy by verifying buffer is at the same memory location.
        EXPECT_EQ(packet.GetHciSpan().data(),
                  send_capture.h4_packet->GetHciSpan().data());
      });

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromHost(std::move(h4_packet));

  // Verify to controller callback was called.
  EXPECT_EQ(send_capture.sends_called, 1);
}

TEST_F(BadPacketTest, BadH4TypeToHostIsPassedOn) {
  std::array<uint8_t, emboss::InquiryCompleteEventView::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_EXPECT_OK(CreateNonInteractingToHostBuffer(h4_packet));

  // Set back to an invalid type.
  h4_packet.SetH4Type(emboss::H4PacketType::UNKNOWN);

  // Struct for capturing because `pw::Function` can't fit multiple captures.
  struct {
    // Use a copy for comparison to catch if proxy incorrectly changes the
    // passed buffer.
    std::array<uint8_t, emboss::InquiryCompleteEventView::SizeInBytes()>
        hci_arr;
    H4PacketWithHci* h4_packet;
    uint8_t sends_called = 0;
  } send_capture = {hci_arr, &h4_packet, 0};

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture](H4PacketWithHci&& packet) {
        send_capture.sends_called++;
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::UNKNOWN);
        EXPECT_TRUE(std::equal(send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end(),
                               send_capture.h4_packet->GetHciSpan().begin(),
                               send_capture.h4_packet->GetHciSpan().end()));
        // Verify no copy by verifying buffer is at the same memory location.
        EXPECT_EQ(packet.GetHciSpan().data(),
                  send_capture.h4_packet->GetHciSpan().data());
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  // Verify to controller callback was called.
  EXPECT_EQ(send_capture.sends_called, 1);
}

TEST_F(BadPacketTest, EmptyBufferToControllerIsPassedOn) {
  std::array<uint8_t, 0> h4_arr;
  H4PacketWithH4 h4_packet{emboss::H4PacketType::COMMAND, h4_arr};
  // H4PacketWithH4 use the underlying h4 buffer to store type. Since its length
  // is zero, it can't store it and will always return UNKNOWN.
  EXPECT_EQ(h4_packet.GetH4Type(), emboss::H4PacketType::UNKNOWN);

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&sends_called](H4PacketWithH4&& packet) {
        sends_called++;
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::UNKNOWN);
        EXPECT_TRUE(packet.GetHciSpan().empty());
      });

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromHost(std::move(h4_packet));

  // Verify callback was called.
  EXPECT_EQ(sends_called, 1);
}

TEST_F(BadPacketTest, EmptyBufferToHostIsPassedOn) {
  std::array<uint8_t, 0> hci_arr;
  H4PacketWithHci h4_packet{emboss::H4PacketType::EVENT, hci_arr};

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&sends_called](H4PacketWithHci&& packet) {
        sends_called++;
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::EVENT);
        EXPECT_TRUE(packet.GetHciSpan().empty());
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  // Verify callback was called.
  EXPECT_EQ(sends_called, 1);
}

TEST_F(BadPacketTest, TooShortEventToHostIsPassOn) {
  std::array<uint8_t, emboss::InquiryCompleteEventView::SizeInBytes()>
      valid_hci_arr{};
  H4PacketWithHci valid_packet{emboss::H4PacketType::UNKNOWN, valid_hci_arr};
  PW_TEST_EXPECT_OK(CreateNonInteractingToHostBuffer(valid_packet));

  // Create packet for sending whose span size is one less than a valid command
  // complete event.
  H4PacketWithHci h4_packet{valid_packet.GetH4Type(),
                            valid_packet.GetHciSpan().subspan(
                                0, emboss::EventHeaderView::SizeInBytes() - 1)};

  // Struct for capturing because `pw::Function` can't fit multiple captures.
  struct {
    std::array<uint8_t, emboss::EventHeaderView::SizeInBytes() - 1> hci_arr;
    uint8_t sends_called = 0;
  } send_capture;
  // Copy valid event into a short_array whose size is one less than a valid
  // EventHeader.
  std::copy(h4_packet.GetHciSpan().begin(),
            h4_packet.GetHciSpan().end(),
            send_capture.hci_arr.begin());
  send_capture.sends_called = 0;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture](H4PacketWithHci&& packet) {
        send_capture.sends_called++;
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               send_capture.hci_arr.begin(),
                               send_capture.hci_arr.end()));
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  // Verify callback was called.
  EXPECT_EQ(send_capture.sends_called, 1);
}

TEST_F(BadPacketTest, TooShortCommandCompleteEventToHost) {
  std::array<
      uint8_t,
      emboss::ReadLocalVersionInfoCommandCompleteEventWriter::SizeInBytes()>
      valid_hci_arr{};
  H4PacketWithHci valid_packet{emboss::H4PacketType::UNKNOWN, valid_hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::ReadLocalVersionInfoCommandCompleteEventWriter>(
          valid_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::READ_LOCAL_VERSION_INFO);

  // Create packet for sending whose span size is one less than a valid command
  // complete event.
  H4PacketWithHci h4_packet{
      valid_packet.GetH4Type(),
      valid_packet.GetHciSpan().subspan(
          0,
          emboss::ReadLocalVersionInfoCommandCompleteEventWriter::
                  SizeInBytes() -
              1)};

  // Struct for capturing because `pw::Function` capture can't fit multiple
  // fields .
  struct {
    std::array<
        uint8_t,
        emboss::ReadLocalVersionInfoCommandCompleteEventWriter::SizeInBytes() -
            1>
        hci_arr;
    uint8_t sends_called = 0;
  } send_capture;
  std::copy(h4_packet.GetHciSpan().begin(),
            h4_packet.GetHciSpan().end(),
            send_capture.hci_arr.begin());
  send_capture.sends_called = 0;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&send_capture](H4PacketWithHci&& packet) {
        send_capture.sends_called++;
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               send_capture.hci_arr.begin(),
                               send_capture.hci_arr.end()));
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  // Verify callback was called.
  EXPECT_EQ(send_capture.sends_called, 1);
}

// ########## ReserveLeAclCreditsTest

class ReserveLeAclCreditsTest : public ProxyHostTest {};

// Proxy Host should reserve requested ACL credits from controller's ACL credits
// when using ReadBufferSize command.
TEST_F(ReserveLeAclCreditsTest, ProxyCreditsReserveCreditsWithReadBufferSize) {
  std::array<uint8_t,
             emboss::ReadBufferSizeCommandCompleteEventWriter::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::ReadBufferSizeCommandCompleteEventWriter>(
          h4_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::READ_BUFFER_SIZE);
  view.total_num_acl_data_packets().Write(10);
  view.acl_data_packet_length().Write(20);

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&sends_called](H4PacketWithHci&& received_packet) {
        sends_called++;
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_view,
            MakeEmbossWriter<emboss::ReadBufferSizeCommandCompleteEventWriter>(
                received_packet.GetHciSpan()));
        // Should reserve 2 credits from original total of 10 (so 8 left for
        // host).
        EXPECT_EQ(event_view.total_num_acl_data_packets().Read(), 8);
        EXPECT_EQ(event_view.acl_data_packet_length().Read(), 20);
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/2,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(proxy.GetNumFreeBrEdrAclPackets(), 2);

  EXPECT_TRUE(proxy.HasSendBrEdrAclCapability());

  // Verify to controller callback was called.
  EXPECT_EQ(sends_called, 1);
}

// Proxy Host should reserve requested ACL LE credits from controller's ACL LE
// credits when using LEReadBufferSizeV1 command.
TEST_F(ReserveLeAclCreditsTest,
       ProxyCreditsReserveCreditsWithLEReadBufferSizeV1) {
  std::array<
      uint8_t,
      emboss::LEReadBufferSizeV1CommandCompleteEventWriter::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
          h4_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::LE_READ_BUFFER_SIZE_V1);
  view.total_num_le_acl_data_packets().Write(10);

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&sends_called](H4PacketWithHci&& received_packet) {
        sends_called++;
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_view,
            MakeEmbossView<
                emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
                received_packet.GetHciSpan()));

        // Should reserve 2 credits from original total of 10 (so 8 left for
        // host).
        EXPECT_EQ(event_view.total_num_le_acl_data_packets().Read(), 8);
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);

  EXPECT_TRUE(proxy.HasSendLeAclCapability());

  // Verify to controller callback was called.
  EXPECT_EQ(sends_called, 1);
}

// Proxy Host should reserve requested ACL LE credits from controller's ACL LE
// credits when using LEReadBufferSizeV2 command.
TEST_F(ReserveLeAclCreditsTest,
       ProxyCreditsReserveCreditsWithLEReadBufferSizeV2) {
  std::array<
      uint8_t,
      emboss::LEReadBufferSizeV2CommandCompleteEventWriter::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::LEReadBufferSizeV2CommandCompleteEventWriter>(
          h4_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::LE_READ_BUFFER_SIZE_V2);
  view.total_num_le_acl_data_packets().Write(10);

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&sends_called](H4PacketWithHci&& received_packet) {
        sends_called++;
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_view,
            MakeEmbossView<
                emboss::LEReadBufferSizeV2CommandCompleteEventWriter>(
                received_packet.GetHciSpan()));
        // Should reserve 2 credits from original total of 10 (so 8 left for
        // host).
        EXPECT_EQ(event_view.total_num_le_acl_data_packets().Read(), 8);
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);

  EXPECT_TRUE(proxy.HasSendLeAclCapability());

  // Verify to controller callback was called.
  EXPECT_EQ(sends_called, 1);
}

// If controller provides less than wanted credits, we should reserve that
// smaller amount.
TEST_F(ReserveLeAclCreditsTest, ProxyCreditsCappedByControllerCredits) {
  std::array<
      uint8_t,
      emboss::LEReadBufferSizeV1CommandCompleteEventWriter::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
          h4_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::LE_READ_BUFFER_SIZE_V1);
  view.total_num_le_acl_data_packets().Write(5);

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&sends_called](H4PacketWithHci&& received_packet) {
        sends_called++;
        // We want 7, but can reserve only 5 from original 5 (so 0 left for
        // host).
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_view,
            MakeEmbossView<
                emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
                received_packet.GetHciSpan()));
        EXPECT_EQ(event_view.total_num_le_acl_data_packets().Read(), 0);
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/7,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 5);

  // Verify to controller callback was called.
  EXPECT_EQ(sends_called, 1);
}

// Proxy Host can reserve zero credits from controller's ACL LE credits.
TEST_F(ReserveLeAclCreditsTest, ProxyCreditsReserveZeroCredits) {
  std::array<
      uint8_t,
      emboss::LEReadBufferSizeV1CommandCompleteEventWriter::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
          h4_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::LE_READ_BUFFER_SIZE_V1);
  view.total_num_le_acl_data_packets().Write(10);

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&sends_called](H4PacketWithHci&& received_packet) {
        sends_called++;
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_view,
            MakeEmbossView<
                emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
                received_packet.GetHciSpan()));
        // Should reserve 0 credits from original total of 10 (so 10 left for
        // host).
        EXPECT_EQ(event_view.total_num_le_acl_data_packets().Read(), 10);
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);

  EXPECT_FALSE(proxy.HasSendLeAclCapability());

  // Verify to controller callback was called.
  EXPECT_EQ(sends_called, 1);
}

// If controller has no credits, proxy should reserve none.
TEST_F(ReserveLeAclCreditsTest, ProxyCreditsZeroWhenHostCreditsZero) {
  std::array<
      uint8_t,
      emboss::LEReadBufferSizeV1CommandCompleteEventWriter::SizeInBytes()>
      hci_arr{};
  H4PacketWithHci h4_packet{emboss::H4PacketType::UNKNOWN, hci_arr};
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto view,
      CreateAndPopulateToHostEventWriter<
          emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
          h4_packet, emboss::EventCode::COMMAND_COMPLETE));
  view.command_complete().command_opcode().Write(
      emboss::OpCode::LE_READ_BUFFER_SIZE_V1);
  view.total_num_le_acl_data_packets().Write(0);

  uint8_t sends_called = 0;
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&sends_called](H4PacketWithHci&& received_packet) {
        sends_called++;
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_view,
            MakeEmbossView<
                emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
                received_packet.GetHciSpan()));
        // Should reserve 0 credit from original total of 0 (so 0 left for
        // host).
        EXPECT_EQ(event_view.total_num_le_acl_data_packets().Read(), 0);
      });

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);

  EXPECT_TRUE(proxy.HasSendLeAclCapability());

  // Verify to controller callback was called.
  EXPECT_EQ(sends_called, 1);
}

TEST_F(ReserveLeAclCreditsTest, ProxyCreditsZeroWhenNotInitialized) {
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);

  EXPECT_TRUE(proxy.HasSendLeAclCapability());
}

// ########## NumberOfCompletedPacketsTest

class NumberOfCompletedPacketsTest : public ProxyHostTest {};

TEST_F(NumberOfCompletedPacketsTest, TwoOfThreeSentPacketsComplete) {
  constexpr size_t kNumConnections = 3;
  struct {
    int sends_called = 0;
    const std::array<uint16_t, kNumConnections> connection_handles = {
        0x123, 0x456, 0x789};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(packet.GetHciSpan().size(), 15ul);
        EXPECT_EQ(view.num_handles().Read(), capture.connection_handles.size());
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Proxy should have reclaimed 1 credit from Connection 0 (leaving 0
        // credits in packet), no credits from Connection 1 (meaning 0 will be
        // unchanged), and 1 credit from Connection 2 (leaving 0).
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  capture.connection_handles[0]);
        EXPECT_EQ(view.nocp_data()[0].num_completed_packets().Read(), 0);

        EXPECT_EQ(view.nocp_data()[1].connection_handle().Read(),
                  capture.connection_handles[1]);
        EXPECT_EQ(view.nocp_data()[1].num_completed_packets().Read(), 0);

        EXPECT_EQ(view.nocp_data()[2].connection_handle().Read(),
                  capture.connection_handles[2]);
        EXPECT_EQ(view.nocp_data()[2].num_completed_packets().Read(), 0);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/kNumConnections,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(
      SendLeReadBufferResponseFromController(proxy, kNumConnections));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.connection_handles[0], emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.connection_handles[1], emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.connection_handles[2], emboss::StatusCode::SUCCESS));
  EXPECT_EQ(capture.sends_called, 4);

  std::array<uint8_t, 1> attribute_value = {7};

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 3);

  // Send packet; num free packets should decrement.
  {
    GattNotifyChannel channel = BuildGattNotifyChannel(
        proxy, {.handle = capture.connection_handles[0]});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);
    // Proxy host took all credits so will not pass NOCP on to host.
    EXPECT_EQ(capture.sends_called, 4);
  }

  // Send packet over Connection 1, which will not have a packet completed in
  // the Number_of_Completed_Packets event.
  {
    GattNotifyChannel channel = BuildGattNotifyChannel(
        proxy, {.handle = capture.connection_handles[1]});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 1);
  }

  // Send third packet; num free packets should decrement again.
  {
    GattNotifyChannel channel = BuildGattNotifyChannel(
        proxy, {.handle = capture.connection_handles[2]});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  }

  // Send Number_of_Completed_Packets event that reports 1 packet on Connection
  // 0, 0 packets on Connection 1, and 1 packet on Connection 2. Checks in
  // send_to_host_fn will ensure we have reclaimed 2 of 3 credits.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy,
                                   {{capture.connection_handles[0], 1},
                                    {capture.connection_handles[1], 0},
                                    {capture.connection_handles[2], 1}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);
  // Proxy host took all credits so will not pass NOCP event on to host.
  EXPECT_EQ(capture.sends_called, 4);
}

TEST_F(NumberOfCompletedPacketsTest, InterlaceProxyAndHostCredits) {
  struct {
    int nocp_sends_called = 0;
    uint16_t last_host_reclaimed = 0;
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }
        capture.nocp_sends_called++;
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  kConnectionHandle);
        capture.last_host_reclaimed =
            view.nocp_data()[0].num_completed_packets().Read();
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/5,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 10));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 5);

  // Send Host packet.
  std::array<uint8_t, 9> host_packet_arr = {
      0x02,
      0x23,
      0x01,
      0x04,
      0x00,  // H4 type, Handle, Length
      0x00,
      0x00,
      0x00,
      0x00  // Payload
  };
  proxy.HandleH4HciFromHost(H4PacketWithH4(host_packet_arr));

  // Send Proxy packet.
  GattNotifyChannel channel =
      BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
  std::array<uint8_t, 3> proxy_packet_arr1 = {1, 2, 3};
  PW_TEST_EXPECT_OK(channel.Write(MultiBufFromArray(proxy_packet_arr1)).status);
  RunDispatcher();

  // Send another Host packet.
  proxy.HandleH4HciFromHost(H4PacketWithH4(host_packet_arr));

  // Send another Proxy packet.
  std::array<uint8_t, 3> proxy_packet_arr2 = {4, 5, 6};
  PW_TEST_EXPECT_OK(channel.Write(MultiBufFromArray(proxy_packet_arr2)).status);
  RunDispatcher();

  // 2 proxy packets pending.
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 3);

  // Now send NOCP events and verify interlacing.

  // 1st completed packet was Host.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy, {{kConnectionHandle, 1}}));
  EXPECT_EQ(capture.nocp_sends_called, 1);
  EXPECT_EQ(capture.last_host_reclaimed, 1);
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 3);

  // 2nd completed packet was Proxy.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy, {{kConnectionHandle, 1}}));
  // Proxy took the credit, so no NOCP sent to host.
  EXPECT_EQ(capture.nocp_sends_called, 1);
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 4);

  // 3rd and 4th completed packets were Host and Proxy.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy, {{kConnectionHandle, 2}}));
  // One for host, one for proxy. Host should get a NOCP with 1 packet.
  EXPECT_EQ(capture.nocp_sends_called, 2);
  EXPECT_EQ(capture.last_host_reclaimed, 1);
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 5);
}

TEST_F(NumberOfCompletedPacketsTest,
       ManyMorePacketsCompletedThanPacketsPending) {
  constexpr size_t kNumConnections = 2;
  struct {
    int sends_called = 0;
    const std::array<uint16_t, kNumConnections> connection_handles = {0x123,
                                                                      0x456};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(packet.GetHciSpan().size(), 11ul);
        EXPECT_EQ(view.num_handles().Read(), capture.connection_handles.size());
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Proxy should have reclaimed 1 credit from Connection 0 (leaving
        // 9 credits in packet) and 1 credit from Connection 2 (leaving 14).
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  capture.connection_handles[0]);
        EXPECT_EQ(view.nocp_data()[0].num_completed_packets().Read(), 9);

        EXPECT_EQ(view.nocp_data()[1].connection_handle().Read(),
                  capture.connection_handles[1]);
        EXPECT_EQ(view.nocp_data()[1].num_completed_packets().Read(), 14);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 2));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.connection_handles[0], emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.connection_handles[1], emboss::StatusCode::SUCCESS));
  EXPECT_EQ(capture.sends_called, 3);

  std::array<uint8_t, 1> attribute_value = {0};

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);

  // Send packet over Connection 0; num free packets should decrement.
  {
    GattNotifyChannel channel = BuildGattNotifyChannel(
        proxy, {.handle = capture.connection_handles[0]});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 1);
  }

  // Send packet over Connection 1; num free packets should decrement again.
  {
    GattNotifyChannel channel = BuildGattNotifyChannel(
        proxy, {.handle = capture.connection_handles[1]});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  }

  // Send Number_of_Completed_Packets event that reports 10 packets on
  // Connection 0 and 15 packets on Connection 1. Checks in send_to_host_fn
  // will ensure we have reclaimed exactly 2 credits, 1 from each Connection.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy,
                                   {{capture.connection_handles[0], 10},
                                    {capture.connection_handles[1], 15}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);
  EXPECT_EQ(capture.sends_called, 4);
}

TEST_F(NumberOfCompletedPacketsTest, ProxyReclaimsOnlyItsUsedCredits) {
  constexpr size_t kNumConnections = 2;
  struct {
    int sends_called = 0;
    const std::array<uint16_t, kNumConnections> connection_handles = {
        kConnectionHandle, kConnectionHandle2};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(packet.GetHciSpan().size(), 11ul);
        EXPECT_EQ(view.num_handles().Read(), 2);
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Proxy has 4 credits it wants to reclaim, but it should have only
        // reclaimed the 2 credits it used on Connection 0.
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  capture.connection_handles[0]);
        EXPECT_EQ(view.nocp_data()[0].num_completed_packets().Read(), 8);
        EXPECT_EQ(view.nocp_data()[1].connection_handle().Read(),
                  capture.connection_handles[1]);
        EXPECT_EQ(view.nocp_data()[1].num_completed_packets().Read(), 15);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/4,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 4));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.connection_handles[0], emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.connection_handles[1], emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle3, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(capture.sends_called, 4);

  std::array<uint8_t, 1> attribute_value = {0};

  // Use 2 credits on Connection 0 and 2 credits on random connections that will
  // not be included in the NOCP event.
  {
    GattNotifyChannel channel = BuildGattNotifyChannel(
        proxy, {.handle = capture.connection_handles[0]});
    multibuf::MultiBuf mbuf1 = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf1)).status);
    RunDispatcher();

    multibuf::MultiBuf mbuf2 = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf2)).status);
    RunDispatcher();
  }
  {
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle3});
    multibuf::MultiBuf mbuf1 = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf1)).status);
    RunDispatcher();

    multibuf::MultiBuf mbuf2 = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf2)).status);
    RunDispatcher();

    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  }

  // Send Number_of_Completed_Packets event that reports 10 packets on
  // Connection 0 and 15 packets on Connection 1. Checks in send_to_host_fn
  // will ensure we have reclaimed only 2 credits.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy,
                                   {{capture.connection_handles[0], 10},
                                    {capture.connection_handles[1], 15}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);
  // NOCP has credits remaining so will be passed on to host.
  EXPECT_EQ(capture.sends_called, 5);
}

TEST_F(NumberOfCompletedPacketsTest, EventUnmodifiedIfNoCreditsInUse) {
  constexpr size_t kNumConnections = 2;
  struct {
    int sends_called = 0;
    const std::array<uint16_t, kNumConnections> connection_handles = {0x123,
                                                                      0x456};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(packet.GetHciSpan().size(), 11ul);
        EXPECT_EQ(view.num_handles().Read(), 2);
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Event should be unmodified.
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  capture.connection_handles[0]);
        EXPECT_EQ(view.nocp_data()[0].num_completed_packets().Read(), 10);
        EXPECT_EQ(view.nocp_data()[1].connection_handle().Read(),
                  capture.connection_handles[1]);
        EXPECT_EQ(view.nocp_data()[1].num_completed_packets().Read(), 15);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/10,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 10));
  EXPECT_EQ(capture.sends_called, 1);

  // Send Number_of_Completed_Packets event that reports 10 packets on
  // Connection 0 and 15 packets on Connection 1. Checks in send_to_host_fn
  // will ensure we have not modified the NOCP event.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy,
                                   {{capture.connection_handles[0], 10},
                                    {capture.connection_handles[1], 15}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 10);
  // NOCP has credits remaining so will be passed on to host.
  EXPECT_EQ(capture.sends_called, 2);
}

TEST_F(NumberOfCompletedPacketsTest, HandlesUnusualEvents) {
  constexpr size_t kNumConnections = 5;
  struct {
    int sends_called = 0;
    const std::array<uint16_t, kNumConnections> connection_handles = {
        0x123, 0x234, 0x345, 0x456, 0x567};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        if (view.num_handles().Read() == 0) {
          return;
        }

        EXPECT_EQ(packet.GetHciSpan().size(), 23ul);
        EXPECT_EQ(view.num_handles().Read(), 5);
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Event should be unmodified.
        for (size_t i = 0; i < 5; ++i) {
          EXPECT_EQ(view.nocp_data()[i].connection_handle().Read(),
                    capture.connection_handles[i]);
          EXPECT_EQ(view.nocp_data()[i].num_completed_packets().Read(), 0);
        }
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/10,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 10));
  EXPECT_EQ(capture.sends_called, 1);

  // Send Number_of_Completed_Packets event with no entries.
  PW_TEST_EXPECT_OK(SendNumberOfCompletedPackets(proxy, {{}}));
  // NOCP has no entries, so will not be passed on to host.
  EXPECT_EQ(capture.sends_called, 1);

  // Send Number_of_Completed_Packets event that reports 0 packets for various
  // connections.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy,
                                   {{capture.connection_handles[0], 0},
                                    {capture.connection_handles[1], 0},
                                    {capture.connection_handles[2], 0},
                                    {capture.connection_handles[3], 0},
                                    {capture.connection_handles[4], 0}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 10);
  // Proxy host will not pass on a NOCP with no credits.
  EXPECT_EQ(capture.sends_called, 1);
}

TEST_F(NumberOfCompletedPacketsTest, MultipleChannelsDifferentTransports) {
  static constexpr size_t kPayloadSize = 3;
  const uint16_t kLeConnectionHandle = 0x123;
  const uint16_t kBrEdrConnectionHandle = 0x456;
  struct {
    int sends_called = 0;
    std::array<uint8_t, kPayloadSize> payload = {
        0xAB,
        0xCD,
        0xEF,
    };
  } capture;

  pw::Function<void(H4PacketWithHci&&)>&& send_to_host_fn(
      [](H4PacketWithHci&&) {});
  pw::Function<void(H4PacketWithH4&&)>&& send_to_controller_fn(
      [&capture](H4PacketWithH4&&) { ++capture.sends_called; });

  auto* allocator = GetProxyHostAllocator();
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/1,
                              allocator);
  StartDispatcherOnCurrentThread(proxy);
  // Allow proxy to reserve BR/EDR 1 credit.
  PW_TEST_EXPECT_OK(SendReadBufferResponseFromController(proxy, 1));
  // Allow proxy to reserve LE 1 credit.
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kLeConnectionHandle, emboss::StatusCode::SUCCESS));
  PW_TEST_EXPECT_OK(SendConnectionCompleteEvent(
      proxy, kBrEdrConnectionHandle, emboss::StatusCode::SUCCESS));

  // Test that sending on one type of transport doesn't get blocked if the other
  // type of transport is out of credits.

  L2capCoc le_channel = BuildCoc(
      proxy, CocParameters{.handle = kLeConnectionHandle, .tx_credits = 2});
  multibuf::MultiBuf empty = MakeEmptyMultiBuf();
  PW_TEST_EXPECT_OK(le_channel.Write(std::move(empty)).status);
  RunDispatcher();
  EXPECT_EQ(capture.sends_called, 1);

  BasicL2capChannel bredr_channel =
      BuildBasicL2capChannel(proxy,
                             {.handle = kBrEdrConnectionHandle,
                              .transport = AclTransportType::kBrEdr});
  auto mbuf_result = multibuf::FromSpan(
      *allocator, as_writable_bytes(span(capture.payload)), [](ByteSpan) {});
  ASSERT_TRUE(mbuf_result.has_value());
  multibuf::MultiBuf mbuf = std::move(*mbuf_result);
  PW_TEST_EXPECT_OK(bredr_channel.Write(std::move(mbuf)).status);
  RunDispatcher();

  // Send should succeed even though no LE credits available
  EXPECT_EQ(capture.sends_called, 2);

  // Queue an LE write
  empty = MakeEmptyMultiBuf();
  PW_TEST_EXPECT_OK(le_channel.Write(std::move(empty)).status);
  RunDispatcher();
  EXPECT_EQ(capture.sends_called, 2);

  // Complete previous LE write
  PW_TEST_EXPECT_OK(SendNumberOfCompletedPackets(proxy, {{0x123, 1}}));
  EXPECT_EQ(capture.sends_called, 3);

  // Complete BR/EDR write
  PW_TEST_EXPECT_OK(SendNumberOfCompletedPackets(proxy, {{0x456, 1}}));

  // Write again
  mbuf_result = multibuf::FromSpan(
      *allocator, as_writable_bytes(span(capture.payload)), [](ByteSpan) {});
  ASSERT_TRUE(mbuf_result.has_value());
  mbuf = std::move(*mbuf_result);
  PW_TEST_EXPECT_OK(bredr_channel.Write(std::move(mbuf)).status);
  RunDispatcher();
  EXPECT_EQ(capture.sends_called, 4);
}

// ########## DisconnectionCompleteTest

class DisconnectionCompleteTest : public ProxyHostTest {};

TEST_F(DisconnectionCompleteTest, DisconnectionReclaimsCredits) {
  struct {
    int sends_called = 0;
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(packet.GetHciSpan().size(), 7ul);
        EXPECT_EQ(view.num_handles().Read(), 1);
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Event should be unmodified.
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  kConnectionHandle);
        EXPECT_EQ(view.nocp_data()[0].num_completed_packets().Read(), 10);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/10,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 10));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle3, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(capture.sends_called, 3);

  std::array<uint8_t, 1> attribute_value = {0};

  {
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});

    // Use up 3 of the 10 credits on the Connection that will be disconnected.
    for (int i = 0; i < 3; ++i) {
      multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
      PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
      RunDispatcher();
    }
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 7);
  }

  // Use up 2 credits on a random Connection.
  {
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle3});

    for (int i = 0; i < 2; ++i) {
      multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
      PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
      RunDispatcher();
    }
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 5);
  }

  // Send Disconnection_Complete event, which should reclaim 3 credits.
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, kConnectionHandle));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 8);
  EXPECT_EQ(capture.sends_called, 4);

  // Use 1 credit and reclaim it on a bunch of random channels. Then send
  // disconnect and ensure it was cleaned up in connections list. The send will
  // fail if disconnect doesn't cleanup properly.
  //
  // We already have an active connection at this point in the test, so loop
  // over the remaining slots + 1 which would otherwise fail if cleanup wasn't
  // working right.
  size_t kNumRemainingConnections = ProxyHost::GetMaxNumAclConnections() - 2;
  for (uint16_t i = 0; i < kNumRemainingConnections; ++i) {
    uint16_t handle = 0x234 + i;
    PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
        proxy, handle, emboss::StatusCode::SUCCESS));
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = handle});

    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();

    PW_TEST_EXPECT_OK(SendNumberOfCompletedPackets(proxy, {{handle, 1}}));
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 8);
    PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, handle));
  }

  // Send Number_of_Completed_Packets event that reports 10 packets, none of
  // which should be reclaimed because this Connection has disconnected. Checks
  // in send_to_host_fn will ensure we have not modified the NOCP event.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy, {{kConnectionHandle, 10}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 8);
  // NOCP has credits remaining so will be passed on to host.
  EXPECT_EQ(static_cast<size_t>(capture.sends_called),
            4 + (2 * kNumRemainingConnections) + 1);
}

TEST_F(DisconnectionCompleteTest, FailedDisconnectionHasNoEffect) {
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  std::array<uint8_t, 1> attribute_value = {0};

  // Use sole credit.
  GattNotifyChannel channel =
      BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
  multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
  PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
  RunDispatcher();
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);

  // Send failed Disconnection_Complete event, should not reclaim credit.
  PW_TEST_EXPECT_OK(
      SendDisconnectionCompleteEvent(proxy,
                                     kConnectionHandle,
                                     /*direction=*/Direction::kFromController,
                                     /*successful=*/false));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
}

TEST_F(DisconnectionCompleteTest, DisconnectionOfUnusedConnectionHasNoEffect) {
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  std::array<uint8_t, 1> attribute_value = {0};

  // Use sole credit.
  GattNotifyChannel channel =
      BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
  multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
  PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
  RunDispatcher();
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);

  // Send Disconnection_Complete event to random Connection, should have no
  // effect.
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, 0x456));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
}

TEST_F(DisconnectionCompleteTest, CanReuseConnectionHandleAfterDisconnection) {
  struct {
    int sends_called = 0;
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(packet.GetHciSpan().size(), 7ul);
        EXPECT_EQ(view.num_handles().Read(), 1);
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Should have reclaimed the 1 packet.
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  kConnectionHandle);
        EXPECT_EQ(view.nocp_data()[0].num_completed_packets().Read(), 0);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(capture.sends_called, 2);

  std::array<uint8_t, 1> attribute_value = {0};

  {
    // Establish connection over `connection_handle`.
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  }

  // Disconnect
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, kConnectionHandle));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 1);
  EXPECT_EQ(capture.sends_called, 3);

  // Reconnect
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  {
    // Re-establish connection over `connection_handle`.
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  }

  // Send Number_of_Completed_Packets event that reports 1 packet. Checks in
  // send_to_host_fn will ensure packet has been reclaimed.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy, {{kConnectionHandle, 1}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 1);
  // Since proxy reclaimed the one credit, it does not pass event on to host.
  EXPECT_EQ(capture.sends_called, 4);
}

TEST_F(DisconnectionCompleteTest, DisconnectionErasesAclConnection) {
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [](H4PacketWithHci&&) {});
  int sends_called = 0;
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&sends_called](H4PacketWithH4&&) { ++sends_called; });
  pw::allocator::test::AllocatorForTest<34000> allocator;
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              &allocator);
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));

  uint16_t connection_handle = 0x567;
  pw::Vector<L2capCoc, ProxyHost::GetMaxNumAclConnections()> channels;
  for (size_t i = 0; i < ProxyHost::GetMaxNumAclConnections(); ++i) {
    uint16_t handle = ++connection_handle;
    PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
        proxy, handle, emboss::StatusCode::SUCCESS));
    channels.push_back(BuildCoc(proxy, CocParameters{.handle = handle}));
  }
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, connection_handle + 1, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(
      BuildCocWithResult(
          proxy,
          CocParameters{.handle = static_cast<uint16_t>(connection_handle + 1)})
          .status(),
      Status::Unavailable());

  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, connection_handle++));
  // After erasing the last ACL connection, there should be space for a new one.
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, connection_handle, emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      L2capCoc channel,
      BuildCocWithResult(proxy, CocParameters{.handle = connection_handle}));
  // Confirm signaling channels are functional.
  PW_TEST_EXPECT_OK(channel.SendAdditionalRxCredits(3));
  RunDispatcher();

  EXPECT_EQ(sends_called, 1);
  channels.clear();
}

// ########## DestructionTest

class DestructionTest : public ProxyHostTest {};

// This test can deadlock on failure.
TEST_F(DestructionTest, CanDestructWhenPacketsQueuedInSignalingChannel) {
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [](H4PacketWithHci&&) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle2, emboss::StatusCode::SUCCESS));

  L2capCoc channel =
      BuildCoc(proxy, CocParameters{.handle = kConnectionHandle});
  L2capCoc channel2 =
      BuildCoc(proxy, CocParameters{.handle = kConnectionHandle2});

  PW_TEST_EXPECT_OK(channel.SendAdditionalRxCredits(1));
}

// ########## ResetTest

class ResetTest : public ProxyHostTest {};

TEST_F(ResetTest, ResetClearsActiveConnections) {
  struct {
    int sends_called = 0;
  } host_capture;
  struct {
    int sends_called = 0;
  } controller_capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&host_capture](H4PacketWithHci&& packet) {
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto event_header,
            MakeEmbossView<emboss::EventHeaderView>(packet.GetHciSpan().subspan(
                0, emboss::EventHeader::IntrinsicSizeInBytes())));
        host_capture.sends_called++;
        if (event_header.event_code().Read() !=
            emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS) {
          return;
        }

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto view,
            MakeEmbossView<emboss::NumberOfCompletedPacketsEventView>(
                packet.GetHciSpan()));
        EXPECT_EQ(packet.GetHciSpan().size(), 7ul);
        EXPECT_EQ(view.num_handles().Read(), 1);
        EXPECT_EQ(view.header().event_code().Read(),
                  emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);

        // Should be unchanged.
        EXPECT_EQ(view.nocp_data()[0].connection_handle().Read(),
                  kConnectionHandle);
        EXPECT_EQ(view.nocp_data()[0].num_completed_packets().Read(), 1);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&controller_capture]([[maybe_unused]] H4PacketWithH4&& packet) {
        ++controller_capture.sends_called;
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 2));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(host_capture.sends_called, 2);

  std::array<uint8_t, 1> attribute_value = {0};

  {
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(controller_capture.sends_called, 1);
  }

  proxy.Reset();

  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  // Reset should not have cleared `le_acl_credits_to_reserve`, so proxy should
  // still indicate the capability.
  EXPECT_TRUE(proxy.HasSendLeAclCapability());

  // Re-initialize AclDataChannel with 2 credits.
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 2));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle2, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(host_capture.sends_called, 4);

  {
    // Send ACL on random handle to expend one credit.
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle2});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(controller_capture.sends_called, 2);
  }

  // This should have no effect, as the reset has cleared our active connection
  // on this handle.
  PW_TEST_EXPECT_OK(
      SendNumberOfCompletedPackets(proxy, {{kConnectionHandle, 1}}));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 1);
  // NOCP has credits remaining so will be passed on to host.
  EXPECT_EQ(host_capture.sends_called, 5);
}

TEST_F(ResetTest, ProxyHandlesMultipleResets) {
  int sends_called = 0;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&sends_called]([[maybe_unused]] H4PacketWithH4&& packet) {
        ++sends_called;
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));

  proxy.Reset();
  proxy.Reset();

  std::array<uint8_t, 1> attribute_value = {0};
  // Validate state after double reset.
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  EXPECT_TRUE(proxy.HasSendLeAclCapability());
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  {
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
  }
  EXPECT_EQ(sends_called, 1);

  proxy.Reset();

  // Validate state after third reset.
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 0);
  EXPECT_TRUE(proxy.HasSendLeAclCapability());
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  {
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
  }
  EXPECT_EQ(sends_called, 2);
}

TEST_F(ResetTest, HandleHciReset) {
  struct {
    int sends_called = 0;
  } host_capture;
  struct {
    int sends_called = 0;
  } controller_capture;

  pw::Function<void(H4PacketWithHci&&)> send_to_host_fn(
      [&host_capture](H4PacketWithHci&&) { ++host_capture.sends_called; });
  pw::Function<void(H4PacketWithH4&&)> send_to_controller_fn(
      [&controller_capture](H4PacketWithH4&&) {
        ++controller_capture.sends_called;
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/2,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 2));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(host_capture.sends_called, 2);

  // Use 1 credit.
  std::array<uint8_t, 1> attribute_value = {0};
  GattNotifyChannel channel =
      BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
  multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
  PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
  RunDispatcher();
  EXPECT_EQ(controller_capture.sends_called, 1);
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 1);

  // Send HCI_Reset. This should cause proxy to reset and our free credits as
  // well.
  std::array<uint8_t, emboss::ResetCommandView::SizeInBytes() + 1>
      h4_array_from_host{};
  H4PacketWithH4 h4_packet_from_host{emboss::H4PacketType::UNKNOWN,
                                     h4_array_from_host};
  PW_TEST_EXPECT_OK(
      CreateAndPopulateToControllerView<emboss::ResetCommandWriter>(
          h4_packet_from_host,
          emboss::OpCode::RESET,
          /*parameter_total_size=*/0));
  proxy.HandleH4HciFromHost(std::move(h4_packet_from_host));

  // Send new buffer response which shouldn't crash.
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 2));
  EXPECT_EQ(host_capture.sends_called, 3);
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), 2);
}

// ########## MultiSendTest

class MultiSendTest : public ProxyHostTest {};

TEST_F(MultiSendTest, CanOccupyAllThenReuseEachBuffer) {
  constexpr uint8_t kAclCredits = 20;
  struct {
    size_t sends_called = 0;
    // These are packets that have been sent towards controller, but not
    // released yet by container.
    pw::Vector<H4PacketWithH4, 50> in_flight_packets{};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        // Capture all packets to prevent their destruction.
        capture.sends_called++;
        capture.in_flight_packets.push_back(std::move(packet));
      });

  allocator::test::AllocatorForTest<4096> allocator;
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/kAclCredits,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              &allocator);
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, kAclCredits));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  std::optional<GattNotifyChannel> channel =
      BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});

  std::array<uint8_t, 240> attribute_value = {};

  // Occupy all H4 buffers and queue 1 packet.
  size_t num_writes_0 = 0;
  do {
    auto mbuf_result = multibuf::FromSpan(
        allocator, as_writable_bytes(span(attribute_value)), [](ByteSpan) {});
    ASSERT_TRUE(mbuf_result.has_value());
    multibuf::MultiBuf mbuf = std::move(*mbuf_result);
    PW_TEST_EXPECT_OK(channel->Write(std::move(mbuf)).status);
    RunDispatcher();
    ++num_writes_0;
  } while (capture.sends_called == num_writes_0);
  // The final write should be queued and not sent.
  EXPECT_EQ(capture.sends_called, num_writes_0 - 1);

  // Release an H4 buffer, which should result in the queued packet being sent.
  // Move the packet first to avoid a push_back to in_flight_packets during a
  // pop_back.
  std::optional<H4PacketWithH4> last_packet =
      std::move(capture.in_flight_packets.back());
  capture.in_flight_packets.pop_back();
  last_packet.reset();
  RunDispatcher();
  EXPECT_EQ(capture.sends_called, num_writes_0);

  // Free up remaining slots.
  capture.in_flight_packets.clear();

  // There should have been no more sends since there were no payloads queued.
  EXPECT_EQ(capture.sends_called, num_writes_0);

  // Confirm we can now reoccupy each H4 buffer slot.
  size_t num_writes_1 = 0;
  capture.sends_called = 0;
  do {
    auto mbuf_result = multibuf::FromSpan(
        allocator, as_writable_bytes(span(attribute_value)), [](ByteSpan) {});
    ASSERT_TRUE(mbuf_result.has_value());
    multibuf::MultiBuf mbuf = std::move(*mbuf_result);
    PW_TEST_EXPECT_OK(channel->Write(std::move(mbuf)).status);
    RunDispatcher();
    ++num_writes_1;
  } while (capture.sends_called == num_writes_1);
  EXPECT_EQ(num_writes_0, num_writes_1);
  // The final write should be queued and not sent.
  EXPECT_EQ(capture.sends_called, num_writes_1 - 1);

  // Free all packets before destroying ProxyHost to avoid UAF.
  channel.reset();
  capture.in_flight_packets.clear();
}

TEST_F(MultiSendTest, CanRepeatedlyReuseOneBuffer) {
  constexpr size_t kAclBuffersSize = 10;
  struct {
    size_t sends_called = 0;
    // These are packets that have been sent towards controller, but not
    // released yet by container.
    pw::Vector<H4PacketWithH4, kAclBuffersSize> in_flight_packets{};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        ++capture.sends_called;
        capture.in_flight_packets.push_back(std::move(packet));
      });

  // Allow proxy to reserve enough credits for all the sends we do below.
  // simultaneous sends supported by proxy.
  constexpr size_t kTotalAclCredits = 2 * kAclBuffersSize;

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/kTotalAclCredits,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(
      SendLeReadBufferResponseFromController(proxy, kTotalAclCredits));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  GattNotifyChannel channel =
      BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});

  std::array<uint8_t, 1> attribute_value = {0xF};

  // Occupy all H4 buffers.
  for (size_t sent = 1; sent <= kAclBuffersSize; ++sent) {
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    // Each write is sent towards controller
    EXPECT_EQ(capture.sends_called, sent);
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), kTotalAclCredits - sent);
    // Container holds on to each H4 buffer.
    EXPECT_EQ(capture.in_flight_packets.size(), sent);
  }

  // This was already verified in last iteration of loop above, but we EXPECT
  // explicitly here to provide reader context for EXPECTs in the loop below.
  EXPECT_EQ(capture.sends_called, kAclBuffersSize);
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), kTotalAclCredits - kAclBuffersSize);
  EXPECT_EQ(capture.in_flight_packets.size(), kAclBuffersSize);

  // Repeatedly free and reoccupy last buffer.
  for (size_t sent = 1; sent <= kAclBuffersSize; ++sent) {
    capture.in_flight_packets.pop_back();
    // No send due to release of H4 buffer since no payloads were queued.
    EXPECT_EQ(capture.sends_called, kAclBuffersSize + sent - 1);
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(),
              kTotalAclCredits - kAclBuffersSize - (sent - 1));
    // In flight packets has one free slot (which should align with one free H4
    // buffer slot).
    EXPECT_EQ(capture.in_flight_packets.size(), kAclBuffersSize - 1);

    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();

    // Send happened using that one free H4 buffer slot.
    EXPECT_EQ(capture.sends_called, kAclBuffersSize + sent);
    EXPECT_EQ(proxy.GetNumFreeLeAclPackets(),
              kTotalAclCredits - kAclBuffersSize - sent);
    // In flight packets full again, which should align with H4
    // buffers being full.
    EXPECT_EQ(capture.in_flight_packets.size(), kAclBuffersSize);
  }

  // If captured packets are not reset here, they may destruct after the proxy
  // and lead to a crash when trying to lock the proxy's destructed mutex.
  capture.in_flight_packets.clear();
}

TEST_F(MultiSendTest, CanSendOverManyDifferentConnections) {
  std::array<uint8_t, 1> attribute_value = {0xF};
  struct {
    uint16_t sends_called = 0;
  } capture;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&capture]([[maybe_unused]] H4PacketWithH4&& packet) {
        ++capture.sends_called;
      });

  pw::allocator::test::AllocatorForTest<32768> allocator;
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              ProxyHost::GetMaxNumAclConnections(),
                              /*br_edr_acl_credits_to_reserve=*/0,
                              &allocator);
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(
      proxy, ProxyHost::GetMaxNumAclConnections()));

  for (uint16_t send = 1; send <= ProxyHost::GetMaxNumAclConnections();
       send++) {
    // Use current send count as the connection handle.
    uint16_t conn_handle = send;
    PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
        proxy, conn_handle, emboss::StatusCode::SUCCESS));
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = conn_handle});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(capture.sends_called, send);
  }
}

TEST_F(MultiSendTest, AttemptToCreateOverMaxConnectionsFails) {
  constexpr uint16_t kSends = ProxyHost::GetMaxNumAclConnections() + 1;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::allocator::test::AllocatorForTest<34000> allocator;
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/kSends,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              &allocator);
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, kSends));

  std::vector<GattNotifyChannel> channels;

  for (uint16_t send = 1; send <= ProxyHost::GetMaxNumAclConnections();
       send++) {
    // Use current send count as the connection handle.
    uint16_t conn_handle = send;
    PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
        proxy, conn_handle, emboss::StatusCode::SUCCESS));
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = conn_handle});
    channels.push_back(std::move(channel));
  }

  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, /*handle=*/kSends, emboss::StatusCode::SUCCESS));
  // Last one should fail
  EXPECT_EQ(
      BuildGattNotifyChannelWithResult(proxy, {.handle = kSends}).status(),
      Status::Unavailable());
}

// ########## BasicL2capChannelTest

class BasicL2capChannelTest : public ProxyHostTest {};

TEST_F(BasicL2capChannelTest, BasicWrite) {
  struct {
    int sends_called = 0;
    // First four bits 0x0 encode PB & BC flags
    uint16_t handle = 0x0ACB;
    // Length of L2CAP PDU
    uint16_t acl_data_total_length = 0x0007;
    // L2CAP header PDU length field
    uint16_t pdu_length = 0x0003;
    // Random CID
    uint16_t channel_id = 0x1234;
    // L2CAP information payload
    std::array<uint8_t, 3> payload = {0xAB, 0xCD, 0xEF};

    // Built from the preceding values in little endian order (except payload in
    // big endian).
    std::array<uint8_t, 11> expected_hci_packet = {
        0xCB, 0x0A, 0x07, 0x00, 0x03, 0x00, 0x34, 0x12, 0xAB, 0xCD, 0xEF};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        ++capture.sends_called;
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::ACL_DATA);
        EXPECT_EQ(packet.GetHciSpan().size(),
                  capture.expected_hci_packet.size());
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               capture.expected_hci_packet.begin(),
                               capture.expected_hci_packet.end()));
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto acl,
            MakeEmbossView<emboss::AclDataFrameView>(packet.GetHciSpan()));
        EXPECT_EQ(acl.header().handle().Read(), capture.handle);
        EXPECT_EQ(acl.header().packet_boundary_flag().Read(),
                  emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
        EXPECT_EQ(acl.header().broadcast_flag().Read(),
                  emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
        EXPECT_EQ(acl.data_total_length().Read(),
                  capture.acl_data_total_length);
        emboss::BFrameView bframe = emboss::MakeBFrameView(
            acl.payload().BackingStorage().data(), acl.SizeInBytes());
        EXPECT_EQ(bframe.pdu_length().Read(), capture.pdu_length);
        EXPECT_EQ(bframe.channel_id().Read(), capture.channel_id);
        for (size_t i = 0; i < 3; ++i) {
          EXPECT_EQ(bframe.payload()[i].Read(), capture.payload[i]);
        }
      });

  auto* allocator = GetProxyHostAllocator();
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              allocator);
  StartDispatcherOnCurrentThread(proxy);
  // Allow proxy to reserve 1 LE credit.
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.handle, emboss::StatusCode::SUCCESS));

  BasicL2capChannel channel =
      BuildBasicL2capChannel(proxy,
                             {.handle = capture.handle,
                              .local_cid = 0x123,
                              .remote_cid = capture.channel_id,
                              .transport = AclTransportType::kLe});

  auto mbuf_result = multibuf::FromSpan(
      *allocator, as_writable_bytes(span(capture.payload)), [](ByteSpan) {});
  ASSERT_TRUE(mbuf_result.has_value());
  multibuf::MultiBuf mbuf = std::move(*mbuf_result);
  PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
  RunDispatcher();
  EXPECT_EQ(capture.sends_called, 1);
}

TEST_F(BasicL2capChannelTest, ErrorOnWriteTooLarge) {
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [](H4PacketWithHci&&) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) { FAIL(); });

  auto* allocator = GetProxyHostAllocator();
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              allocator);
  StartDispatcherOnCurrentThread(proxy);
  // Allow proxy to reserve 1 credit.
  const uint16_t kAclDataPacketLength = 100;
  PW_TEST_EXPECT_OK(SendReadBufferResponseFromController(
      proxy, /*num_credits_to_reserve=*/1, kAclDataPacketLength));
  PW_TEST_ASSERT_OK(SendConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  std::array<uint8_t,
             kAclDataPacketLength -
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() + 1>
      one_byte_too_big_sdu;

  BasicL2capChannel channel =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = 0x123,
                              .remote_cid = 0x123,
                              .transport = AclTransportType::kBrEdr});

  auto mbuf_result = multibuf::FromSpan(
      *allocator, as_writable_bytes(span(one_byte_too_big_sdu)), [](ByteSpan) {
      });
  ASSERT_TRUE(mbuf_result.has_value());
  multibuf::MultiBuf mbuf = std::move(*mbuf_result);
  EXPECT_EQ(channel.Write(std::move(mbuf)).status, Status::InvalidArgument());
  RunDispatcher();
}

TEST_F(BasicL2capChannelTest, CannotCreateChannelWithInvalidArgs) {
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [](H4PacketWithHci&&) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  // Connection handle too large by 1.
  Result<BasicL2capChannel> channel =
      BuildBasicL2capChannelWithResult(proxy,
                                       {.handle = 0x0FFF,
                                        .local_cid = 0x123,
                                        .remote_cid = 0x123,
                                        .transport = AclTransportType::kLe});
  EXPECT_EQ(channel.status(), Status::InvalidArgument());

  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  // Local CID invalid (0).
  channel =
      BuildBasicL2capChannelWithResult(proxy,
                                       BasicL2capParameters{
                                           .handle = kConnectionHandle,
                                           .local_cid = 0,
                                           .remote_cid = 0x123,
                                           .transport = AclTransportType::kLe,
                                       });
  EXPECT_EQ(channel.status(), Status::InvalidArgument());
}

TEST_F(BasicL2capChannelTest, BasicRead) {
  struct {
    int sends_called = 0;
    int to_host_called = 0;
    std::array<uint8_t, 3> expected_payload = {0xAB, 0xCD, 0xEF};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        if (packet.GetH4Type() == emboss::H4PacketType::ACL_DATA) {
          ++capture.to_host_called;
        }
      });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  uint16_t handle = 334;
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, handle, emboss::StatusCode::SUCCESS));

  uint16_t local_cid = 443;
  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = handle,
          .local_cid = local_cid,
          .remote_cid = 0x123,
          .transport = AclTransportType::kLe,
          .payload_from_controller_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                ++capture.sends_called;
                PW_ASSERT(!buffer.empty());
                ConstByteSpan payload = *buffer.ConstChunks().begin();
                ConstByteSpan expected_bytes =
                    as_bytes(span(capture.expected_payload.data(),
                                  capture.expected_payload.size()));
                EXPECT_TRUE(std::equal(payload.begin(),
                                       payload.end(),
                                       expected_bytes.begin(),
                                       expected_bytes.end()));
                return std::nullopt;
              },
      });

  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 capture.expected_payload.size()>
      hci_arr;
  hci_arr.fill(0);
  H4PacketWithHci h4_packet{emboss::H4PacketType::ACL_DATA, hci_arr};

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_arr);
  acl->header().handle().Write(handle);
  acl->data_total_length().Write(
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      capture.expected_payload.size());

  emboss::BFrameWriter bframe = emboss::MakeBFrameView(
      acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
  bframe.pdu_length().Write(capture.expected_payload.size());
  bframe.channel_id().Write(local_cid);
  std::copy(capture.expected_payload.begin(),
            capture.expected_payload.end(),
            hci_arr.begin() +
                emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                emboss::BasicL2capHeader::IntrinsicSizeInBytes());

  // Send ACL data packet destined for the CoC we registered.
  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(capture.sends_called, 1);
  EXPECT_EQ(capture.to_host_called, 0);
}

TEST_F(BasicL2capChannelTest, BasicForward) {
  struct {
    int sends_called = 0;
    int to_host_called = 0;
    std::array<uint8_t, 3> expected_payload = {0xAB, 0xCD, 0xEF};
    std::array<uint8_t,
               emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                   emboss::BasicL2capHeader::IntrinsicSizeInBytes() + 3>
        hci_arr{};
  } capture;

  H4PacketWithHci h4_packet{emboss::H4PacketType::ACL_DATA, capture.hci_arr};

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        if (packet.GetH4Type() != emboss::H4PacketType::ACL_DATA) {
          return;
        }
        ++capture.to_host_called;
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               capture.hci_arr.begin(),
                               capture.hci_arr.end()));
      });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  uint16_t handle = 334;
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, handle, emboss::StatusCode::SUCCESS));

  uint16_t local_cid = 443;
  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = handle,
          .local_cid = local_cid,
          .remote_cid = 0x123,
          .transport = AclTransportType::kLe,
          .payload_from_controller_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                ++capture.sends_called;
                // Forward to host.
                return multibuf::MultiBuf(std::move(buffer));
              },
      });

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(capture.hci_arr);
  acl->header().handle().Write(handle);
  acl->data_total_length().Write(
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      capture.expected_payload.size());

  emboss::BFrameWriter bframe = emboss::MakeBFrameView(
      acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
  bframe.pdu_length().Write(capture.expected_payload.size());
  bframe.channel_id().Write(local_cid);
  std::copy(capture.expected_payload.begin(),
            capture.expected_payload.end(),
            capture.hci_arr.begin() +
                emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                emboss::BasicL2capHeader::IntrinsicSizeInBytes());

  // Send ACL data packet destined for the CoC we registered.
  proxy.HandleH4HciFromController(std::move(h4_packet));

  EXPECT_EQ(capture.sends_called, 1);
  EXPECT_EQ(capture.to_host_called, 1);
}

TEST_F(BasicL2capChannelTest, ReadPacketToController) {
  struct {
    int sends_called = 0;
    int from_host_called = 0;
    std::array<uint8_t, 3> expected_payload = {0xAB, 0xCD, 0xEF};
    std::array<uint8_t,
               emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                   emboss::BasicL2capHeader::IntrinsicSizeInBytes() + 3>
        hci_arr{};
  } capture;

  std::array<uint8_t, sizeof(emboss::H4PacketType) + capture.hci_arr.size()>
      h4_arr;
  h4_arr[0] = cpp23::to_underlying(emboss::H4PacketType::ACL_DATA);
  H4PacketWithH4 h4_packet{h4_arr};

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [](H4PacketWithHci&&) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        ++capture.from_host_called;
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               capture.hci_arr.begin(),
                               capture.hci_arr.end()));
      });
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  uint16_t handle = 0x334;
  PW_TEST_ASSERT_OK(
      SendConnectionCompleteEvent(proxy, handle, emboss::StatusCode::SUCCESS));
  uint16_t local_cid = 0x443;
  uint16_t remote_cid = 0x123;
  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = handle,
          .local_cid = local_cid,
          .remote_cid = remote_cid,
          .transport = AclTransportType::kBrEdr,
          .payload_from_host_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                ++capture.sends_called;
                return multibuf::MultiBuf(std::move(buffer));
              },
      });

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(capture.hci_arr);
  acl->header().handle().Write(handle);
  acl->data_total_length().Write(
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      capture.expected_payload.size());

  emboss::BasicL2capHeaderWriter l2cap_header =
      emboss::MakeBasicL2capHeaderView(
          acl->payload().BackingStorage().data(),
          acl->payload().BackingStorage().SizeInBytes());
  l2cap_header.pdu_length().Write(capture.expected_payload.size());
  l2cap_header.channel_id().Write(remote_cid);

  std::copy(capture.expected_payload.begin(),
            capture.expected_payload.end(),
            capture.hci_arr.begin() +
                emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                emboss::BasicL2capHeader::IntrinsicSizeInBytes());

  std::copy(capture.hci_arr.begin(), capture.hci_arr.end(), h4_arr.begin() + 1);

  proxy.HandleH4HciFromHost(std::move(h4_packet));

  EXPECT_EQ(capture.from_host_called, 1);
  EXPECT_EQ(capture.sends_called, 1);
}

TEST_F(BasicL2capChannelTest, BasicModifyForwardToHost) {
  struct {
    int from_controller_called = 0;
    int to_host_called = 0;
    std::array<uint8_t, 3> expected_payload_to_host = {0xAB, 0xCD, 0xEF};
    std::array<uint8_t, 3> payload_from_controller = {0xDE, 0xAD, 0xBE};
    std::array<uint8_t,
               emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                   emboss::BasicL2capHeader::IntrinsicSizeInBytes() + 3>
        hci_arr{};
  } capture;

  H4PacketWithHci h4_packet{emboss::H4PacketType::ACL_DATA, capture.hci_arr};

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        if (packet.GetH4Type() != emboss::H4PacketType::ACL_DATA) {
          return;
        }
        ++capture.to_host_called;
        auto offset = emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                      emboss::BasicL2capHeader::IntrinsicSizeInBytes();
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin() + offset,
                               packet.GetHciSpan().end(),
                               capture.expected_payload_to_host.begin(),
                               capture.expected_payload_to_host.end()));
      });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  uint16_t handle = 334;
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, handle, emboss::StatusCode::SUCCESS));

  uint16_t local_cid = 443;
  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = handle,
          .local_cid = local_cid,
          .remote_cid = 0x123,
          .transport = AclTransportType::kLe,
          .payload_from_controller_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                ++capture.from_controller_called;
                PW_ASSERT(!buffer.empty());
                // Forward to host.
                ByteSpan payload = buffer.ContiguousSpan().value();
                ConstByteSpan modified_bytes =
                    as_bytes(span(capture.expected_payload_to_host.data(),
                                  capture.expected_payload_to_host.size()));

                std::copy(modified_bytes.begin(),
                          modified_bytes.end(),
                          payload.begin());
                return multibuf::MultiBuf(std::move(buffer));
              },
      });

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(capture.hci_arr);
  acl->header().handle().Write(handle);
  acl->data_total_length().Write(
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      capture.payload_from_controller.size());

  emboss::BFrameWriter bframe = emboss::MakeBFrameView(
      acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
  bframe.pdu_length().Write(capture.payload_from_controller.size());
  bframe.channel_id().Write(local_cid);
  std::copy(capture.payload_from_controller.begin(),
            capture.payload_from_controller.end(),
            capture.hci_arr.begin() +
                emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                emboss::BasicL2capHeader::IntrinsicSizeInBytes());

  // Send ACL data packet destined for the CoC we registered.
  proxy.HandleH4HciFromController(std::move(h4_packet));
  EXPECT_EQ(capture.from_controller_called, 1);
  EXPECT_EQ(capture.to_host_called, 1);
}

TEST_F(BasicL2capChannelTest, BasicModifyForwardToController) {
  struct {
    int from_host_called = 0;
    int to_controller_called = 0;
    std::array<uint8_t, 3> expected_payload_to_controller = {0xAB, 0xCD, 0xEF};
    std::array<uint8_t, 3> payload_from_host = {0xDE, 0xAD, 0xBE};
    std::array<uint8_t,
               emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                   emboss::BasicL2capHeader::IntrinsicSizeInBytes() + 3>
        hci_arr{};
  } capture;

  std::array<uint8_t, sizeof(emboss::H4PacketType) + capture.hci_arr.size()>
      h4_arr;
  h4_arr[0] = cpp23::to_underlying(emboss::H4PacketType::ACL_DATA);
  H4PacketWithH4 h4_packet{h4_arr};

  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        if (packet.GetH4Type() != emboss::H4PacketType::ACL_DATA) {
          return;
        }
        ++capture.to_controller_called;
        auto offset = emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                      emboss::BasicL2capHeader::IntrinsicSizeInBytes();
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin() + offset,
                               packet.GetHciSpan().end(),
                               capture.expected_payload_to_controller.begin(),
                               capture.expected_payload_to_controller.end()));
      });
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [](H4PacketWithHci&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  uint16_t handle = 334;
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, handle, emboss::StatusCode::SUCCESS));

  uint16_t local_cid = 443;
  uint16_t remote_cid = 0x123;

  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = handle,
          .local_cid = local_cid,
          .remote_cid = 0x123,
          .transport = AclTransportType::kLe,
          .payload_from_host_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                ++capture.from_host_called;
                PW_ASSERT(!buffer.empty());
                // Forward to host.
                ByteSpan payload = buffer.ContiguousSpan().value();
                ConstByteSpan modified_bytes = as_bytes(
                    span(capture.expected_payload_to_controller.data(),
                         capture.expected_payload_to_controller.size()));

                std::copy(modified_bytes.begin(),
                          modified_bytes.end(),
                          payload.begin());
                return multibuf::MultiBuf(std::move(buffer));
              },
      });

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(capture.hci_arr);
  acl->header().handle().Write(handle);
  acl->data_total_length().Write(
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      capture.payload_from_host.size());

  emboss::BasicL2capHeaderWriter l2cap_header =
      emboss::MakeBasicL2capHeaderView(
          acl->payload().BackingStorage().data(),
          acl->payload().BackingStorage().SizeInBytes());
  l2cap_header.pdu_length().Write(capture.payload_from_host.size());
  l2cap_header.channel_id().Write(remote_cid);

  std::copy(capture.payload_from_host.begin(),
            capture.payload_from_host.end(),
            capture.hci_arr.begin() +
                emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                emboss::BasicL2capHeader::IntrinsicSizeInBytes());

  std::copy(capture.hci_arr.begin(), capture.hci_arr.end(), h4_arr.begin() + 1);
  proxy.HandleH4HciFromHost(std::move(h4_packet));

  EXPECT_EQ(capture.from_host_called, 1);
  EXPECT_EQ(capture.to_controller_called, 1);
}

// TODO: https://pwbug.dev/365161669 - Disable test at build-level once
// joinability is a build-system constraint.
#if PW_THREAD_JOINING_ENABLED
// Have multiple threads write to a BasicL2cap channel. Verify all resulting ACL
// packets are sent towards controller in the correct order per channel.
// This test be run repetitively with googletest by using:
// clang-format off
// bazelisk --config=googletest //pw_bluetooth_proxy:pw_bluetooth_proxy_test --
//   --gtest_filter=BasicL2capChannelTest.MultithreadedWrite --gtest_repeat=1000
// clang-format on
TEST_F(BasicL2capChannelTest, MultithreadedWrite) {
  constexpr unsigned int kNumThreads = 40;
  constexpr unsigned int kPacketsPerThread =
      L2capChannel::QueueCapacity() - NumBufferedPayloads();

  constexpr uint16_t kBaseLocalCid = 0xb000;   // 176
  constexpr uint16_t kBaseRemoteCid = 0xc000;  // 192
  constexpr uint16_t kPayloadSize = 10;

  struct {
    const uint16_t kExpectedPduLength = kPayloadSize;
    const uint16_t kTestHandle = 0xaa;  // 170
    const uint16_t kExpectedAclDataTotalLength =
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() + kExpectedPduLength;
    sync::Mutex sends_by_channel_mutex;
    std::array<unsigned int, kNumThreads> sends_by_channel
        PW_GUARDED_BY(sends_by_channel_mutex){};
  } capture;

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::ACL_DATA);
        EXPECT_EQ(packet.GetHciSpan().size(),
                  static_cast<unsigned long>(
                      emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                      capture.kExpectedAclDataTotalLength));

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto acl,
            MakeEmbossView<emboss::AclDataFrameView>(packet.GetHciSpan()));
        EXPECT_EQ(acl.header().handle().Read(), capture.kTestHandle);
        EXPECT_EQ(acl.header().packet_boundary_flag().Read(),
                  emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
        EXPECT_EQ(acl.header().broadcast_flag().Read(),
                  emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
        EXPECT_EQ(acl.data_total_length().Read(),
                  capture.kExpectedAclDataTotalLength);

        PW_TEST_ASSERT_OK_AND_ASSIGN(
            emboss::BFrameView bframe,
            MakeEmbossView<emboss::BFrameView>(
                acl.payload().BackingStorage().data(), acl.SizeInBytes()));

        EXPECT_EQ(bframe.pdu_length().Read(), capture.kExpectedPduLength);

        // Each channel's remote cid has the thread index as its LSB.
        uint16_t current_remote_cid = bframe.channel_id().Read();
        unsigned int current_thread_id = current_remote_cid & ~kBaseRemoteCid;
        {
          std::lock_guard lock(capture.sends_by_channel_mutex);

          // Each payload byte should match the send count (to verify ordering).
          for (size_t i = 0; i < kPayloadSize; ++i) {
            EXPECT_EQ(bframe.payload()[i].Read(),
                      capture.sends_by_channel[current_thread_id]);
          }
          capture.sends_by_channel[current_thread_id]++;
        }
      });

  allocator::test::AllocatorForTest<65536> allocator;
  // Use libc allocators so msan can detect use after frees.
  std::array<std::byte, 200 * 1024> packet_buffer{};
  pw::multibuf::SimpleAllocator multibuf_allocator{
      /*data_area=*/packet_buffer,
      /*metadata_alloc=*/allocator::GetLibCAllocator()};

  ProxyHost proxy =
      ProxyHost(std::move(send_to_host_fn),
                std::move(send_to_controller_fn),
                /*le_acl_credits_to_reserve=*/kNumThreads * kPacketsPerThread,
                /*br_edr_acl_credits_to_reserve=*/0,
                &allocator);

  // If using async, start a dispatcher thread.
  StartDispatcherOnNewThread(proxy);

  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(
      proxy, kNumThreads * kPacketsPerThread));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, capture.kTestHandle, emboss::StatusCode::SUCCESS));

  struct ThreadCapture {
    BasicL2capChannel channel;
    multibuf::MultiBufAllocator& packet_allocator;
  };

  pw::Vector<ThreadCapture, kNumThreads> captures;
  pw::thread::test::TestThreadContext context;
  pw::Vector<pw::Thread, kNumThreads> threads;

  for (unsigned int i = 0; i < kNumThreads; ++i) {
    uint16_t local_cid = static_cast<uint16_t>(kBaseLocalCid + i);
    // Each channel's remote cid has the thread index as its LSB. That is
    // used to track packet ordering per channel.
    uint16_t remote_cid = static_cast<uint16_t>(kBaseRemoteCid + i);
    // TODO: https://pwbug.dev/422222575 -  Move channel creation, close, and
    // destruction inside each thread once we have proper channel lifecycle
    // locking.
    ThreadCapture thread_capture{
        BuildBasicL2capChannel(
            proxy,
            BasicL2capParameters{.handle = capture.kTestHandle,
                                 .local_cid = local_cid,
                                 .remote_cid = remote_cid}),
        multibuf_allocator,
    };
    captures.emplace_back(std::move(thread_capture));
  }

  for (unsigned int thread_numb = 0; thread_numb < kNumThreads; ++thread_numb) {
    ThreadCapture& thread_capture = captures[thread_numb];
    threads.emplace_back(context.options(), [&thread_capture]() {
      for (unsigned int packet_numb = 0; packet_numb < kPacketsPerThread;
           ++packet_numb) {
        auto mbuf_result =
            thread_capture.packet_allocator.AllocateContiguous(kPayloadSize);
        ASSERT_TRUE(mbuf_result.has_value());
        multibuf::MultiBuf mbuf_inst = std::move(*mbuf_result);
        std::fill(mbuf_inst.begin(),
                  mbuf_inst.end(),
                  static_cast<std::byte>(packet_numb));
        PW_TEST_EXPECT_OK(
            thread_capture.channel.Write(std::move(mbuf_inst)).status);
      }
    });
  }

  // Ensure the writer threads complete, drop the channels, and ensure the
  // dispatcher thread completes.
  for (auto& t : threads) {
    t.join();
  }
  captures.clear();
  JoinDispatcherThread();

  {
    std::lock_guard lock(capture.sends_by_channel_mutex);
    for (unsigned int i = 0; i < kNumThreads; ++i) {
      EXPECT_EQ(capture.sends_by_channel[i], kPacketsPerThread);
    }
  }
}
#endif  // PW_THREAD_JOINING_ENABLED

// ########## L2capSignalingTest

class L2capSignalingTest : public ProxyHostTest {};

TEST_F(L2capSignalingTest, FlowControlCreditIndDrainsQueue) {
  size_t sends_called = 0;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [&sends_called]([[maybe_unused]] H4PacketWithH4&& packet) {
        ++sends_called;
      });
  ProxyHost proxy =
      ProxyHost(std::move(send_to_host_fn),
                std::move(send_to_controller_fn),
                /*le_acl_credits_to_reserve=*/L2capCoc::QueueCapacity(),
                /*br_edr_acl_credits_to_reserve=*/0,
                GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_EXPECT_OK(
      SendLeReadBufferResponseFromController(proxy, L2capCoc::QueueCapacity()));
  EXPECT_EQ(proxy.GetNumFreeLeAclPackets(), L2capCoc::QueueCapacity());

  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  uint16_t remote_cid = 456;
  L2capCoc channel = BuildCoc(proxy,
                              CocParameters{.handle = kConnectionHandle,
                                            .remote_cid = remote_cid,
                                            .tx_credits = 0});

  for (size_t i = 0; i < L2capCoc::QueueCapacity(); ++i) {
    multibuf::MultiBuf empty = MakeEmptyMultiBuf();
    PW_TEST_EXPECT_OK(channel.Write(std::move(empty)).status);
    RunDispatcher();
  }
  multibuf::MultiBuf empty = MakeEmptyMultiBuf();
  EXPECT_EQ(channel.Write(std::move(empty)).status, Status::Unavailable());
  RunDispatcher();
  EXPECT_EQ(sends_called, 0u);

  constexpr size_t kL2capLength =
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes();
  constexpr size_t kHciLength =
      emboss::AclDataFrame::MinSizeInBytes() + kL2capLength;
  std::array<uint8_t, kHciLength> hci_arr;
  hci_arr.fill(0);
  H4PacketWithHci flow_control_credit_ind{emboss::H4PacketType::ACL_DATA,
                                          pw::span(hci_arr.data(), kHciLength)};

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_arr);
  acl->header().handle().Write(kConnectionHandle);
  acl->data_total_length().Write(kL2capLength);

  emboss::CFrameWriter l2cap = emboss::MakeCFrameView(
      acl->payload().BackingStorage().data(), kL2capLength);
  l2cap.pdu_length().Write(
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
  // 0x0005 = LE-U fixed signaling channel ID.
  l2cap.channel_id().Write(0x0005);

  emboss::L2capFlowControlCreditIndWriter ind =
      emboss::MakeL2capFlowControlCreditIndView(
          l2cap.payload().BackingStorage().data(),
          emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
  ind.command_header().code().Write(
      emboss::L2capSignalingPacketCode::FLOW_CONTROL_CREDIT_IND);
  ind.command_header().data_length().Write(
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes() -
      emboss::L2capSignalingCommandHeader::IntrinsicSizeInBytes());
  ind.cid().Write(remote_cid);
  ind.credits().Write(L2capCoc::QueueCapacity());

  proxy.HandleH4HciFromController(std::move(flow_control_credit_ind));
  RunDispatcher();
  EXPECT_EQ(sends_called, L2capCoc::QueueCapacity());
}

TEST_F(L2capSignalingTest, ChannelClosedWithErrorIfCreditsExceeded) {
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy =
      ProxyHost(std::move(send_to_host_fn),
                std::move(send_to_controller_fn),
                /*le_acl_credits_to_reserve=*/L2capCoc::QueueCapacity(),
                /*br_edr_acl_credits_to_reserve=*/0,
                GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  uint16_t remote_cid = 456;
  int events_received = 0;
  L2capCoc channel = BuildCoc(
      proxy,
      CocParameters{
          .handle = kConnectionHandle,
          .remote_cid = remote_cid,
          // Initialize with max credit count.
          .tx_credits =
              emboss::L2capLeCreditBasedConnectionReq::max_credit_value(),
          .event_fn = [&events_received](L2capChannelEvent event) {
            EXPECT_EQ(event, L2capChannelEvent::kRxInvalid);
            ++events_received;
          }});

  constexpr size_t kL2capLength =
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes();
  constexpr size_t kHciLength =
      emboss::AclDataFrame::MinSizeInBytes() + kL2capLength;
  std::array<uint8_t, kHciLength> hci_arr;
  hci_arr.fill(0);
  H4PacketWithHci flow_control_credit_ind{emboss::H4PacketType::ACL_DATA,
                                          pw::span(hci_arr.data(), kHciLength)};

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_arr);
  acl->header().handle().Write(kConnectionHandle);
  acl->data_total_length().Write(kL2capLength);

  emboss::CFrameWriter l2cap =
      emboss::MakeCFrameView(acl->payload().BackingStorage().data(),
                             emboss::BasicL2capHeader::IntrinsicSizeInBytes());
  l2cap.pdu_length().Write(
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
  // 0x0005 = LE-U fixed signaling channel ID.
  l2cap.channel_id().Write(0x0005);

  emboss::L2capFlowControlCreditIndWriter ind =
      emboss::MakeL2capFlowControlCreditIndView(
          l2cap.payload().BackingStorage().data(),
          emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
  ind.command_header().code().Write(
      emboss::L2capSignalingPacketCode::FLOW_CONTROL_CREDIT_IND);
  ind.command_header().data_length().Write(
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes() -
      emboss::L2capSignalingCommandHeader::IntrinsicSizeInBytes());
  ind.cid().Write(remote_cid);
  // Exceed max credit count by 1.
  ind.credits().Write(1);

  proxy.HandleH4HciFromController(std::move(flow_control_credit_ind));

  EXPECT_EQ(events_received, 1);
}

TEST_F(L2capSignalingTest, SignalsArePassedOnToHost) {
  int forwards_to_host = 0;
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&forwards_to_host](H4PacketWithHci&&) { ++forwards_to_host; });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  EXPECT_EQ(forwards_to_host, 0);

  PW_TEST_EXPECT_OK(
      SendL2capConnectionReq(proxy, Direction::kFromController, 44, 55, 56));
  EXPECT_EQ(forwards_to_host, 1);
}

TEST_F(L2capSignalingTest, SignalsArePassedOnToHostAfterAclDisconnect) {
  int sends_to_host = 0;
  int sends_to_controller = 0;
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&sends_to_host](H4PacketWithHci&&) { ++sends_to_host; });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [&sends_to_controller](H4PacketWithH4&&) { ++sends_to_controller; });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  // Allow proxy to reserve 1 credit.
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(sends_to_host, 2);

  std::array<uint8_t, 1> attribute_value = {0};
  {
    GattNotifyChannel channel =
        BuildGattNotifyChannel(proxy, {.handle = kConnectionHandle});
    multibuf::MultiBuf mbuf = MultiBufFromArray(attribute_value);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
  }
  EXPECT_EQ(sends_to_controller, 1);

  // Disconnect that connection.
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, kConnectionHandle));
  EXPECT_EQ(sends_to_host, 3);

  // Send signal again using the same connection. Signal should be passed on
  // to host.
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromController, kConnectionHandle, 55, 56));
  EXPECT_EQ(sends_to_host, 4);

  // Trigger credit send for L2capCoc to verify new signalling channel
  // object is present and working.
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  {
    L2capCoc channel =
        BuildCoc(proxy, CocParameters{.handle = kConnectionHandle});
    PW_TEST_EXPECT_OK(channel.SendAdditionalRxCredits(7));
    RunDispatcher();
  }
  EXPECT_EQ(sends_to_controller, 2);
}

TEST_F(L2capSignalingTest,
       CreditIndAddressedToNonManagedChannelForwardedToHost) {
  int forwards_to_host = 0;
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&forwards_to_host](H4PacketWithHci&&) { ++forwards_to_host; });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});

  ProxyHost proxy =
      ProxyHost(std::move(send_to_host_fn),
                std::move(send_to_controller_fn),
                /*le_acl_credits_to_reserve=*/L2capCoc::QueueCapacity(),
                /*br_edr_acl_credits_to_reserve=*/0,
                GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(forwards_to_host, 1);

  uint16_t remote_cid = 456;
  L2capCoc channel = BuildCoc(
      proxy,
      CocParameters{.handle = kConnectionHandle, .remote_cid = remote_cid});

  constexpr size_t kL2capLength =
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes();
  constexpr size_t kHciLength =
      emboss::AclDataFrame::MinSizeInBytes() + kL2capLength;
  std::array<uint8_t, kHciLength> hci_arr;
  hci_arr.fill(0);
  H4PacketWithHci flow_control_credit_ind{emboss::H4PacketType::ACL_DATA,
                                          pw::span(hci_arr.data(), kHciLength)};

  Result<emboss::AclDataFrameWriter> acl =
      MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_arr);
  acl->header().handle().Write(kConnectionHandle);
  acl->data_total_length().Write(kL2capLength);

  emboss::CFrameWriter l2cap =
      emboss::MakeCFrameView(acl->payload().BackingStorage().data(),
                             emboss::BasicL2capHeader::IntrinsicSizeInBytes());
  l2cap.pdu_length().Write(
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
  // 0x0005 = LE-U fixed signaling channel ID.
  l2cap.channel_id().Write(0x0005);

  emboss::L2capFlowControlCreditIndWriter ind =
      emboss::MakeL2capFlowControlCreditIndView(
          l2cap.payload().BackingStorage().data(),
          emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
  ind.command_header().code().Write(
      emboss::L2capSignalingPacketCode::FLOW_CONTROL_CREDIT_IND);
  ind.command_header().data_length().Write(
      emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes() -
      emboss::L2capSignalingCommandHeader::IntrinsicSizeInBytes());
  // Address packet to different CID on same connection.
  ind.cid().Write(remote_cid + 1);

  proxy.HandleH4HciFromController(std::move(flow_control_credit_ind));

  EXPECT_EQ(forwards_to_host, 2);
}

TEST_F(L2capSignalingTest, RxAdditionalCreditsSent) {
  struct {
    uint16_t local_cid = 456;
    uint16_t credits = 3;
    int sends_called = 0;
  } capture;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [](H4PacketWithHci&&) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        ++capture.sends_called;
        PW_TEST_ASSERT_OK_AND_ASSIGN(
            auto acl,
            MakeEmbossView<emboss::AclDataFrameView>(packet.GetHciSpan()));
        EXPECT_EQ(acl.header().handle().Read(), kConnectionHandle);
        EXPECT_EQ(
            acl.data_total_length().Read(),
            emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
        emboss::CFrameView cframe = emboss::MakeCFrameView(
            acl.payload().BackingStorage().data(), acl.payload().SizeInBytes());
        EXPECT_EQ(cframe.pdu_length().Read(),
                  emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes());
        // 0x0005 = LE-U fixed signaling channel ID.
        EXPECT_EQ(cframe.channel_id().Read(), 0x0005);
        emboss::L2capFlowControlCreditIndView ind =
            emboss::MakeL2capFlowControlCreditIndView(
                cframe.payload().BackingStorage().data(),
                cframe.payload().SizeInBytes());
        EXPECT_EQ(ind.command_header().code().Read(),
                  emboss::L2capSignalingPacketCode::FLOW_CONTROL_CREDIT_IND);
        // TODO: https://pwbug.dev/382553099 - Test to ensure we are properly
        // incrementing Identifier when sending multiple signaling packets.
        EXPECT_EQ(ind.command_header().identifier().Read(), 1);
        EXPECT_EQ(
            ind.command_header().data_length().Read(),
            emboss::L2capFlowControlCreditInd::IntrinsicSizeInBytes() -
                emboss::L2capSignalingCommandHeader::IntrinsicSizeInBytes());
        EXPECT_EQ(ind.cid().Read(), capture.local_cid);
        EXPECT_EQ(ind.credits().Read(), capture.credits);
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  // Allow proxy to reserve 1 LE credit.
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 1));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  // Build channel so ACL connection is registered.
  L2capCoc channel = BuildCoc(proxy,
                              CocParameters{.handle = kConnectionHandle,
                                            .local_cid = capture.local_cid});

  PW_TEST_EXPECT_OK(channel.SendAdditionalRxCredits(capture.credits));
  RunDispatcher();

  EXPECT_EQ(capture.sends_called, 1);
}

TEST_F(L2capSignalingTest, RemoteLocalCidCollisionBetweenProfiles) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [](H4PacketWithHci&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/5,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  // We are receiving the connection and disconnection request for two different
  // channels where one channel has same local CID and the others remote CID.
  constexpr uint8_t kPsm = 0x19;
  constexpr uint16_t kRemoteCID = 0x65;
  constexpr uint16_t kLocalCID = 0x46;

  constexpr uint8_t kPsm2 = 0x1B;
  constexpr uint16_t kRemoteCID2 = 0x46;
  constexpr uint16_t kLocalCID2 = 0x4f;

  // Receive L2capConnectionReq on first PSM
  EXPECT_EQ(SendL2capConnectionReq(proxy,
                                   Direction::kFromController,
                                   kConnectionHandle,
                                   kRemoteCID,
                                   kPsm),
            pw::OkStatus());
  EXPECT_EQ(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kConnectionHandle,
                             kRemoteCID,
                             kLocalCID,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL),
      pw::OkStatus());

  // Acquire first channel with the event_fn_
  uint8_t reset_called = 0;

  auto event_fn([&reset_called](L2capChannelEvent event) -> void {
    switch (event) {
      case L2capChannelEvent::kChannelClosedByOther:
      case L2capChannelEvent::kReset:
        reset_called++;
        break;
      case L2capChannelEvent::kRxInvalid:
      case L2capChannelEvent::kRxOutOfMemory:
      case L2capChannelEvent::kRxWhileStopped:
      case L2capChannelEvent::kWriteAvailable:
      default:
        break;
    }
  });
  BasicL2capChannel channel =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = kLocalCID,
                              .remote_cid = kRemoteCID,
                              .transport = AclTransportType::kBrEdr,
                              .event_fn = event_fn});

  // Receive L2capConnectionReq on second PSM
  EXPECT_EQ(SendL2capConnectionReq(proxy,
                                   Direction::kFromController,
                                   kConnectionHandle,
                                   kRemoteCID2,
                                   kPsm2),
            pw::OkStatus());
  EXPECT_EQ(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kConnectionHandle,
                             kRemoteCID2,
                             kLocalCID2,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL),
      pw::OkStatus());

  // Send Disconnect second channel (Received this disconnect rsp)
  EXPECT_EQ(SendL2capDisconnectRsp(proxy,
                                   Direction::kFromController,
                                   AclTransportType::kBrEdr,
                                   kConnectionHandle,
                                   kLocalCID2,
                                   kRemoteCID2),
            pw::OkStatus());

  // Assert first event channel wasn't called
  EXPECT_EQ(reset_called, 0);

  // Send Disconnect first channel (Received this disconnect rsp)
  EXPECT_EQ(SendL2capDisconnectRsp(proxy,
                                   Direction::kFromController,
                                   AclTransportType::kBrEdr,
                                   kConnectionHandle,
                                   kLocalCID,
                                   kRemoteCID),
            pw::OkStatus());

  // Assert first event channel was called
  EXPECT_EQ(reset_called, 1);
}

// ########## AcluSignalingChannelTest

class AcluSignalingChannelTest : public ProxyHostTest {};

TEST_F(AcluSignalingChannelTest, HandlesMultipleCommands) {
  std::optional<H4PacketWithHci> host_packet;
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&host_packet](H4PacketWithHci&& packet) {
        host_packet = std::move(packet);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  constexpr uint16_t kHandle = 123;

  // Test that the proxy can parse a CFrame containing multiple commands and
  // pass it through. We pack 3 CONNECTION_REQ commands into one CFrame.
  constexpr size_t kNumCommands = 3;
  constexpr size_t kCmdLen = emboss::L2capConnectionReq::IntrinsicSizeInBytes();
  constexpr size_t kL2capLength =
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() + kCmdLen * kNumCommands;
  constexpr size_t kHciLength =
      emboss::AclDataFrame::MinSizeInBytes() + kL2capLength;
  std::array<uint8_t, kHciLength> hci_arr{};
  H4PacketWithHci l2cap_cframe_packet{emboss::H4PacketType::ACL_DATA,
                                      pw::span(hci_arr.data(), kHciLength)};

  // ACL header
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto acl, MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_arr));
  acl.header().handle().Write(kHandle);
  acl.data_total_length().Write(kL2capLength);
  EXPECT_EQ(kL2capLength, acl.payload().BackingStorage().SizeInBytes());

  // L2CAP header
  auto l2cap =
      emboss::MakeCFrameView(acl.payload().BackingStorage().data(),
                             acl.payload().BackingStorage().SizeInBytes());
  l2cap.pdu_length().Write(kNumCommands * kCmdLen);
  l2cap.channel_id().Write(
      cpp23::to_underlying(emboss::L2capFixedCid::ACL_U_SIGNALING));
  EXPECT_TRUE(l2cap.Ok());

  auto command_buffer =
      pw::span(l2cap.payload().BackingStorage().data(),
               l2cap.payload().BackingStorage().SizeInBytes());
  EXPECT_EQ(l2cap.payload().BackingStorage().SizeInBytes(),
            kCmdLen * kNumCommands);

  do {
    // CONNECTION_REQ
    auto cmd_writer = emboss::MakeL2capConnectionReqView(command_buffer.data(),
                                                         command_buffer.size());
    cmd_writer.command_header().code().Write(
        emboss::L2capSignalingPacketCode::CONNECTION_REQ);
    // Note data_length doesn't include command header.
    cmd_writer.command_header().data_length().Write(
        kCmdLen - emboss::L2capSignalingCommandHeader::IntrinsicSizeInBytes());
    cmd_writer.psm().Write(1);
    cmd_writer.source_cid().Write(1);
    EXPECT_TRUE(cmd_writer.Ok());
    EXPECT_EQ(cmd_writer.SizeInBytes(), kCmdLen);
    command_buffer = command_buffer.subspan(cmd_writer.SizeInBytes());
  } while (!command_buffer.empty());

  proxy.HandleH4HciFromController(std::move(l2cap_cframe_packet));
  // We should get back what we sent, since the proxy doesn't consume
  // CONNECTION_REQ commands. It would be nice to also verify the individual
  // commands were parsed out but hooks don't exist for that at the time of
  // writing.
  EXPECT_TRUE(host_packet.has_value());
  EXPECT_EQ(host_packet->GetHciSpan().size(), kHciLength);
}

TEST_F(AcluSignalingChannelTest, InvalidPacketForwarded) {
  std::optional<H4PacketWithHci> host_packet;
  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&host_packet](H4PacketWithHci&& packet) {
        host_packet = std::move(packet);
      });
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/1,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  constexpr uint16_t kHandle = 123;

  // Test that the proxy forwards on invalid L2cap B-frames destined for
  // signaling channel.

  constexpr size_t kL2capLength =
      emboss::BasicL2capHeader::IntrinsicSizeInBytes();
  constexpr size_t kHciLength =
      emboss::AclDataFrame::MinSizeInBytes() + kL2capLength;
  std::array<uint8_t, kHciLength> hci_arr{};
  H4PacketWithHci l2cap_cframe_packet{emboss::H4PacketType::ACL_DATA,
                                      pw::span(hci_arr.data(), kHciLength)};

  // ACL header
  PW_TEST_ASSERT_OK_AND_ASSIGN(
      auto acl, MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_arr));
  acl.header().handle().Write(kHandle);
  acl.data_total_length().Write(kL2capLength);
  EXPECT_EQ(kL2capLength, acl.payload().BackingStorage().SizeInBytes());

  // L2CAP header
  auto l2cap =
      emboss::MakeCFrameView(acl.payload().BackingStorage().data(),
                             acl.payload().BackingStorage().SizeInBytes());
  // Invalid length, since we aren't encoding a payload.
  l2cap.pdu_length().Write(1);
  l2cap.channel_id().Write(
      cpp23::to_underlying(emboss::L2capFixedCid::ACL_U_SIGNALING));
  EXPECT_FALSE(l2cap.Ok());

  proxy.HandleH4HciFromController(std::move(l2cap_cframe_packet));
  // We should get back what we sent.
  EXPECT_TRUE(host_packet.has_value());
  EXPECT_EQ(host_packet->GetHciSpan().size(), kHciLength);
}

// ########## ProxyHostConnectionEventTest

class ProxyHostConnectionEventTest : public ProxyHostTest {};

TEST_F(ProxyHostConnectionEventTest, ConnectionCompletePassthroughOk) {
  size_t host_called = 0;
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&host_called]([[maybe_unused]] H4PacketWithHci&& packet) {
        ++host_called;
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_EXPECT_OK(
      SendConnectionCompleteEvent(proxy, 1, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(host_called, 1U);

  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, 1));
  EXPECT_EQ(host_called, 2U);
}

TEST_F(ProxyHostConnectionEventTest,
       ConnectionCompleteWithErrorStatusPassthroughOk) {
  size_t host_called = 0;
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&host_called]([[maybe_unused]] H4PacketWithHci&& packet) {
        ++host_called;
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_EXPECT_OK(SendConnectionCompleteEvent(
      proxy, 1, emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED));
  EXPECT_EQ(host_called, 1U);
}

TEST_F(ProxyHostConnectionEventTest, LeConnectionCompletePassthroughOk) {
  size_t host_called = 0;
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&host_called]([[maybe_unused]] H4PacketWithHci&& packet) {
        ++host_called;
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_EXPECT_OK(
      SendLeConnectionCompleteEvent(proxy, 1, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(host_called, 1U);
}

class L2capStatusTrackerTest : public ProxyHostTest,
                               public L2capStatusDelegate {
 public:
  static constexpr uint16_t kPsm = 1;

  bool ShouldTrackPsm(uint16_t psm) override { return psm == kPsm; }
  void HandleConnectionComplete(const L2capChannelConnectionInfo& i) override {
    EXPECT_FALSE(info.has_value());
    PW_CHECK(proxy_ptr);
    info.emplace(i);
    // Test we can create channel directly in callback.
    l2cap_channel =
        BuildBasicL2capChannel(*proxy_ptr,
                               {.handle = i.connection_handle,
                                .local_cid = i.local_cid,
                                .remote_cid = i.remote_cid,
                                .transport = AclTransportType::kBrEdr});
  }
  void HandleDisconnectionComplete(
      const L2capChannelConnectionInfo& i) override {
    ASSERT_TRUE(info.has_value());
    EXPECT_EQ(info->direction, i.direction);
    EXPECT_EQ(info->connection_handle, i.connection_handle);
    EXPECT_EQ(info->remote_cid, i.remote_cid);
    EXPECT_EQ(info->local_cid, i.local_cid);
    info.reset();
  }

  void HandleConfigurationChanged(
      const L2capChannelConfigurationInfo& i) override {
    configuration_called++;
    PW_CHECK(proxy_ptr);

    EXPECT_EQ(config_info->direction, i.direction);
    EXPECT_EQ(config_info->connection_handle, i.connection_handle);
    EXPECT_EQ(config_info->local_cid, i.local_cid);
    EXPECT_EQ(config_info->mtu, i.mtu);
  }

  ProxyHost* proxy_ptr = nullptr;
  uint8_t configuration_called = 0;
  std::optional<L2capChannelConnectionInfo> info;
  std::optional<BasicL2capChannel> l2cap_channel;
  std::optional<L2capChannelConfigurationInfo> config_info;
};

// TODO(b/405201804): Add test that check MTU value in the response
TEST_F(L2capStatusTrackerTest, L2capConfigurationMTUCalled) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy_ptr = &proxy;

  constexpr uint16_t kLocalCid = 30;
  constexpr uint16_t kRemoteCid = 31;
  constexpr uint16_t kHandle = 123;

  proxy.RegisterL2capStatusDelegate(*this);

  PW_TEST_EXPECT_OK(
      SendConnectionCompleteEvent(proxy, kHandle, emboss::StatusCode::SUCCESS));

  // Receive new connection req
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromController, kHandle, kRemoteCid, kPsm));
  EXPECT_FALSE(info.has_value());
  // Send success rsp
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kHandle,
                             kRemoteCid,
                             kLocalCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));

  auto l2cap_options = L2capOptions{
      .mtu = MtuOption{1024},
  };

  // Send Configure Request
  auto expected_sent_l2cap_configuration = L2capChannelConfigurationInfo{
      .direction = Direction::kFromHost,
      .connection_handle = kHandle,
      .remote_cid = kRemoteCid,
      .local_cid = kLocalCid,
      .mtu = MtuOption{1024},
  };
  config_info.emplace(expected_sent_l2cap_configuration);

  PW_TEST_EXPECT_OK(SendL2capConfigureReq(
      proxy, Direction::kFromHost, kHandle, kRemoteCid, l2cap_options));

  PW_TEST_EXPECT_OK(
      SendL2capConfigureRsp(proxy,
                            Direction::kFromController,
                            kHandle,
                            kLocalCid,
                            emboss::L2capConfigurationResult::SUCCESS));
  ASSERT_EQ(this->configuration_called, 1);

  // Receive Configure Request
  auto expected_recv_l2cap_configuration = L2capChannelConfigurationInfo{
      .direction = Direction::kFromController,
      .connection_handle = kHandle,
      .remote_cid = kRemoteCid,
      .local_cid = kLocalCid,
      .mtu = MtuOption{1024},
  };

  config_info.emplace(expected_recv_l2cap_configuration);

  PW_TEST_EXPECT_OK(SendL2capConfigureReq(
      proxy, Direction::kFromController, kHandle, kLocalCid, l2cap_options));

  PW_TEST_EXPECT_OK(
      SendL2capConfigureRsp(proxy,
                            Direction::kFromHost,
                            kHandle,
                            kRemoteCid,
                            emboss::L2capConfigurationResult::SUCCESS));
  ASSERT_EQ(this->configuration_called, 2);

  proxy.UnregisterL2capStatusDelegate(*this);
}

TEST_F(L2capStatusTrackerTest, L2capConfigurationNoOption) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  proxy_ptr = &proxy;

  constexpr uint16_t kSourceCid = 30;
  constexpr uint16_t kDestinationCid = 31;
  constexpr uint16_t kHandle = 123;

  proxy.RegisterL2capStatusDelegate(*this);

  PW_TEST_EXPECT_OK(
      SendConnectionCompleteEvent(proxy, kHandle, emboss::StatusCode::SUCCESS));

  // Send new connection req
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromController, kHandle, kSourceCid, kPsm));
  EXPECT_FALSE(info.has_value());

  // Send success rsp
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));

  // Send Configure Request
  auto expected_l2cap_configuration = L2capChannelConfigurationInfo{
      .direction = Direction::kFromController,
      .connection_handle = kHandle,
      .remote_cid = kSourceCid,
      .local_cid = kDestinationCid,
      .mtu = std::nullopt,
  };

  config_info.emplace(expected_l2cap_configuration);

  auto l2cap_options = L2capOptions{
      .mtu = std::nullopt,
  };

  PW_TEST_EXPECT_OK(SendL2capConfigureReq(proxy,
                                          Direction::kFromController,
                                          kHandle,
                                          kDestinationCid,
                                          l2cap_options));

  PW_TEST_EXPECT_OK(
      SendL2capConfigureRsp(proxy,
                            Direction::kFromHost,
                            kHandle,
                            kSourceCid,
                            emboss::L2capConfigurationResult::SUCCESS));

  proxy.UnregisterL2capStatusDelegate(*this);
}

TEST_F(L2capStatusTrackerTest, L2capEventsControllerInitiated) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  proxy_ptr = &proxy;

  constexpr uint16_t kSourceCid = 30;
  constexpr uint16_t kDestinationCid = 31;
  constexpr uint16_t kHandle = 123;

  proxy.RegisterL2capStatusDelegate(*this);

  PW_TEST_EXPECT_OK(
      SendConnectionCompleteEvent(proxy, kHandle, emboss::StatusCode::SUCCESS));

  // First send CONNECTION_REQ to setup partial connection
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromController, kHandle, kSourceCid, kPsm));
  EXPECT_FALSE(info.has_value());

  // Send non-successful connection response.
  PW_TEST_EXPECT_OK(SendL2capConnectionRsp(
      proxy,
      Direction::kFromHost,
      kHandle,
      kSourceCid,
      kDestinationCid,
      emboss::L2capConnectionRspResultCode::INVALID_SOURCE_CID));
  EXPECT_FALSE(info.has_value());

  // Send successful connection response, but expect that it will not have
  // called listener since the connection was closed with error already.
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));
  EXPECT_FALSE(info.has_value());

  // Send new connection req
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromController, kHandle, kSourceCid, kPsm));
  EXPECT_FALSE(info.has_value());

  // Send rsp with PENDING set.
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::PENDING));
  EXPECT_FALSE(info.has_value());

  // Send success rsp
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));
  EXPECT_TRUE(info.has_value());
  EXPECT_EQ(info->direction, Direction::kFromController);
  EXPECT_EQ(info->connection_handle, kHandle);
  EXPECT_EQ(info->local_cid, kDestinationCid);
  EXPECT_EQ(info->remote_cid, kSourceCid);

  // Send disconnect
  PW_TEST_EXPECT_OK(SendL2capDisconnectRsp(proxy,
                                           Direction::kFromHost,
                                           AclTransportType::kBrEdr,
                                           kHandle,
                                           kSourceCid,
                                           kDestinationCid));
  EXPECT_FALSE(info.has_value());

  proxy.UnregisterL2capStatusDelegate(*this);

  // Send successful connection sequence with no listeners.
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromController, kHandle, kSourceCid, kPsm));
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromHost,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));
  EXPECT_FALSE(info.has_value());
}

TEST_F(L2capStatusTrackerTest, L2capEventsHostInitiated) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  proxy_ptr = &proxy;

  constexpr uint16_t kSourceCid = 30;
  constexpr uint16_t kDestinationCid = 31;
  constexpr uint16_t kHandle = 123;

  proxy.RegisterL2capStatusDelegate(*this);

  PW_TEST_EXPECT_OK(
      SendConnectionCompleteEvent(proxy, kHandle, emboss::StatusCode::SUCCESS));

  // First send CONNECTION_REQ to setup partial connection
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromHost, kHandle, kSourceCid, kPsm));
  EXPECT_FALSE(info.has_value());

  // Send non-successful connection response.
  PW_TEST_EXPECT_OK(SendL2capConnectionRsp(
      proxy,
      Direction::kFromController,
      kHandle,
      kSourceCid,
      kDestinationCid,
      emboss::L2capConnectionRspResultCode::INVALID_SOURCE_CID));
  EXPECT_FALSE(info.has_value());

  // Send successful connection response, but expect that it will not have
  // called listener since the connection was closed with error already.
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromController,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));
  EXPECT_FALSE(info.has_value());

  // Send new connection req
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromHost, kHandle, kSourceCid, kPsm));
  EXPECT_FALSE(info.has_value());

  // Send rsp with PENDING set.
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromController,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::PENDING));
  EXPECT_FALSE(info.has_value());

  // Send success rsp
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromController,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));
  EXPECT_TRUE(info.has_value());
  EXPECT_EQ(info->direction, Direction::kFromHost);
  EXPECT_EQ(info->connection_handle, kHandle);
  EXPECT_EQ(info->local_cid, kSourceCid);
  EXPECT_EQ(info->remote_cid, kDestinationCid);

  // Send disconnect rsp
  PW_TEST_EXPECT_OK(SendL2capDisconnectRsp(proxy,
                                           Direction::kFromController,
                                           AclTransportType::kBrEdr,
                                           kHandle,
                                           kSourceCid,
                                           kDestinationCid));
  EXPECT_FALSE(info.has_value());

  proxy.UnregisterL2capStatusDelegate(*this);

  // Send successful connection sequence with no listeners.
  PW_TEST_EXPECT_OK(SendL2capConnectionReq(
      proxy, Direction::kFromHost, kHandle, kSourceCid, kPsm));
  PW_TEST_EXPECT_OK(
      SendL2capConnectionRsp(proxy,
                             Direction::kFromController,
                             kHandle,
                             kSourceCid,
                             kDestinationCid,
                             emboss::L2capConnectionRspResultCode::SUCCESSFUL));
  EXPECT_FALSE(info.has_value());
}

TEST_F(ProxyHostConnectionEventTest, HciDisconnectionAlertsListeners) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [](H4PacketWithHci&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  constexpr uint16_t kPsm = 1;

  class TestStatusDelegate final : public L2capStatusDelegate {
   public:
    bool ShouldTrackPsm(uint16_t psm) override { return psm == kPsm; }
    void HandleConnectionComplete(const L2capChannelConnectionInfo&) override {
      ++connections_received;
    }
    void HandleDisconnectionComplete(
        const L2capChannelConnectionInfo&) override {
      ++disconnections_received;
    }

    void HandleConfigurationChanged(
        const L2capChannelConfigurationInfo&) override {
      ++configuration_received;
    }

    int connections_received = 0;
    int disconnections_received = 0;
    int configuration_received = 0;
  };

  TestStatusDelegate test_delegate;
  proxy.RegisterL2capStatusDelegate(test_delegate);

  constexpr uint16_t Handle1 = 0x123, Handle2 = 0x124;
  PW_TEST_EXPECT_OK(
      SendConnectionCompleteEvent(proxy, Handle1, emboss::StatusCode::SUCCESS));
  PW_TEST_EXPECT_OK(
      SendConnectionCompleteEvent(proxy, Handle2, emboss::StatusCode::SUCCESS));

  // Establish three connected_channels:
  // handle = 0x123, PSM = 1 | handle = 0x124, PSM = 1 | handle = 0x123, PSM =
  // 1
  constexpr uint16_t kStartSourceCid = 0x111;
  constexpr uint16_t kStartDestinationCid = 0x211;

  auto l2cap_options = L2capOptions{
      .mtu = MtuOption{1024},
  };

  for (size_t i = 0; i < 3; ++i) {
    PW_TEST_EXPECT_OK(
        SendL2capConnectionReq(proxy,
                               Direction::kFromController,
                               i == 1 ? Handle2 : Handle1,
                               static_cast<uint16_t>(kStartSourceCid + i),
                               kPsm));
    PW_TEST_EXPECT_OK(SendL2capConnectionRsp(
        proxy,
        Direction::kFromHost,
        i == 1 ? Handle2 : Handle1,
        static_cast<uint16_t>(kStartSourceCid + i),
        static_cast<uint16_t>(kStartDestinationCid + i),
        emboss::L2capConnectionRspResultCode::SUCCESSFUL));
    PW_TEST_EXPECT_OK(
        SendL2capConfigureReq(proxy,
                              Direction::kFromController,
                              i == 1 ? Handle2 : Handle1,
                              static_cast<uint16_t>(kStartDestinationCid + i),
                              l2cap_options));
    PW_TEST_EXPECT_OK(
        SendL2capConfigureRsp(proxy,
                              Direction::kFromHost,
                              i == 1 ? Handle2 : Handle1,
                              static_cast<uint16_t>(kStartSourceCid + i),
                              emboss::L2capConfigurationResult::SUCCESS));
  }

  EXPECT_EQ(test_delegate.connections_received, 3);
  EXPECT_EQ(test_delegate.configuration_received, 3);
  EXPECT_EQ(test_delegate.disconnections_received, 0);

  // Disconnect handle1, which should disconnect first and third channel.
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, Handle1));
  EXPECT_EQ(test_delegate.disconnections_received, 2);

  // Confirm remaining channel can still be disconnected properly.
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, Handle2));
  EXPECT_EQ(test_delegate.disconnections_received, 3);

  proxy.UnregisterL2capStatusDelegate(test_delegate);
}

TEST_F(ProxyHostConnectionEventTest,
       HciDisconnectionFromControllerClosesChannels) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [](H4PacketWithHci&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle + 1, emboss::StatusCode::SUCCESS));

  constexpr uint16_t kStartingCid = 0x111;
  int events_received = 0;
  auto event_fn = [&events_received](L2capChannelEvent event) {
    ++events_received;
    EXPECT_EQ(event, L2capChannelEvent::kChannelClosedByOther);
  };
  BasicL2capChannel chan1 = BuildBasicL2capChannel(proxy,
                                                   {.handle = kConnectionHandle,
                                                    .local_cid = kStartingCid,
                                                    .remote_cid = kStartingCid,
                                                    .event_fn = event_fn});

  // chan2 is on a different connection so should not be closed
  BasicL2capChannel chan2 =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle + 1,
                              .local_cid = kStartingCid + 1,
                              .remote_cid = kStartingCid + 1,
                              .event_fn = event_fn});

  BasicL2capChannel chan3 =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = kStartingCid + 2,
                              .remote_cid = kStartingCid + 2,
                              .event_fn = event_fn});

  EXPECT_EQ(GetState(chan1), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan3), L2capChannel::State::kRunning);

  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, kConnectionHandle));

  EXPECT_EQ(events_received, 2);
  EXPECT_EQ(GetState(chan1), L2capChannel::State::kClosed);
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan3), L2capChannel::State::kClosed);

  // Confirm L2CAP_DISCONNECTION_RSP packet does not result in another event.
  PW_TEST_EXPECT_OK(SendL2capDisconnectRsp(proxy,
                                           Direction::kFromHost,
                                           AclTransportType::kLe,
                                           kConnectionHandle,
                                           kStartingCid,
                                           kStartingCid));
  EXPECT_EQ(events_received, 2);
}

TEST_F(ProxyHostConnectionEventTest,
       L2capDisconnectionRspFromHostClosesChannels) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [](H4PacketWithHci&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  constexpr uint16_t kStartingSourceCid = 0x111;
  constexpr uint16_t kStartingDestinationCid = 0x211;
  int events_received = 0;
  auto event_fn = [&events_received](L2capChannelEvent event) {
    ++events_received;
    EXPECT_EQ(event, L2capChannelEvent::kChannelClosedByOther);
  };
  BasicL2capChannel chan1 =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = kStartingDestinationCid,
                              .remote_cid = kStartingSourceCid,
                              .event_fn = event_fn});

  BasicL2capChannel chan2 =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = kStartingDestinationCid + 1,
                              .remote_cid = kStartingSourceCid + 1,
                              .event_fn = event_fn});

  BasicL2capChannel chan3 =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = kStartingDestinationCid + 2,
                              .remote_cid = kStartingSourceCid + 2,
                              .event_fn = event_fn});

  EXPECT_EQ(GetState(chan1), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan3), L2capChannel::State::kRunning);

  // Close chan1's & chan2's underlying L2CAP connections.
  PW_TEST_EXPECT_OK(
      SendL2capDisconnectRsp(proxy,
                             Direction::kFromHost,
                             AclTransportType::kLe,
                             kConnectionHandle,
                             /*source_cid=*/kStartingSourceCid,
                             /*destination_cid=*/kStartingDestinationCid));
  PW_TEST_EXPECT_OK(
      SendL2capDisconnectRsp(proxy,
                             Direction::kFromHost,
                             AclTransportType::kLe,
                             kConnectionHandle,
                             /*source_cid=*/kStartingSourceCid + 2,
                             /*destination_cid=*/kStartingDestinationCid + 2));

  EXPECT_EQ(events_received, 2);
  EXPECT_EQ(GetState(chan1), L2capChannel::State::kClosed);
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan3), L2capChannel::State::kClosed);

  // Confirm HCI disconnection only closes remaining channel.
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, kConnectionHandle));
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kClosed);
  EXPECT_EQ(events_received, 3);
}

TEST_F(ProxyHostConnectionEventTest,
       L2capDisconnectionRspFromControllerClosesChannels) {
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [](H4PacketWithHci&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));

  constexpr uint16_t kStartingCid = 0x111;
  int events_received = 0;
  auto event_fn = [&events_received](L2capChannelEvent event) {
    ++events_received;
    EXPECT_EQ(event, L2capChannelEvent::kChannelClosedByOther);
  };
  BasicL2capChannel chan1 = BuildBasicL2capChannel(proxy,
                                                   {.handle = kConnectionHandle,
                                                    .local_cid = kStartingCid,
                                                    .remote_cid = kStartingCid,
                                                    .event_fn = event_fn});

  BasicL2capChannel chan2 =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = kStartingCid + 1,
                              .remote_cid = kStartingCid + 1,
                              .event_fn = event_fn});

  BasicL2capChannel chan3 =
      BuildBasicL2capChannel(proxy,
                             {.handle = kConnectionHandle,
                              .local_cid = kStartingCid + 2,
                              .remote_cid = kStartingCid + 2,
                              .event_fn = event_fn});

  EXPECT_EQ(GetState(chan1), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan3), L2capChannel::State::kRunning);

  // Close chan1's & chan2's underlying L2CAP connections.
  PW_TEST_EXPECT_OK(SendL2capDisconnectRsp(proxy,
                                           Direction::kFromController,
                                           AclTransportType::kLe,
                                           kConnectionHandle,
                                           kStartingCid,
                                           kStartingCid));
  PW_TEST_EXPECT_OK(SendL2capDisconnectRsp(proxy,
                                           Direction::kFromController,
                                           AclTransportType::kLe,
                                           kConnectionHandle,
                                           kStartingCid + 2,
                                           kStartingCid + 2));

  EXPECT_EQ(events_received, 2);
  EXPECT_EQ(GetState(chan1), L2capChannel::State::kClosed);
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kRunning);
  EXPECT_EQ(GetState(chan3), L2capChannel::State::kClosed);

  // Confirm HCI disconnection only closes remaining channel.
  PW_TEST_EXPECT_OK(SendDisconnectionCompleteEvent(proxy, kConnectionHandle));
  EXPECT_EQ(GetState(chan2), L2capChannel::State::kClosed);
  EXPECT_EQ(events_received, 3);
}

// ########## AclFragTest

// TODO: https://pwbug.dev/438553038 - Update tests to also test in to-host
// direction.
class AclFragTest : public ProxyHostTest {
 protected:
  static constexpr uint16_t kHandle = 0x04AD;
  static constexpr uint16_t kLocalCid = 0xC1D;

  ProxyHost GetProxy() {
    // We can't add a ProxyHost member because it makes the test fixture too
    // large, so we provide a helper function instead.
    return ProxyHost(pw::bind_member<&AclFragTest::SendToHost>(this),
                     pw::bind_member<&AclFragTest::SendToController>(this),
                     /*le_acl_credits_to_reserve=*/0,
                     /*br_edr_acl_credits_to_reserve=*/0,
                     GetProxyHostAllocator());
  }

  BasicL2capChannel GetL2capChannel(
      ProxyHost& proxy,
      multibuf::MultiBufAllocator* rx_multibuf_allocator = nullptr) {
    return BuildBasicL2capChannel(
        proxy,
        BasicL2capParameters{
            .rx_multibuf_allocator = rx_multibuf_allocator,
            .handle = kHandle,
            .local_cid = kLocalCid,
            .remote_cid = 0x123,
            .transport = AclTransportType::kLe,
            .payload_from_controller_fn =
                [this](multibuf::MultiBuf&& buffer) {
                  payloads_from_controller_.emplace_back(std::move(buffer));
                  return std::nullopt;  // Consume
                },
        });
  }

  // Verify the payloads the client received.
  // Also dtor them (in some cases they may have been allocated in the test).
  void ExpectClientReceivedPayloadsAndClear(
      std::initializer_list<ConstByteSpan> expected_payloads) {
    ASSERT_EQ(payloads_from_controller_.size(), expected_payloads.size());
    auto payloads_iter = payloads_from_controller_.begin();
    for (ConstByteSpan expected : expected_payloads) {
      const multibuf::MultiBuf& mbuf = *payloads_iter++;
      ConstByteSpan payload = mbuf.ContiguousSpan().value();
      EXPECT_TRUE(std::equal(
          payload.begin(), payload.end(), expected.begin(), expected.end()));
    }
    payloads_from_controller_.clear();
  }

  void VerifyNormalOperationAfterRecombination(ProxyHost& proxy) {
    // Verify things work normally after recombination ends.
    static constexpr std::array<uint8_t, 4> kPayload = {'D', 'o', 'n', 'e'};
    payloads_from_controller_.clear();
    SendL2capBFrame(proxy, kHandle, kPayload, kPayload.size(), kLocalCid);
    ExpectClientReceivedPayloadsAndClear({
        as_bytes(span(kPayload)),
    });
  }

  int packets_sent_to_host_ = 0;
  int packets_sent_to_controller_ = 0;

 private:
  void SendToHost(H4PacketWithHci&& /*packet*/) { ++packets_sent_to_host_; }

  void SendToController(H4PacketWithH4&& /*packet*/) {
    ++packets_sent_to_controller_;
  }

  std::vector<multibuf::MultiBuf> payloads_from_controller_;
};

TEST_F(AclFragTest, AclBiggerThanL2capDropped) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  BasicL2capChannel channel = GetL2capChannel(proxy);

  // Send an ACL packet with more data than L2CAP header indicates.
  static constexpr std::array<uint8_t, 4> kPayload{};
  SendL2capBFrame(proxy, kHandle, kPayload, 1, kLocalCid);

  // Should be dropped.
  EXPECT_EQ(packets_sent_to_host_, 1);
  ExpectClientReceivedPayloadsAndClear({});
}

TEST_F(AclFragTest, RecombinationWorksWithEmptyFirstPayload) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  BasicL2capChannel channel = GetL2capChannel(proxy);

  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  // Fragment 1: ACL Header + L2CAP B-Frame Header + (no payload)
  PW_LOG_INFO("Sending frag 1: ACL + L2CAP header");
  SendL2capBFrame(proxy, kHandle, {}, kPayload.size(), kLocalCid);

  // Fragment 2: ACL Header + Payload frag 2
  PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2");
  SendAclContinuingFrag(proxy, kHandle, kPayload);

  EXPECT_EQ(packets_sent_to_host_, 1);
  ExpectClientReceivedPayloadsAndClear({
      as_bytes(span(kPayload)),
  });

  VerifyNormalOperationAfterRecombination(proxy);
}

// If a client channel is dropped between first and last
// packet of a fragmented PDU, then packet should be dropped.
// Under msan this test also verifies code is not trying to access channel
// allocator's memory after channel dtor.
TEST_F(AclFragTest, ChannelDtorDuringRecombinationDropsPdu) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  {
    BasicL2capChannel channel = GetL2capChannel(proxy);

    // Fragment 1: ACL Header + L2CAP B-Frame Header + (no payload)
    PW_LOG_INFO("Sending frag 1: ACL + L2CAP header");

    SendL2capBFrame(proxy, kHandle, {}, kPayload.size(), kLocalCid);

    // Dtor of channel and allocator.
  }

  // Fragment 2: ACL Header + Payload frag 2
  PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2");
  // Since channel was destroyed before this, channel allocator's memory should
  // not be accessed (msan will verify).
  SendAclContinuingFrag(proxy, kHandle, kPayload);

  // Since channel was destroyed before 2nd fragment was sent, PDU should have
  // been dropped.
  EXPECT_EQ(packets_sent_to_host_, 1);
  ExpectClientReceivedPayloadsAndClear({});

  // Open up channel again to verify rx still works after completing above.
  BasicL2capChannel channel2 = GetL2capChannel(proxy);
  VerifyNormalOperationAfterRecombination(proxy);
}

// During recombination dtor first channel, but then create new channel with
// same cid. Verify recombination is properly dropped.
TEST_F(AclFragTest, ChannelDtorAndNewChannelDuringRecombination) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  {
    BasicL2capChannel channel = GetL2capChannel(proxy);

    // Fragment 1: ACL Header + L2CAP B-Frame Header + (no payload)
    PW_LOG_INFO("Sending frag 1: ACL + L2CAP header");

    SendL2capBFrame(proxy, kHandle, {}, kPayload.size(), kLocalCid);

    // Dtor of channel and allocator.
  }

  // Open up L2CAP channel with same channel id on same connection.
  BasicL2capChannel channel2 = GetL2capChannel(proxy);

  // Fragment 2: ACL Header + Payload frag 2
  PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2");
  // Since channel1 was destroyed before this, channel1 allocator's
  // memory should not be accessed (msan will verify).
  SendAclContinuingFrag(proxy, kHandle, kPayload);

  // Since channel1 was destroyed before 2nd fragment was sent, its PDU should
  // have been dropped even though channel2 with same cid was created.
  EXPECT_EQ(packets_sent_to_host_, 1);
  ExpectClientReceivedPayloadsAndClear({});

  // Verify rx to channel2 still works.
  VerifyNormalOperationAfterRecombination(proxy);
}

// Ensure expected handling of channel not having enough allocator space to fit
// the recombined buffer. Current behavior is to pass first and any continuing
// packets to AP.
// TODO: https://pwbug.dev/404275508 - We should probably do something different
// in this case (like stopping channel or at least sending it an event).
TEST_F(AclFragTest, ChannelCantAllocateMultibuf) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);

  // Intentionally use allocator without enough room for PDU buf.
  std::array<std::byte, 1> packet_buffer{};
  pw::multibuf::SimpleAllocator multibuf_allocator{
      /*data_area=*/packet_buffer,
      /*metadata_alloc=*/allocator::GetLibCAllocator()};

  BasicL2capChannel channel = GetL2capChannel(proxy, &multibuf_allocator);

  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  // Fragment 1: ACL Header + L2CAP B-Frame Header + (no payload)
  PW_LOG_INFO("Sending frag 1: ACL + L2CAP header");
  SendL2capBFrame(proxy, kHandle, {}, kPayload.size(), kLocalCid);

  // Fragment 2: ACL Header + Payload frag 2
  PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2");
  SendAclContinuingFrag(proxy, kHandle, kPayload);

  // Both packets should have been sent to host.
  EXPECT_EQ(packets_sent_to_host_, 3);
  // No payloads should have been sent to the client.
  ExpectClientReceivedPayloadsAndClear({});
}

// When an ACL fragmented payload is received for a channel with no rx allocator
// the original ACL packets are passed to the host.
// This currently can happen for signal and GATT channels.
// TODO: https://pwbug.dev/423695410 - In future we should always support
// recombination so the client has the option to reject.
TEST_F(AclFragTest, ChannelHasNoRxAllocator) {
  // GATT fixed CID is 0x04.
  uint16_t local_cid = 0x0004;

  constexpr uint8_t kPayloadFragmentSize = 3;
  constexpr uint8_t kRecombinedPayloadSize = kPayloadFragmentSize * 2;
  std::array<uint8_t, kPayloadFragmentSize> payload_fragment = {
      0xAB, 0xCD, 0xEF};

  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kPayloadFragmentSize>
      hci_first{};
  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kPayloadFragmentSize>
      hci_cont{};

  struct {
    size_t to_host_called = 0;
    std::array<H4PacketWithHci, 2> h4s;
  } capture{.h4s = {H4PacketWithHci{emboss::H4PacketType::ACL_DATA, hci_first},
                    H4PacketWithHci{emboss::H4PacketType::ACL_DATA, hci_cont}}};

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        if (packet.GetH4Type() != emboss::H4PacketType::ACL_DATA) {
          return;
        }
        auto expected_hci = capture.h4s[capture.to_host_called].GetHciSpan();
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               expected_hci.begin(),
                               expected_hci.end()));
        ++capture.to_host_called;
      });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));

  GattNotifyChannel channel = BuildGattNotifyChannel(proxy,
                                                     {
                                                         .handle = kHandle,
                                                     });

  {
    // Define and send first fragment.
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_first);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kPayloadFragmentSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    // We are going to send twice the expected payload (over two fragments).
    bframe.pdu_length().Write(kRecombinedPayloadSize);
    bframe.channel_id().Write(local_cid);
    std::copy(payload_fragment.begin(),
              payload_fragment.end(),
              bframe.payload().BackingStorage().begin());

    std::array<uint8_t, hci_first.size()> hci_first_send{};
    std::copy(hci_first.begin(), hci_first.end(), hci_first_send.begin());

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_first_send};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // ACL fragment should be delivered to host since channel can't
    // recombine. An error should be logged also, but we don't have way in
    // Pigweed to test that here.
    EXPECT_EQ(capture.to_host_called, 1u);
    ExpectClientReceivedPayloadsAndClear({});
  }

  {
    // Define and send 2nd fragment.
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_first);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::CONTINUING_FRAGMENT);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    // Just contains the 2nd payload with no l2cap headers.
    acl->data_total_length().Write(kPayloadFragmentSize);

    // Entire ACL payload is just the fragment.
    std::copy(payload_fragment.begin(),
              payload_fragment.end(),
              acl->payload().BackingStorage().begin());

    std::array<uint8_t, hci_cont.size()> hci_cont_send{};
    std::copy(hci_cont.begin(), hci_cont.end(), hci_cont_send.begin());

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_cont_send};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // ACL fragment should be delivered to host since channel can't recombine.
    // The fact there were two fragments also verifies that recombination didn't
    // happen.
    EXPECT_EQ(capture.to_host_called, 2u);
    ExpectClientReceivedPayloadsAndClear({});
  }
}

// If a recombined PDU is unhandled, then a ACL packet containing the entire
// PDU should be passed on to host.
TEST_F(AclFragTest, UnhandledRecombinedPdu) {
  constexpr uint8_t kPayloadFragmentSize = 3;
  constexpr uint8_t kRecombinedPayloadSize = kPayloadFragmentSize * 2;
  // rename to fragment
  std::array<uint8_t, kPayloadFragmentSize> payload_first = {0x04, 0x05, 0x06};
  std::array<uint8_t, kPayloadFragmentSize> payload_cont = {0x07, 0x08, 0x09};

  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kPayloadFragmentSize>
      hci_first{};
  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kPayloadFragmentSize>
      hci_cont{};

  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kRecombinedPayloadSize>
      hci_recombined{};

  {
    // Fill expected combined packet.
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_recombined);
    acl->header().handle().Write(kHandle);
    // Controller to Host are always flushable (except for loopback), per
    // Volume 4, Part E, 5.4.2, Packet_Boundary_Flag table.
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kRecombinedPayloadSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    // We are going to send twice the expected payload (over two fragments).
    bframe.pdu_length().Write(kRecombinedPayloadSize);
    bframe.channel_id().Write(kLocalCid);
    std::copy(payload_first.begin(),
              payload_first.end(),
              bframe.payload().BackingStorage().begin());
    std::copy(payload_cont.begin(),
              payload_cont.end(),
              bframe.payload().BackingStorage().begin() + kPayloadFragmentSize);
  }

  struct {
    int channel_pdus_received = 0;
    int to_host_acls = 0;
    H4PacketWithHci h4;
  } capture{
      .h4 = H4PacketWithHci{emboss::H4PacketType::ACL_DATA, hci_recombined}};

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        if (packet.GetH4Type() == emboss::H4PacketType::EVENT) {
          // No need to verify the READ_BUFFER event.
          return;
        }
        ++capture.to_host_acls;
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::ACL_DATA);
        auto expected_hci = capture.h4.GetHciSpan();
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               expected_hci.begin(),
                               expected_hci.end()));
      });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(
      proxy, /*num_credits_to_reserve=*/0));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(capture.to_host_acls, 0);

  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = kHandle,
          .local_cid = kLocalCid,
          .payload_from_controller_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                capture.channel_pdus_received++;
                // Unhandled
                return multibuf::MultiBuf(std::move(buffer));
              },
      });

  EXPECT_EQ(capture.channel_pdus_received, 0);

  {
    // Define and send first fragment.
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_first);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kPayloadFragmentSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    bframe.pdu_length().Write(kRecombinedPayloadSize);
    bframe.channel_id().Write(kLocalCid);
    std::copy(payload_first.begin(),
              payload_first.end(),
              bframe.payload().BackingStorage().begin());

    std::array<uint8_t, hci_first.size()> hci_send{};
    std::copy(hci_first.begin(), hci_first.end(), hci_send.begin());

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_send};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // ACL fragment should be added to partial recombined PDU. Nothing passed
    // on.
    EXPECT_EQ(capture.to_host_acls, 0);
    EXPECT_EQ(capture.channel_pdus_received, 0);
  }

  {
    // Define and send 2nd fragment.
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_cont);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::CONTINUING_FRAGMENT);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    // Just contains the 2nd payload with no l2cap headers.
    acl->data_total_length().Write(kPayloadFragmentSize);

    // Entire ACL payload is just the fragment.
    std::copy(payload_cont.begin(),
              payload_cont.end(),
              acl->payload().BackingStorage().begin());

    std::array<uint8_t, hci_cont.size()> hci_send{};
    std::copy(hci_cont.begin(), hci_cont.end(), hci_send.begin());

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_send};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // Recombined ACL packet should be delivered to host since channel rejected
    // it.
    EXPECT_EQ(capture.to_host_acls, 1);
    // Channel received the PDU, but rejected it.
    EXPECT_EQ(capture.channel_pdus_received, 1);
  }
}

TEST_F(AclFragTest, RecombineMaxValidSizePdu) {
  // L2CAP Basic Header is 4 bytes.
  // We want total L2CAP frame to be 2048 bytes (the proxy limit).
  // So L2CAP payload is 2044 bytes.
  constexpr uint32_t kL2capPayloadSize = 2044;
  constexpr uint32_t kFirstFragmentPayloadSize = 100;
  constexpr uint32_t kSecondFragmentPayloadSize =
      kL2capPayloadSize - kFirstFragmentPayloadSize;

  // Create a custom allocator with enough memory for the 2048-byte recombined
  // buffer. Needs to hold at least kH4AclHeaderSize (5) + 2048 = 2053 bytes.
  // We'll allocate 16384 bytes to be safe.
  std::array<std::byte, 16384> recombine_buffer_storage;
  pw::multibuf::SimpleAllocator recombine_allocator{
      recombine_buffer_storage, allocator::GetLibCAllocator()};

  // Pre-allocate the expected H4 packet that the proxy will output.
  // Size will be 1 (H4 indicator) + 4 (ACL header) + 4 (L2CAP header) +
  // kL2capPayloadSize = 2053 bytes.
  constexpr size_t kExpectedH4Size =
      1 + emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
      emboss::BasicL2capHeader::IntrinsicSizeInBytes() + kL2capPayloadSize;
  std::array<uint8_t, kExpectedH4Size> expected_h4{};
  {
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(
            pw::span(expected_h4).subspan(1));
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() + kL2capPayloadSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    bframe.pdu_length().Write(kL2capPayloadSize);
    bframe.channel_id().Write(kLocalCid);
    // Fill payload with some recognizable pattern, e.g., 0xA5.
    std::fill(bframe.payload().BackingStorage().begin(),
              bframe.payload().BackingStorage().end(),
              0xA5);
  }

  struct {
    int channel_pdus_received = 0;
    int to_host_acls = 0;
    pw::span<const uint8_t> expected_h4;
  } capture;
  capture.expected_h4 = expected_h4;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        if (packet.GetH4Type() == emboss::H4PacketType::EVENT) {
          return;
        }
        ++capture.to_host_acls;
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::ACL_DATA);

        // Verify size.
        ASSERT_EQ(packet.GetHciSpan().size() + 1, capture.expected_h4.size());

        // Verify contents.
        auto expected_hci = capture.expected_h4.subspan(1);
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               expected_hci.begin(),
                               expected_hci.end()));
      });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(
      proxy, /*num_credits_to_reserve=*/0));
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(capture.to_host_acls, 0);

  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .rx_multibuf_allocator = &recombine_allocator,
          .handle = kHandle,
          .local_cid = kLocalCid,
          .payload_from_controller_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                capture.channel_pdus_received++;
                // Return unhandled to trigger forwarding
                return multibuf::MultiBuf(std::move(buffer));
              },
      });

  // Construct and send fragment 1.
  {
    constexpr size_t kFirstFragmentHciSize =
        emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kFirstFragmentPayloadSize;
    std::array<uint8_t, kFirstFragmentHciSize> hci_first{};
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_first);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kFirstFragmentPayloadSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    bframe.pdu_length().Write(
        kL2capPayloadSize);  // The TOTAL payload size is 2044.
    bframe.channel_id().Write(kLocalCid);
    std::fill(bframe.payload().BackingStorage().begin(),
              bframe.payload().BackingStorage().end(),
              0xA5);

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_first};
    proxy.HandleH4HciFromController(std::move(h4_send));

    EXPECT_EQ(capture.to_host_acls, 0);
    EXPECT_EQ(capture.channel_pdus_received, 0);
  }

  // Construct and send fragment 2 (continuing fragment).
  {
    constexpr size_t kSecondFragmentHciSize =
        emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
        kSecondFragmentPayloadSize;
    std::array<uint8_t, kSecondFragmentHciSize> hci_cont{};
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_cont);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::CONTINUING_FRAGMENT);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(kSecondFragmentPayloadSize);

    std::fill(acl->payload().BackingStorage().begin(),
              acl->payload().BackingStorage().end(),
              0xA5);

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_cont};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // Recombined ACL packet should be delivered to host since channel rejected
    // it.
    EXPECT_EQ(capture.to_host_acls, 1);
    // Channel received the PDU, but rejected it.
    EXPECT_EQ(capture.channel_pdus_received, 1);
  }
}

TEST_F(AclFragTest, PassThroughLargePdu) {
  // L2CAP Basic Header is 4 bytes.
  // We want total L2CAP frame to be 2049 bytes (which exceeds the 2048-byte
  // proxy limit). So L2CAP payload is 2045 bytes.
  constexpr uint32_t kL2capPayloadSize = 2045;
  constexpr uint32_t kFirstFragmentPayloadSize = 100;
  constexpr uint32_t kSecondFragmentPayloadSize =
      kL2capPayloadSize - kFirstFragmentPayloadSize;

  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);

  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);

  BasicL2capChannel channel = GetL2capChannel(proxy);

  // Construct and send fragment 1.
  {
    constexpr size_t kFirstFragmentHciSize =
        emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kFirstFragmentPayloadSize;
    std::array<uint8_t, kFirstFragmentHciSize> hci_first{};
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_first);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kFirstFragmentPayloadSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    bframe.pdu_length().Write(
        kL2capPayloadSize);  // The TOTAL payload size is 2045.
    bframe.channel_id().Write(kLocalCid);
    std::fill(bframe.payload().BackingStorage().begin(),
              bframe.payload().BackingStorage().end(),
              0xA5);

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_first};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // First fragment should be passed through to host.
    EXPECT_EQ(packets_sent_to_host_, 2);
  }

  // Construct and send fragment 2 (continuing fragment).
  {
    constexpr size_t kSecondFragmentHciSize =
        emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
        kSecondFragmentPayloadSize;
    std::array<uint8_t, kSecondFragmentHciSize> hci_cont{};
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_cont);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::CONTINUING_FRAGMENT);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(kSecondFragmentPayloadSize);

    std::fill(acl->payload().BackingStorage().begin(),
              acl->payload().BackingStorage().end(),
              0xA5);

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_cont};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // Second fragment should also be passed through to host.
    EXPECT_EQ(packets_sent_to_host_, 3);
  }

  // Channel should NOT have received anything.
  ExpectClientReceivedPayloadsAndClear({});
}

TEST_F(AclFragTest, RecombinationWorksWithSplitPayloads) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  BasicL2capChannel channel = GetL2capChannel(proxy);

  static constexpr std::array<uint8_t, 2> kPayloadFrag1 = {0xA1, 0xB2};
  static constexpr std::array<uint8_t, 2> kPayloadFrag2 = {0xC3, 0xD2};
  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  constexpr int kNumIter = 4;

  for (int i = 0; i < kNumIter; ++i) {
    // Fragment 1: ACL Header + L2CAP B-Frame Header + Payload frag 1
    PW_LOG_INFO("Sending frag 1: ACL + L2CAP header + payload1");
    SendL2capBFrame(proxy, kHandle, kPayloadFrag1, kPayload.size(), kLocalCid);

    // Fragment 2: ACL Header + Payload frag 2
    PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2");
    SendAclContinuingFrag(proxy, kHandle, kPayloadFrag2);
  }

  EXPECT_EQ(packets_sent_to_host_, 1);
  ExpectClientReceivedPayloadsAndClear({
      as_bytes(span(kPayload)),
      as_bytes(span(kPayload)),
      as_bytes(span(kPayload)),
      as_bytes(span(kPayload)),
  });

  VerifyNormalOperationAfterRecombination(proxy);
}

TEST_F(AclFragTest, UnexpectedContinuingFragment) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  BasicL2capChannel channel = GetL2capChannel(proxy);

  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  // Send an unexpected CONTINUING_FRAGMENT
  PW_LOG_INFO("Sending frag 1: ACL(CONT) + payload");
  SendAclContinuingFrag(proxy, kHandle, kPayload);

  ExpectClientReceivedPayloadsAndClear({});
  EXPECT_EQ(packets_sent_to_host_, 2);  // Should be passed on to host

  VerifyNormalOperationAfterRecombination(proxy);
}

TEST_F(AclFragTest, UnexpectedFirstFragment) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  BasicL2capChannel channel = GetL2capChannel(proxy);

  static constexpr std::array<uint8_t, 2> kPayloadFrag1 = {0xA1, 0xB2};
  static constexpr std::array<uint8_t, 2> kPayloadFrag2 = {0xC3, 0xD2};
  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  // PDU A: Fragment 1: Start recombination by sending first fragment.
  PW_LOG_INFO("Sending frag 1: ACL + L2CAP header + payload1");
  SendL2capBFrame(proxy, kHandle, {}, 100, kLocalCid);

  // We never send the 100 byte payload here.

  // So this new first-fragment is unexpected:
  // PDU B: Fragment 1: ACL Header + L2CAP B-Frame Header + Payload frag 1
  PW_LOG_INFO("Sending frag 1: ACL + L2CAP header + payload1");
  SendL2capBFrame(proxy, kHandle, kPayloadFrag1, kPayload.size(), kLocalCid);

  // PDU B: Fragment 2: ACL Header + Payload frag 2
  PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2");
  SendAclContinuingFrag(proxy, kHandle, kPayloadFrag2);

  // Nothing should be sent to the host. The first fragment of PDU A is dropped.
  EXPECT_EQ(packets_sent_to_host_, 1);

  // PDU B is delivered.
  ExpectClientReceivedPayloadsAndClear({
      as_bytes(span(kPayload)),
  });

  VerifyNormalOperationAfterRecombination(proxy);
}

TEST_F(AclFragTest, ContinuingFragmentTooLarge) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);
  BasicL2capChannel channel = GetL2capChannel(proxy);

  static constexpr std::array<uint8_t, 2> kPayloadFrag1 = {0xA1, 0xB2};
  static constexpr std::array<uint8_t, 5> kPayloadFrag2TooBig = {
      0xC3, 0xD2, 0xBA, 0xAA, 0xAD};
  static constexpr std::array<uint8_t, 4> kPayload = {0xA1, 0xB2, 0xC3, 0xD2};

  // Fragment 1: ACL Header + L2CAP B-Frame Header + Payload frag 1
  PW_LOG_INFO("Sending frag 1: ACL + L2CAP header + payload1");
  SendL2capBFrame(proxy, kHandle, kPayloadFrag1, kPayload.size(), kLocalCid);

  // Fragment 2: ACL Header + Payload frag 2
  PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2 (too big)");
  SendAclContinuingFrag(proxy, kHandle, kPayloadFrag2TooBig);

  ExpectClientReceivedPayloadsAndClear({});

  // This was for a channel owned by the proxy so it should have been dropped.
  EXPECT_EQ(packets_sent_to_host_, 1);

  VerifyNormalOperationAfterRecombination(proxy);
}

TEST_F(AclFragTest,
       CanReceiveUnfragmentedPduOnOneChannelWhileRecombiningOnAnother) {
  ProxyHost proxy = GetProxy();
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 1);

  // Channel 1
  static constexpr std::array<uint8_t, 2> kPayload1Frag1 = {0xA1, 0xB2};
  static constexpr std::array<uint8_t, 2> kPayload1Frag2 = {0xC3, 0xD2};
  static constexpr std::array<uint8_t, 4> kPayload1 = {0xA1, 0xB2, 0xC3, 0xD2};

  int channel1_sends_called = 0;
  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = kHandle,
          .local_cid = kLocalCid,
          .remote_cid = 0x123,
          .transport = AclTransportType::kLe,
          .payload_from_controller_fn =
              [&channel1_sends_called](multibuf::MultiBuf&& buffer) {
                ++channel1_sends_called;
                PW_ASSERT(!buffer.empty());
                ConstByteSpan payload = *buffer.ConstChunks().begin();
                ConstByteSpan expected_bytes = as_bytes(span(kPayload1));
                EXPECT_TRUE(std::equal(payload.begin(),
                                       payload.end(),
                                       expected_bytes.begin(),
                                       expected_bytes.end()));
                return std::nullopt;
              },
      });

  // Channel 2
  static constexpr uint16_t kHandle2 = 0x4D2;
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle2, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(packets_sent_to_host_, 2);
  static constexpr uint16_t kLocalCid2 = 0xC2D;
  static constexpr std::array<uint8_t, 4> kPayload2 = {0x33, 0x66, 0x99, 0xCC};

  int channel2_sends_called = 0;
  BasicL2capChannel channel2 = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = kHandle2,
          .local_cid = kLocalCid2,
          .remote_cid = 0x321,
          .transport = AclTransportType::kLe,
          .payload_from_controller_fn =
              [&channel2_sends_called](multibuf::MultiBuf&& buffer) {
                ++channel2_sends_called;
                PW_ASSERT(!buffer.empty());
                ConstByteSpan payload = *buffer.ConstChunks().begin();
                ConstByteSpan expected_bytes = as_bytes(span(kPayload2));
                EXPECT_TRUE(std::equal(payload.begin(),
                                       payload.end(),
                                       expected_bytes.begin(),
                                       expected_bytes.end()));
                return std::nullopt;
              },
      });

  // Channel 1: Fragment 1: ACL Header + L2CAP B-Frame Header + Payload frag 1
  PW_LOG_INFO("Sending frag 1: ACL + L2CAP header + payload1");
  SendL2capBFrame(proxy, kHandle, kPayload1Frag1, kPayload1.size(), kLocalCid);

  // Channel 2: Send full PDU
  SendL2capBFrame(proxy, kHandle2, kPayload2, kPayload2.size(), kLocalCid2);
  EXPECT_EQ(channel2_sends_called, 1);

  // Channel 1: Fragment 2: ACL Header + Payload frag 2
  PW_LOG_INFO("Sending frag 2: ACL(CONT) + payload2");
  SendAclContinuingFrag(proxy, kHandle, kPayload1Frag2);

  EXPECT_EQ(channel1_sends_called, 1);
  EXPECT_EQ(packets_sent_to_host_, 2);
}

TEST_F(ProxyHostTest, ClientProvidedAllocatorUsedForH4) {
  std::array<uint8_t, 100> payload = {};
  pw::allocator::test::AllocatorForTest<4096> allocator;

  struct {
    int sends_called = 0;
    pw::Vector<H4PacketWithH4, 5> sent_packets;
  } capture;

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      []([[maybe_unused]] H4PacketWithHci&& packet) {});
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [&capture](H4PacketWithH4&& packet) {
        ++capture.sends_called;
        capture.sent_packets.emplace_back(std::move(packet));
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/10,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              &allocator);
  StartDispatcherOnCurrentThread(proxy);
  size_t initial = allocator.GetAllocated();

  // Allow proxy to reserve 1 LE credit.
  PW_TEST_EXPECT_OK(SendLeReadBufferResponseFromController(proxy, 10));

  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  EXPECT_GT(allocator.GetAllocated(), initial);
  size_t allocated_for_connection = allocator.GetAllocated();

  constexpr uint16_t remote_channel_id = 0x1234;
  constexpr uint16_t local_channel_id = 0x4321;

  {
    BasicL2capChannel channel =
        BuildBasicL2capChannel(proxy,
                               {.handle = kConnectionHandle,
                                .local_cid = local_channel_id,
                                .remote_cid = remote_channel_id,
                                .transport = AclTransportType::kLe});

    auto mbuf_result = multibuf::FromSpan(
        allocator, as_writable_bytes(span(payload)), [](ByteSpan) {});
    ASSERT_TRUE(mbuf_result.has_value());
    multibuf::MultiBuf mbuf = std::move(*mbuf_result);
    PW_TEST_EXPECT_OK(channel.Write(std::move(mbuf)).status);
    RunDispatcher();
    EXPECT_EQ(capture.sends_called, 1);
  }
  EXPECT_GT(allocator.GetAllocated(),
            initial + allocated_for_connection + payload.size());

  capture.sent_packets.clear();
  proxy.Reset();
  EXPECT_EQ(allocator.GetAllocated(), initial);
}

TEST_F(ProxyHostTest, NotEnoughMemoryToAllocateConnection) {
  // Allocator is too small to hold connection state.
  pw::allocator::test::AllocatorForTest<0x600> allocator;

  size_t host_called = 0;
  pw::Function<void(H4PacketWithH4 && packet)> send_to_controller_fn(
      []([[maybe_unused]] H4PacketWithH4&& packet) {});

  pw::Function<void(H4PacketWithHci && packet)> send_to_host_fn(
      [&host_called]([[maybe_unused]] H4PacketWithHci&& packet) {
        ++host_called;
      });

  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              &allocator);
  StartDispatcherOnCurrentThread(proxy);

  // Connection should silently fail for connection complete events.
  allocator.Exhaust();
  PW_TEST_EXPECT_OK(SendLeConnectionCompleteEvent(
      proxy, kConnectionHandle, emboss::StatusCode::SUCCESS));
  EXPECT_EQ(host_called, 1U);

  Result<BasicL2capChannel> channel =
      BuildBasicL2capChannelWithResult(proxy,
                                       {.handle = kConnectionHandle,
                                        .local_cid = 0x123,
                                        .remote_cid = 0x456,
                                        .transport = AclTransportType::kLe});
  EXPECT_EQ(channel.status(), Status::InvalidArgument());
}

TEST_F(AclFragTest, UnhandledRecombinedPduBeforeMaxLeAclLengthKnown) {
  constexpr uint8_t kPayloadFragmentSize = 3;
  constexpr uint8_t kRecombinedPayloadSize = kPayloadFragmentSize * 2;
  std::array<uint8_t, kPayloadFragmentSize> payload_first = {0x04, 0x05, 0x06};
  std::array<uint8_t, kPayloadFragmentSize> payload_cont = {0x07, 0x08, 0x09};

  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kPayloadFragmentSize>
      hci_first{};
  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kPayloadFragmentSize>
      hci_cont{};

  std::array<uint8_t,
             emboss::AclDataFrameHeader::IntrinsicSizeInBytes() +
                 emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
                 kRecombinedPayloadSize>
      hci_recombined{};

  {
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_recombined);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kRecombinedPayloadSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    // We are going to send twice the expected payload (over two fragments).
    bframe.pdu_length().Write(kRecombinedPayloadSize);
    bframe.channel_id().Write(kLocalCid);
    std::copy(payload_first.begin(),
              payload_first.end(),
              bframe.payload().BackingStorage().begin());
    std::copy(payload_cont.begin(),
              payload_cont.end(),
              bframe.payload().BackingStorage().begin() + kPayloadFragmentSize);
  }

  struct {
    int channel_pdus_received = 0;
    int to_host_acls = 0;
    H4PacketWithHci h4;
  } capture{
      .h4 = H4PacketWithHci{emboss::H4PacketType::ACL_DATA, hci_recombined}};

  pw::Function<void(H4PacketWithHci && packet)>&& send_to_host_fn(
      [&capture](H4PacketWithHci&& packet) {
        if (packet.GetH4Type() == emboss::H4PacketType::EVENT) {
          return;
        }
        EXPECT_EQ(packet.GetH4Type(), emboss::H4PacketType::ACL_DATA);
        ++capture.to_host_acls;
        auto expected_hci = capture.h4.GetHciSpan();
        EXPECT_TRUE(std::equal(packet.GetHciSpan().begin(),
                               packet.GetHciSpan().end(),
                               expected_hci.begin(),
                               expected_hci.end()));
      });
  pw::Function<void(H4PacketWithH4 && packet)>&& send_to_controller_fn(
      [](H4PacketWithH4&&) {});
  ProxyHost proxy = ProxyHost(std::move(send_to_host_fn),
                              std::move(send_to_controller_fn),
                              /*le_acl_credits_to_reserve=*/0,
                              /*br_edr_acl_credits_to_reserve=*/0,
                              GetProxyHostAllocator());
  StartDispatcherOnCurrentThread(proxy);
  PW_TEST_ASSERT_OK(SendLeConnectionCompleteEvent(
      proxy, kHandle, emboss::StatusCode::SUCCESS));

  // IMPORTANT: No LE Read Buffer Size response is sent from the controller!

  BasicL2capChannel channel = BuildBasicL2capChannel(
      proxy,
      BasicL2capParameters{
          .handle = kHandle,
          .local_cid = kLocalCid,
          .payload_from_controller_fn =
              [&capture](multibuf::MultiBuf&& buffer) {
                capture.channel_pdus_received++;
                // Unhandled
                return multibuf::MultiBuf(std::move(buffer));
              },
      });

  EXPECT_EQ(capture.channel_pdus_received, 0);

  {
    // Define and send first fragment.
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_first);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    acl->data_total_length().Write(
        emboss::BasicL2capHeader::IntrinsicSizeInBytes() +
        kPayloadFragmentSize);

    emboss::BFrameWriter bframe = emboss::MakeBFrameView(
        acl->payload().BackingStorage().data(), acl->payload().SizeInBytes());
    bframe.pdu_length().Write(kRecombinedPayloadSize);
    bframe.channel_id().Write(kLocalCid);
    std::copy(payload_first.begin(),
              payload_first.end(),
              bframe.payload().BackingStorage().begin());

    std::array<uint8_t, hci_first.size()> hci_send{};
    std::copy(hci_first.begin(), hci_first.end(), hci_send.begin());

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_send};
    proxy.HandleH4HciFromController(std::move(h4_send));
    EXPECT_EQ(capture.to_host_acls, 0);
    EXPECT_EQ(capture.channel_pdus_received, 0);
  }

  {
    // Define and send 2nd fragment.
    Result<emboss::AclDataFrameWriter> acl =
        MakeEmbossWriter<emboss::AclDataFrameWriter>(hci_cont);
    acl->header().handle().Write(kHandle);
    acl->header().packet_boundary_flag().Write(
        emboss::AclDataPacketBoundaryFlag::CONTINUING_FRAGMENT);
    acl->header().broadcast_flag().Write(
        emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
    // Just contains the 2nd payload with no l2cap headers.
    acl->data_total_length().Write(kPayloadFragmentSize);

    // Entire ACL payload is just the fragment.
    std::copy(payload_cont.begin(),
              payload_cont.end(),
              acl->payload().BackingStorage().begin());

    std::array<uint8_t, hci_cont.size()> hci_send{};
    std::copy(hci_cont.begin(), hci_cont.end(), hci_send.begin());

    H4PacketWithHci h4_send{emboss::H4PacketType::ACL_DATA, hci_send};
    proxy.HandleH4HciFromController(std::move(h4_send));

    // Recombined ACL packet should be delivered to host since channel rejected
    // it.
    EXPECT_EQ(capture.to_host_acls, 1);
    // Channel received the PDU, but rejected it.
    EXPECT_EQ(capture.channel_pdus_received, 1);
  }
}

}  // namespace
}  // namespace pw::bluetooth::proxy
