// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/connectivity/bluetooth/core/bt-host/common/log.h"
#include "src/connectivity/bluetooth/core/bt-host/common/slab_allocator.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel_test.h"
#include "src/connectivity/bluetooth/core/bt-host/rfcomm/channel_manager.h"

namespace bt {
namespace rfcomm {
namespace {

constexpr l2cap::ChannelId kL2CAPChannelId = 0x0040;
constexpr hci::ConnectionHandle kHandle1 = 1;

void DoNothingWithChannel(fbl::RefPtr<Channel> channel,
                          ServerChannel server_channel) {}

void DoNothingWithBuffer(ByteBufferPtr buffer) {}

class RFCOMM_ChannelManagerTest : public l2cap::testing::FakeChannelTest {
 public:
  RFCOMM_ChannelManagerTest() : channel_manager_(nullptr) {}
  ~RFCOMM_ChannelManagerTest() override = default;

 protected:
  // Captures the state of the fake remote peer.
  struct PeerState {
    // Whether this peer supports credit-based flow. This bool also indicates
    // whether the session with this peer will have credit-based flow turned on;
    // our RFCOMM implementation will always turn on credit-based flow if the
    // peer supports it.
    bool credit_based_flow;
    Role role;
  };

  void SetUp() override {
    channel_manager_ = std::make_unique<ChannelManager>(fit::bind_member(
        this, &RFCOMM_ChannelManagerTest::OpenRfcommL2capChannel));
    ZX_DEBUG_ASSERT(channel_manager_);
  }

  void TearDown() override {
    channel_manager_ = nullptr;
    handle_to_peer_state_.clear();
    handle_to_fake_channel_.clear();
    handle_to_incoming_frames_.clear();
  }

  // Fake channels are captured and stored in |handle_to_fake_channel_|.
  // Subsequently, all channels will have listeners attached to them, and any
  // frames sent from our RFCOMM sessions will be put into the queues in
  // |handle_to_incoming_frames_|.
  fbl::RefPtr<l2cap::testing::FakeChannel> CreateFakeL2capChannel(
      hci::ConnectionHandle handle) {
    ChannelOptions options(kL2CAPChannelId);
    options.conn_handle = handle;
    options.link_type = hci::Connection::LinkType::kACL;

    auto chan = CreateFakeChannel(options);
    ZX_DEBUG_ASSERT(chan);
    handle_to_fake_channel_.emplace(handle, chan);
    chan->SetSendCallback(
        [this, handle](auto sdu) {
          if (handle_to_incoming_frames_.find(handle) ==
              handle_to_incoming_frames_.end()) {
            handle_to_incoming_frames_.emplace(
                handle, std::queue<std::unique_ptr<const ByteBuffer>>());
          }
          handle_to_incoming_frames_[handle].push(std::move(sdu));
        },
        dispatcher());

    return chan;
  }

  // Called by ChannelManager::OpenRemoteChannel().
  void OpenRfcommL2capChannel(hci::ConnectionHandle handle,
                              l2cap::ChannelCallback cb) {
    auto chan = CreateFakeL2capChannel(handle);
    async::PostTask(dispatcher(), [chan, cb = std::move(cb)] { cb(chan); });
  }

  // Emplace a new PeerState for a new fake peer. Should be called for each fake
  // peer which a test is emulating. The returned PeerState should then be
  // updated throughout the test (e.g. the multiplexer state should change when
  // the multiplexer starts up).
  PeerState& AddFakePeerState(hci::ConnectionHandle handle, PeerState state) {
    ZX_DEBUG_ASSERT(handle_to_peer_state_.find(handle) ==
                    handle_to_peer_state_.end());
    handle_to_peer_state_.emplace(handle, std::move(state));
    return handle_to_peer_state_[handle];
  }

  fbl::RefPtr<l2cap::testing::FakeChannel> GetFakeChannel(
      hci::ConnectionHandle handle) {
    ZX_DEBUG_ASSERT(handle_to_fake_channel_.find(handle) !=
                    handle_to_fake_channel_.end());
    return handle_to_fake_channel_[handle];
  }

  void ExpectFrame(hci::ConnectionHandle handle, FrameType type, DLCI dlci) {
    auto queue_it = handle_to_incoming_frames_.find(handle);
    EXPECT_FALSE(handle_to_incoming_frames_.end() == queue_it);

    EXPECT_FALSE(handle_to_peer_state_.find(handle) ==
                 handle_to_peer_state_.end());
    const PeerState& state = handle_to_peer_state_[handle];

    auto frame = Frame::Parse(state.credit_based_flow, OppositeRole(state.role),
                              queue_it->second.front()->view());
    queue_it->second.pop();
    ASSERT_TRUE(frame);
    EXPECT_EQ(type, static_cast<FrameType>(frame->control()));
    EXPECT_EQ(dlci, frame->dlci());
  }

  void ReceiveFrame(hci::ConnectionHandle handle,
                    std::unique_ptr<Frame> frame) {
    auto channel = GetFakeChannel(handle);

    auto buffer = NewSlabBuffer(frame->written_size());
    frame->Write(buffer->mutable_view());
    channel->Receive(buffer->view());
  }

  // Makes the asynchronous channel-getting process synchronous, for the
  // purposes of writing clean tests. This function will imitiate (to
  // |channel_manager_|) an RFCOMM peer, and will send frames to handle
  // multiplexer startup, optional parameter negotiation, and finally, channel
  // opening.
  //
  // If this is the first channel which will be opened on this handle,
  // the state of the peer should first be set in |handle_to_peer_state_|.
  // These state variables will then be used during the session startup
  // procedure which will ensue.
  fbl::RefPtr<Channel> OpenOutgoingChannel(hci::ConnectionHandle handle,
                                           ServerChannel server_channel);

  // The fake remote peer represented by |handle| attempts to open
  // |server_channel|. If no session exists, this function will handle session
  // startup, multiplexer startup, and parameter negotiation.
  void OpenIncomingChannel(hci::ConnectionHandle handle,
                           ServerChannel server_channel);

  std::unique_ptr<ChannelManager> channel_manager_;

  std::unordered_map<hci::ConnectionHandle,
                     std::queue<std::unique_ptr<const ByteBuffer>>>
      handle_to_incoming_frames_;

  // Maps remote peers (represented as connection handles) to the L2CAP channel
  // (actually a FakeChannel) over which the corresponding RFCOMM session
  // communicates with that peer.
  std::unordered_map<hci::ConnectionHandle,
                     fbl::RefPtr<l2cap::testing::FakeChannel>>
      handle_to_fake_channel_;

  // Holds the state of the fake peers. Tests must manually update this
  // information as needed; for example, if a test mimics mux startup manually,
  // it must change its role accordingly, otherwise utility functions like
  // ExpectFrame() will not parse frames correctly.
  std::unordered_map<hci::ConnectionHandle, PeerState> handle_to_peer_state_;
};

fbl::RefPtr<Channel> RFCOMM_ChannelManagerTest::OpenOutgoingChannel(
    hci::ConnectionHandle handle, ServerChannel server_channel) {
  ZX_DEBUG_ASSERT_MSG(
      handle_to_peer_state_.find(handle) != handle_to_peer_state_.end(),
      "no peer state set for handle %#.4x", handle);
  PeerState& state = handle_to_peer_state_[handle];

  fbl::RefPtr<Channel> return_channel = nullptr;
  channel_manager_->OpenRemoteChannel(
      handle, server_channel,
      [&return_channel](auto channel, auto server_channel) {
        return_channel = channel;
      },
      dispatcher());
  RunLoopUntilIdle();

  ZX_DEBUG_ASSERT(handle_to_fake_channel_.find(handle) !=
                  handle_to_fake_channel_.end());
  EXPECT_FALSE(handle_to_incoming_frames_.find(handle) ==
               handle_to_incoming_frames_.end());
  auto& queue = handle_to_incoming_frames_[handle];

  EXPECT_FALSE(queue.empty());
  auto frame =
      Frame::Parse(state.credit_based_flow, state.role, queue.front()->view());

  queue.pop();
  ZX_DEBUG_ASSERT(frame);

  // If we received a mux startup request, respond to it.
  if (static_cast<FrameType>(frame->control()) ==
          FrameType::kSetAsynchronousBalancedMode &&
      frame->dlci() == kMuxControlDLCI) {
    ReceiveFrame(handle, std::make_unique<UnnumberedAcknowledgementResponse>(
                             state.role, kMuxControlDLCI));

    state.role = Role::kResponder;

    RunLoopUntilIdle();

    // Expect that another frame has arrived.
    EXPECT_FALSE(queue.empty());
    frame = Frame::Parse(state.credit_based_flow, state.role,
                         queue.front()->view());
    queue.pop();
  }

  // If we received a parameter negotiation request, respond to it.
  if (static_cast<FrameType>(frame->control()) ==
          FrameType::kUnnumberedInfoHeaderCheck &&
      frame->dlci() == kMuxControlDLCI) {
    auto pn_command_mux_command =
        static_cast<MuxCommandFrame*>(frame.get())->TakeMuxCommand();
    EXPECT_EQ(MuxCommandType::kDLCParameterNegotiation,
              pn_command_mux_command->command_type());
    EXPECT_EQ(CommandResponse::kCommand,
              pn_command_mux_command->command_response());

    auto pn_command = std::unique_ptr<DLCParameterNegotiationCommand>(
        static_cast<DLCParameterNegotiationCommand*>(
            pn_command_mux_command.release()));

    // For now, just send back the same parameters (making sure to send the
    // correct credit-based flow response based on our credit-based flow
    // setting).
    ParameterNegotiationParams params = pn_command->params();
    params.credit_based_flow_handshake =
        state.credit_based_flow ? CreditBasedFlowHandshake::kSupportedResponse
                                : CreditBasedFlowHandshake::kUnsupported;

    // Give max credits
    params.initial_credits = kMaxInitialCredits;

    ReceiveFrame(handle, std::make_unique<MuxCommandFrame>(
                             state.role, state.credit_based_flow,
                             std::make_unique<DLCParameterNegotiationCommand>(
                                 CommandResponse::kResponse, params)));

    RunLoopUntilIdle();

    // Expect that another frame has arrived.
    EXPECT_FALSE(queue.empty());
    frame = Frame::Parse(state.credit_based_flow, state.role,
                         queue.front()->view());
    queue.pop();
  }

  EXPECT_EQ(FrameType::kSetAsynchronousBalancedMode,
            FrameType(frame->control()));
  DLCI dlci = ServerChannelToDLCI(server_channel, state.role);
  EXPECT_EQ(dlci, frame->dlci());

  ReceiveFrame(handle, std::make_unique<UnnumberedAcknowledgementResponse>(
                           state.role, dlci));

  RunLoopUntilIdle();

  EXPECT_TRUE(return_channel);

  return return_channel;
}

void RFCOMM_ChannelManagerTest::OpenIncomingChannel(
    hci::ConnectionHandle handle, ServerChannel server_channel) {
  ZX_DEBUG_ASSERT_MSG(
      handle_to_peer_state_.find(handle) != handle_to_peer_state_.end(),
      "no peer state set for handle %#.4x", handle);

  PeerState& state = handle_to_peer_state_[handle];

  if (handle_to_fake_channel_.find(handle) == handle_to_fake_channel_.end()) {
    channel_manager_->RegisterL2CAPChannel(CreateFakeL2capChannel(handle));
    RunLoopUntilIdle();

    // If channel didn't exist, then we need to do mux startup and parameter
    // negotiation.
    auto l2cap_channel = GetFakeChannel(handle);

    ReceiveFrame(handle, std::make_unique<SetAsynchronousBalancedModeCommand>(
                             Role::kUnassigned, kMuxControlDLCI));
    RunLoopUntilIdle();
    ExpectFrame(handle, FrameType::kUnnumberedAcknowledgement, kMuxControlDLCI);
    state.role = Role::kInitiator;

    DLCI dlci = ServerChannelToDLCI(server_channel, OppositeRole(state.role));

    // Send parameter negotiation
    ParameterNegotiationParams params;
    params.dlci = dlci;
    params.credit_based_flow_handshake =
        CreditBasedFlowHandshake::kSupportedRequest;
    params.priority = 61;
    params.maximum_frame_size =
        l2cap_channel->rx_mtu() < l2cap_channel->tx_mtu()
            ? l2cap_channel->rx_mtu()
            : l2cap_channel->tx_mtu();
    params.initial_credits = kMaxInitialCredits;
    ReceiveFrame(handle, std::make_unique<MuxCommandFrame>(
                             state.role, state.credit_based_flow,
                             std::make_unique<DLCParameterNegotiationCommand>(
                                 CommandResponse::kCommand, params)));
    RunLoopUntilIdle();

    // Expect parameter negotiation response
    EXPECT_TRUE(handle_to_incoming_frames_[handle].size());
    auto frame =
        Frame::Parse(state.credit_based_flow, state.role,
                     handle_to_incoming_frames_[handle].front()->view());
    handle_to_incoming_frames_[handle].pop();
    EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
              static_cast<FrameType>(frame->control()));
    EXPECT_EQ(kMuxControlDLCI, frame->dlci());
    auto mux_command =
        static_cast<MuxCommandFrame*>(frame.get())->TakeMuxCommand();
    EXPECT_EQ(MuxCommandType::kDLCParameterNegotiation,
              mux_command->command_type());
    EXPECT_EQ(CommandResponse::kResponse, mux_command->command_response());
  }

  // Otherwise, a session must already exist with this remote peer. We can
  // furthermore assume that a channel must be open, and thus that the
  // multiplexer has also been started, and parameter negotiation is complete.

  DLCI dlci = ServerChannelToDLCI(server_channel, OppositeRole(state.role));

  // Send SABM.
  ReceiveFrame(handle, std::make_unique<SetAsynchronousBalancedModeCommand>(
                           state.role, dlci));
  RunLoopUntilIdle();

  // Expect UA response.
  ExpectFrame(handle, FrameType::kUnnumberedAcknowledgement, dlci);
}
// Expect that registration of an L2CAP channel with the Channel Manager results
// in the L2CAP channel's eventual activation.
TEST_F(RFCOMM_ChannelManagerTest, RegisterL2CAPChannel) {
  auto l2cap_channel = CreateFakeL2capChannel(kHandle1);
  EXPECT_TRUE(channel_manager_->RegisterL2CAPChannel(l2cap_channel));
  EXPECT_TRUE(l2cap_channel->activated());
}

// Test that command timeouts during multiplexer startup result in the session
// being closed down.
TEST_F(RFCOMM_ChannelManagerTest, MuxStartupAndParamNegotiation_Timeout) {
  AddFakePeerState(kHandle1, PeerState{true /*credits*/, Role::kUnassigned});

  channel_manager_->OpenRemoteChannel(kHandle1, kMinServerChannel,
                                      &DoNothingWithChannel, dispatcher());
  RunLoopUntilIdle();

  auto channel = GetFakeChannel(kHandle1);

  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode,
              kMuxControlDLCI);

  // Do nothing
  RunLoopFor(zx::min(5));

  // Expect closedown after timeout
  EXPECT_FALSE(channel->activated());
}

// Test successful multiplexer startup (resulting role: responder).
TEST_F(RFCOMM_ChannelManagerTest, MuxStartupAndParamNegotiation_Responder) {
  AddFakePeerState(kHandle1, PeerState{true /*credits*/, Role::kUnassigned});

  channel_manager_->RegisterL2CAPChannel(CreateFakeL2capChannel(kHandle1));
  RunLoopUntilIdle();

  // Receive a multiplexer startup frame on the session
  ReceiveFrame(kHandle1, std::make_unique<SetAsynchronousBalancedModeCommand>(
                             Role::kUnassigned, kMuxControlDLCI));
  RunLoopUntilIdle();

  ExpectFrame(kHandle1, FrameType::kUnnumberedAcknowledgement, kMuxControlDLCI);
}

// Test successful multiplexer startup (resulting role: initiator)
TEST_F(RFCOMM_ChannelManagerTest, MuxStartupAndParamNegotiation_Initiator) {
  auto& state = AddFakePeerState(
      kHandle1, PeerState{true /*credits*/, Role::kUnassigned});

  bool channel_received = false;
  fbl::RefPtr<Channel> channel;
  channel_manager_->OpenRemoteChannel(
      kHandle1, kMinServerChannel,
      [&channel, &channel_received](auto ch, auto server_channel) {
        channel_received = true;
        channel = ch;
      },
      dispatcher());
  RunLoopUntilIdle();

  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode,
              kMuxControlDLCI);

  // Receive a UA on the session
  ReceiveFrame(kHandle1, std::make_unique<UnnumberedAcknowledgementResponse>(
                             Role::kUnassigned, kMuxControlDLCI));
  RunLoopUntilIdle();

  state.role = Role::kResponder;
  DLCI dlci = ServerChannelToDLCI(kMinServerChannel, state.role);

  {
    // Expect a PN command from the session
    auto queue_it = handle_to_incoming_frames_.find(kHandle1);
    EXPECT_FALSE(queue_it == handle_to_incoming_frames_.end());
    EXPECT_EQ(1ul, queue_it->second.size());
    auto frame = Frame::Parse(true, OppositeRole(state.role),
                              queue_it->second.front()->view());
    queue_it->second.pop();
    EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
              static_cast<FrameType>(frame->control()));
    auto mux_command =
        static_cast<MuxCommandFrame*>(frame.get())->TakeMuxCommand();
    EXPECT_EQ(MuxCommandType::kDLCParameterNegotiation,
              mux_command->command_type());

    auto params =
        static_cast<DLCParameterNegotiationCommand*>(mux_command.get())
            ->params();
    EXPECT_EQ(dlci, params.dlci);
    params.credit_based_flow_handshake =
        CreditBasedFlowHandshake::kSupportedResponse;

    // Receive PN response
    ReceiveFrame(kHandle1, std::make_unique<MuxCommandFrame>(
                               state.role, true,
                               std::make_unique<DLCParameterNegotiationCommand>(
                                   CommandResponse::kResponse, params)));
    RunLoopUntilIdle();
  }

  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode, dlci);
  ReceiveFrame(kHandle1, std::make_unique<UnnumberedAcknowledgementResponse>(
                             state.role, dlci));
  RunLoopUntilIdle();

  EXPECT_TRUE(channel_received);
  EXPECT_TRUE(channel);
}

// Test multiplexer startup conflict procedure (resulting role: initiator).
TEST_F(RFCOMM_ChannelManagerTest,
       MuxStartupAndParamNegotiation_Conflict_BecomeInitiator) {
  auto& state = AddFakePeerState(
      kHandle1, PeerState{true /*credits*/, Role::kUnassigned});

  bool channel_received = false;
  fbl::RefPtr<Channel> channel;
  channel_manager_->OpenRemoteChannel(
      kHandle1, kMinServerChannel,
      [&channel, &channel_received](auto ch, auto server_channel) {
        channel_received = true;
        channel = ch;
      },
      dispatcher());
  RunLoopUntilIdle();

  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode,
              kMuxControlDLCI);

  // Receive a conflicting SABM on the session
  ReceiveFrame(kHandle1, std::make_unique<SetAsynchronousBalancedModeCommand>(
                             state.role, kMuxControlDLCI));
  RunLoopUntilIdle();

  ExpectFrame(kHandle1, FrameType::kDisconnectedMode, kMuxControlDLCI);

  // Wait and expect a SABM
  RunLoopFor(zx::sec(5));
  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode,
              kMuxControlDLCI);

  // Receive a UA on the session
  ReceiveFrame(kHandle1, std::make_unique<UnnumberedAcknowledgementResponse>(
                             state.role, kMuxControlDLCI));
  RunLoopUntilIdle();

  state.role = Role::kResponder;
  DLCI dlci = ServerChannelToDLCI(kMinServerChannel, state.role);

  {
    // Expect a PN command from the session
    auto queue_it = handle_to_incoming_frames_.find(kHandle1);
    EXPECT_FALSE(queue_it == handle_to_incoming_frames_.end());
    EXPECT_EQ(1ul, queue_it->second.size());
    auto frame = Frame::Parse(true, OppositeRole(state.role),
                              queue_it->second.front()->view());
    queue_it->second.pop();
    EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
              static_cast<FrameType>(frame->control()));
    auto mux_command =
        static_cast<MuxCommandFrame*>(frame.get())->TakeMuxCommand();
    EXPECT_EQ(MuxCommandType::kDLCParameterNegotiation,
              mux_command->command_type());

    auto params =
        static_cast<DLCParameterNegotiationCommand*>(mux_command.get())
            ->params();
    EXPECT_EQ(dlci, params.dlci);
    params.credit_based_flow_handshake =
        CreditBasedFlowHandshake::kSupportedResponse;

    // Receive PN response
    ReceiveFrame(kHandle1, std::make_unique<MuxCommandFrame>(
                               state.role, true,
                               std::make_unique<DLCParameterNegotiationCommand>(
                                   CommandResponse::kResponse, params)));
    RunLoopUntilIdle();
  }

  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode, dlci);
  ReceiveFrame(kHandle1, std::make_unique<UnnumberedAcknowledgementResponse>(
                             state.role, dlci));
  RunLoopUntilIdle();

  EXPECT_TRUE(channel_received);
  EXPECT_TRUE(channel);
}

// Test multiplexer startup conflict procedure (resulting role: responder).
TEST_F(RFCOMM_ChannelManagerTest,
       MuxStartupAndParamNegotiation_Conflict_BecomeResponder) {
  auto& state = AddFakePeerState(
      kHandle1, PeerState{true /*credits*/, Role::kUnassigned});

  bool channel_delivered = false;
  channel_manager_->OpenRemoteChannel(
      kHandle1, kMinServerChannel,
      [&channel_delivered](auto channel, auto server_channel) {
        channel_delivered = true;
      },
      dispatcher());
  RunLoopUntilIdle();

  // Expect initial mux-opening SABM
  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode,
              kMuxControlDLCI);

  // Receive a conflicting SABM on the session
  state.role = Role::kNegotiating;
  ReceiveFrame(kHandle1, std::make_unique<SetAsynchronousBalancedModeCommand>(
                             state.role, kMuxControlDLCI));
  RunLoopUntilIdle();

  // Expect a DM frame from the session
  ExpectFrame(kHandle1, FrameType::kDisconnectedMode, kMuxControlDLCI);

  // Immediately receive another SABM on the session
  ReceiveFrame(kHandle1, std::make_unique<SetAsynchronousBalancedModeCommand>(
                             state.role, kMuxControlDLCI));
  RunLoopUntilIdle();

  // Expect UA
  ExpectFrame(kHandle1, FrameType::kUnnumberedAcknowledgement, kMuxControlDLCI);
  state.role = Role::kInitiator;

  {
    // Expect a PN command from the session
    EXPECT_FALSE(handle_to_incoming_frames_.find(kHandle1) ==
                 handle_to_incoming_frames_.end());
    auto& queue = handle_to_incoming_frames_[kHandle1];
    EXPECT_EQ(1ul, queue.size());
    auto frame = Frame::Parse(state.credit_based_flow, OppositeRole(state.role),
                              queue.front()->view());
    queue.pop();
    EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
              static_cast<FrameType>(frame->control()));
    DLCI dlci = ServerChannelToDLCI(kMinServerChannel, state.role);
    auto mux_command =
        static_cast<MuxCommandFrame*>(frame.get())->TakeMuxCommand();
    EXPECT_EQ(MuxCommandType::kDLCParameterNegotiation,
              mux_command->command_type());

    auto params =
        static_cast<DLCParameterNegotiationCommand*>(mux_command.get())
            ->params();
    EXPECT_EQ(dlci, params.dlci);
    params.credit_based_flow_handshake =
        CreditBasedFlowHandshake::kSupportedResponse;

    // Receive PN response
    ReceiveFrame(kHandle1, std::make_unique<MuxCommandFrame>(
                               state.role, true,
                               std::make_unique<DLCParameterNegotiationCommand>(
                                   CommandResponse::kResponse, params)));
    RunLoopUntilIdle();
  }

  // EXPECT_TRUE(channel_received);
  // EXPECT_FALSE(channel);
}

// Tests whether sessions handle invalid max frame sizes correctly.
TEST_F(RFCOMM_ChannelManagerTest,
       MuxStartupAndParamNegotiation_BadPN_InvalidMaxFrameSize) {
  auto& state = AddFakePeerState(
      kHandle1, PeerState{true /*credits*/, Role::kUnassigned});

  bool channel_delivered = false;
  channel_manager_->OpenRemoteChannel(
      kHandle1, kMinServerChannel,
      [&channel_delivered](auto channel, auto server_channel) {
        channel_delivered = true;
      },
      dispatcher());
  RunLoopUntilIdle();

  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode,
              kMuxControlDLCI);

  // Receive a UA on the session
  ReceiveFrame(kHandle1, std::make_unique<UnnumberedAcknowledgementResponse>(
                             state.role, kMuxControlDLCI));
  RunLoopUntilIdle();

  state.role = Role::kResponder;
  DLCI dlci = ServerChannelToDLCI(kMinServerChannel, state.role);

  {
    // Expect a PN command from the session
    EXPECT_FALSE(handle_to_incoming_frames_.find(kHandle1) ==
                 handle_to_incoming_frames_.end());
    auto& queue = handle_to_incoming_frames_[kHandle1];
    EXPECT_EQ(1ul, queue.size());
    auto frame = Frame::Parse(state.credit_based_flow, OppositeRole(state.role),
                              queue.front()->view());
    queue.pop();
    EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
              static_cast<FrameType>(frame->control()));
    DLCI dlci = ServerChannelToDLCI(kMinServerChannel, state.role);
    auto mux_command =
        static_cast<MuxCommandFrame*>(frame.get())->TakeMuxCommand();
    EXPECT_EQ(MuxCommandType::kDLCParameterNegotiation,
              mux_command->command_type());

    // Create invalid parameters.
    auto params =
        static_cast<DLCParameterNegotiationCommand*>(mux_command.get())
            ->params();
    EXPECT_EQ(dlci, params.dlci);
    params.credit_based_flow_handshake =
        CreditBasedFlowHandshake::kSupportedResponse;
    // Request a larger max frame size than what was proposed.
    params.maximum_frame_size += 1;

    // Receive PN response
    ReceiveFrame(kHandle1, std::make_unique<MuxCommandFrame>(
                               OppositeRole(state.role), true,
                               std::make_unique<DLCParameterNegotiationCommand>(
                                   CommandResponse::kResponse, params)));
    RunLoopUntilIdle();
  }

  ExpectFrame(kHandle1, FrameType::kDisconnect, dlci);
}

// A DM response to a mux SABM shouldn't crash (but shouldn't do anything else).
TEST_F(RFCOMM_ChannelManagerTest,
       MuxStartupAndParamNegotiation_RejectMuxStartup) {
  AddFakePeerState(kHandle1, PeerState{true /*credits*/, Role::kUnassigned});

  bool channel_delivered = false;
  channel_manager_->OpenRemoteChannel(
      kHandle1, kMinServerChannel,
      [&channel_delivered](auto channel, auto server_channel) {
        channel_delivered = true;
      },
      dispatcher());
  RunLoopUntilIdle();

  ExpectFrame(kHandle1, FrameType::kSetAsynchronousBalancedMode,
              kMuxControlDLCI);

  // Receive a DM on the session
  ReceiveFrame(kHandle1, std::make_unique<DisconnectedModeResponse>(
                             Role::kUnassigned, kMuxControlDLCI));
  RunLoopUntilIdle();
}

TEST_F(RFCOMM_ChannelManagerTest, OpenOutgoingChannel) {
  handle_to_peer_state_.emplace(kHandle1, PeerState{true, Role::kUnassigned});
  PeerState& state = handle_to_peer_state_[kHandle1];

  auto channel = OpenOutgoingChannel(kHandle1, kMinServerChannel);
  EXPECT_TRUE(channel);

  DLCI dlci = ServerChannelToDLCI(kMinServerChannel, state.role);

  ByteBufferPtr received_data;
  channel->Activate(
      [&received_data](auto data) { received_data = std::move(data); }, []() {},
      dispatcher());

  auto pattern = CreateStaticByteBuffer(1, 2, 3, 4);
  auto buffer = std::make_unique<DynamicByteBuffer>(pattern);
  channel->Send(std::move(buffer));
  RunLoopUntilIdle();

  auto frame =
      Frame::Parse(state.credit_based_flow, OppositeRole(state.role),
                   handle_to_incoming_frames_[kHandle1].front()->view());
  EXPECT_TRUE(frame);
  EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
            static_cast<FrameType>(frame->control()));
  EXPECT_EQ(dlci, frame->dlci());
  EXPECT_EQ(pattern,
            *static_cast<UserDataFrame*>(frame.get())->TakeInformation());

  buffer = std::make_unique<DynamicByteBuffer>(pattern);
  ReceiveFrame(kHandle1, std::make_unique<UserDataFrame>(
                             state.role, state.credit_based_flow, dlci,
                             std::move(buffer)));
  RunLoopUntilIdle();

  EXPECT_TRUE(received_data);
  EXPECT_EQ(pattern, *received_data);
}

TEST_F(RFCOMM_ChannelManagerTest, OpenIncomingChannel) {
  auto& state = AddFakePeerState(
      kHandle1, PeerState{true /* credit-based flow */, Role::kUnassigned});

  fbl::RefPtr<Channel> channel;
  auto server_channel = channel_manager_->AllocateLocalChannel(
      [&channel](auto received_channel, auto) { channel = received_channel; },
      dispatcher());

  bt_log(SPEW, "unittests", "rfcomm allocated channel %d", server_channel);

  OpenIncomingChannel(kHandle1, server_channel);
  RunLoopUntilIdle();
  ASSERT_TRUE(channel);

  DLCI dlci = ServerChannelToDLCI(server_channel, OppositeRole(state.role));

  ByteBufferPtr received_data;
  channel->Activate(
      [&received_data](auto data) { received_data = std::move(data); }, []() {},
      dispatcher());

  auto pattern = CreateStaticByteBuffer(1, 2, 3, 4);
  auto buffer = std::make_unique<DynamicByteBuffer>(pattern);
  channel->Send(std::move(buffer));
  RunLoopUntilIdle();

  auto frame =
      Frame::Parse(state.credit_based_flow, OppositeRole(state.role),
                   handle_to_incoming_frames_[kHandle1].front()->view());
  ASSERT_TRUE(frame);
  EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
            static_cast<FrameType>(frame->control()));
  EXPECT_EQ(dlci, frame->dlci());
  EXPECT_EQ(pattern,
            *static_cast<UserDataFrame*>(frame.get())->TakeInformation());

  buffer = std::make_unique<DynamicByteBuffer>(pattern);
  ReceiveFrame(kHandle1, std::make_unique<UserDataFrame>(
                             state.role, state.credit_based_flow, dlci,
                             std::move(buffer)));
  RunLoopUntilIdle();

  EXPECT_TRUE(received_data);
  EXPECT_EQ(pattern, *received_data);
}

// In this test, we test outgoing credit-based flow with the following series of
// actions:
// (We begin with kInitialMaxCredits (7) credits)
// 1. Send 7 frames and ensure they all sent.
// 2. Send 1 more frame and ensure it didn't send.
// 3. Give 2 credits and ensure the frame above sent.
// 4. Send 3 frames and ensure that just 1 of them sent.
// 5. Give 1 credit and ensure that 1 more of the above 3 sent.
// 6. Give 100 credits and ensure that the last of the above 3 sent.
TEST_F(RFCOMM_ChannelManagerTest, CreditBasedFlow_Outgoing) {
  PeerState& state = AddFakePeerState(
      kHandle1, PeerState{true /*credit-based flow*/, Role::kUnassigned});

  auto channel = OpenOutgoingChannel(kHandle1, kMinServerChannel);
  channel->Activate(
      &DoNothingWithBuffer, [] {}, dispatcher());

  auto& queue = handle_to_incoming_frames_[kHandle1];

  for (uint8_t i = 0; i < kMaxInitialCredits; i++) {
    // Send UIH frame with data.
    channel->Send(NewBuffer(i));
    RunLoopUntilIdle();
  }

  // Expect that all of those frames sent.
  EXPECT_EQ(7ul, queue.size());

  {
    // Send one more.
    channel->Send(NewBuffer(7));
    RunLoopUntilIdle();
  }

  // Expect that the last frame didn't send.
  EXPECT_EQ(7ul, queue.size());

  {
    // Replenish credits.
    auto frame = std::make_unique<UserDataFrame>(
        state.role, state.credit_based_flow,
        ServerChannelToDLCI(kMinServerChannel, state.role), nullptr);
    frame->set_credits(2);
    ReceiveFrame(kHandle1, std::move(frame));
    RunLoopUntilIdle();
  }

  // Expect that the last frame sent.
  EXPECT_EQ(8ul, queue.size());

  for (uint8_t i = 0; i < 3; i++) {
    channel->Send(NewBuffer(8 + i));
    RunLoopUntilIdle();
  }

  // Expect that only one of the above frames sent.
  EXPECT_EQ(9ul, queue.size());

  {
    // Replenish no credits.
    auto frame = std::make_unique<UserDataFrame>(
        state.role, state.credit_based_flow,
        ServerChannelToDLCI(kMinServerChannel, state.role), nullptr);
    frame->set_credits(0);
    ReceiveFrame(kHandle1, std::move(frame));
    RunLoopUntilIdle();
  }

  // No more frames should have sent.
  EXPECT_EQ(9ul, queue.size());

  {
    // Replenish just one credit.
    auto frame = std::make_unique<UserDataFrame>(
        state.role, state.credit_based_flow,
        ServerChannelToDLCI(kMinServerChannel, state.role), nullptr);
    frame->set_credits(1);
    ReceiveFrame(kHandle1, std::move(frame));
    RunLoopUntilIdle();
  }

  // Just one more frame should have sent.
  EXPECT_EQ(10ul, queue.size());

  {
    // Replenish a lot of credits.
    auto frame = std::make_unique<UserDataFrame>(
        state.role, state.credit_based_flow,
        ServerChannelToDLCI(kMinServerChannel, state.role), nullptr);
    frame->set_credits(100);
    ReceiveFrame(kHandle1, std::move(frame));
    RunLoopUntilIdle();
  }

  // Just one more frame should have sent.
  EXPECT_EQ(11ul, queue.size());

  // Check that they sent in order.
  size_t count = 0;
  while (!queue.empty()) {
    auto frame = Frame::Parse(state.credit_based_flow, state.role,
                              queue.front()->view());
    queue.pop();
    EXPECT_TRUE(frame);
    EXPECT_EQ(
        count,
        static_cast<UserDataFrame*>(frame.get())->TakeInformation()->view()[0]);
    count++;
  }
}

// In this test, we test incoming credit-based flow with the following series of
// actions:
// 1. Receive a frame on session, which should trigger the session to replenish
//    to the max amount of credits (because we start below the low water mark).
// 2. Receive two frames; nothing should happen.
// 3. Receive an empty frame; nothing should happen.
// 4. Send a frame, which should come attached with two credits for each of the
//    non-empty frames above.
TEST_F(RFCOMM_ChannelManagerTest, CreditBasedFlow_Incoming) {
  PeerState& state = AddFakePeerState(
      kHandle1, PeerState{true /*credit-based flow*/, Role::kUnassigned});

  auto channel = OpenOutgoingChannel(kHandle1, kMinServerChannel);
  DLCI dlci = ServerChannelToDLCI(kMinServerChannel, state.role);
  channel->Activate(
      &DoNothingWithBuffer, [] {}, dispatcher());

  auto& queue = handle_to_incoming_frames_[kHandle1];

  // We'll get kMaxInitialCredits during PN.
  Credits credits = kMaxInitialCredits;

  {
    // Send one frame.
    ReceiveFrame(kHandle1,
                 std::make_unique<UserDataFrame>(
                     state.role, state.credit_based_flow, dlci, NewBuffer(0)));
    credits--;
    RunLoopUntilIdle();
  }

  {
    // Expect that we get back an empty user data frame with credits.
    EXPECT_EQ(1ul, queue.size());
    auto frame = Frame::Parse(state.credit_based_flow, state.role,
                              queue.front()->view());
    queue.pop();
    EXPECT_TRUE(frame);
    EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
              static_cast<FrameType>(frame->control()));
    EXPECT_EQ(dlci, frame->dlci());
    credits +=
        static_cast<UnnumberedInfoHeaderCheckFrame*>(frame.get())->credits();
    // TODO(gusss): we're hard-coding kHighWaterMark here.
    EXPECT_EQ(100ul, credits);
  }

  // Receive two frames.
  for (int i = 0; i < 2; i++) {
    ReceiveFrame(kHandle1, std::make_unique<UserDataFrame>(
                               state.role, state.credit_based_flow, dlci,
                               NewBuffer(i + 1)));
    credits--;
    RunLoopUntilIdle();
  }

  // Expect no new frames.
  EXPECT_EQ(0ul, queue.size());

  {
    // Send frame to the remote, to which we should attach credits.
    channel->Send(NewBuffer(3));
    RunLoopUntilIdle();
  }

  {
    // Send and empty frame, which shouldn't cost any credits.
    ReceiveFrame(kHandle1, std::make_unique<UserDataFrame>(
                               state.role, state.credit_based_flow, dlci,
                               NewSlabBuffer(0)));
    RunLoopUntilIdle();
  }

  {
    // Expect that the frame has credits attached.
    EXPECT_EQ(1ul, queue.size());
    auto frame = Frame::Parse(state.credit_based_flow, state.role,
                              queue.front()->view());
    EXPECT_TRUE(frame);
    EXPECT_EQ(FrameType::kUnnumberedInfoHeaderCheck,
              static_cast<FrameType>(frame->control()));
    EXPECT_EQ(dlci, frame->dlci());
    credits +=
        static_cast<UnnumberedInfoHeaderCheckFrame*>(frame.get())->credits();
    // TODO(gusss): we're hard-coding kHighWaterMark here.
    EXPECT_EQ(100ul, credits);
  }
}

}  // namespace
}  // namespace rfcomm
}  // namespace bt
