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

#include "src/connectivity/bluetooth/core/bt-host/att/bearer.h"

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

namespace bt::att {
namespace {

constexpr OpCode kTestRequest = kFindInformationRequest;
constexpr OpCode kTestResponse = kFindInformationResponse;
constexpr OpCode kTestRequest2 = kExchangeMTURequest;
constexpr OpCode kTestResponse2 = kExchangeMTUResponse;
constexpr OpCode kTestRequest3 = kFindByTypeValueRequest;
constexpr OpCode kTestResponse3 = kFindByTypeValueResponse;

constexpr OpCode kTestCommand = kWriteCommand;

void NopHandler(Bearer::TransactionId /*unused*/, const PacketReader& /*unused*/) {}

class BearerTest : public l2cap::testing::FakeChannelTest {
 public:
  BearerTest() = default;
  ~BearerTest() override = default;

 protected:
  void SetUp() override {
    ChannelOptions options(l2cap::kATTChannelId);
    fake_att_chan_ = CreateFakeChannel(options);
    bearer_ = Bearer::Create(fake_att_chan_);
  }

  void TearDown() override { bearer_ = nullptr; }

  Bearer* bearer() const { return bearer_.get(); }
  l2cap::testing::FakeChannel* fake_att_chan() const { return fake_att_chan_.get(); }

  void DeleteBearer() { bearer_ = nullptr; }

 private:
  fbl::RefPtr<l2cap::testing::FakeChannel> fake_att_chan_;
  fbl::RefPtr<Bearer> bearer_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BearerTest);
};

TEST_F(BearerTest, CreateFailsToActivate) {
  ChannelOptions options(l2cap::kATTChannelId);
  auto fake_chan = CreateFakeChannel(options);
  fake_chan->set_activate_fails(true);

  EXPECT_FALSE(Bearer::Create(std::move(fake_chan)));
}

TEST_F(BearerTest, CreateUsesLEMaxMTUAsPreferredMTU) {
  EXPECT_EQ(kLEMaxMTU, bearer()->preferred_mtu());
}

TEST_F(BearerTest, ShutDown) {
  ASSERT_TRUE(bearer()->is_open());
  ASSERT_FALSE(fake_att_chan()->link_error());

  // Verify that shutting down an open bearer notifies the closed callback.
  bool called = false;
  auto cb = [&called] { called = true; };

  bearer()->set_closed_callback(cb);
  bearer()->ShutDown();
  EXPECT_TRUE(called);
  EXPECT_FALSE(bearer()->is_open());

  // Bearer should also signal a link error over the channel.
  EXPECT_TRUE(fake_att_chan()->link_error());

  // ShutDown() on a closed bearer does nothing.
  bearer()->ShutDown();
  EXPECT_FALSE(bearer()->is_open());
}

TEST_F(BearerTest, StartTransactionErrorClosed) {
  bearer()->ShutDown();
  ASSERT_FALSE(bearer()->is_open());

  bool received_error = false;
  Bearer::TransactionCallback cb = [&received_error](Bearer::TransactionResult result) {
    if (result.is_error()) {
      received_error = true;
    }
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), std::move(cb));
  EXPECT_TRUE(received_error);
}

TEST_F(BearerTest, StartTransactionInvalidPacket) {
  auto cb = [](Bearer::TransactionResult) { FAIL(); };

  // Empty
  EXPECT_DEATH_IF_SUPPORTED(bearer()->StartTransaction(std::make_unique<BufferView>(), cb),
                            "bad length");

  // Exceeds MTU.
  bearer()->set_mtu(1);
  EXPECT_DEATH_IF_SUPPORTED(bearer()->StartTransaction(NewBuffer(kTestRequest, 2), cb),
                            "bad length");
}

TEST_F(BearerTest, StartTransactionWrongMethodType) {
  auto cb = [](Bearer::TransactionResult) { FAIL(); };

  // Command
  EXPECT_DEATH_IF_SUPPORTED(bearer()->StartTransaction(NewBuffer(kWriteCommand), cb),
                            "callback was provided");

  // Notification
  EXPECT_DEATH_IF_SUPPORTED(bearer()->StartTransaction(NewBuffer(kNotification), cb),
                            "callback was provided");
}

TEST_F(BearerTest, RequestTimeout) {
  // We expect the channel to be closed and the pending transaction to end in an
  // error.
  bool closed = false;
  bool err_cb_called = false;
  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_called](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kTimedOut), error);
    EXPECT_EQ(0, handle);

    err_cb_called = true;
  };

  ASSERT_FALSE(fake_att_chan()->link_error());
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  RunLoopFor(kTransactionTimeout);

  EXPECT_TRUE(closed);
  EXPECT_TRUE(err_cb_called);
  EXPECT_TRUE(fake_att_chan()->link_error());
}

// Queue many requests but make sure that FakeChannel only receives one.
TEST_F(BearerTest, RequestTimeoutMany) {
  constexpr unsigned int kTransactionCount = 2;
  unsigned int chan_count = 0;
  auto chan_cb = [&chan_count](auto cb_packet) {
    chan_count++;
    // This should only be called once and for the first request.
    EXPECT_EQ(kTestRequest, (*cb_packet)[0]);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool closed = false;
  unsigned int err_cb_count = 0u;

  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_count](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kTimedOut), error);
    EXPECT_EQ(0, handle);

    err_cb_count++;
  };

  bearer()->StartTransaction(NewBuffer(kTestRequest, 'T', 'e', 's', 't'), cb);
  bearer()->StartTransaction(NewBuffer(kTestRequest2, 'T', 'e', 's', 't'), cb);

  RunLoopUntilIdle();

  // The first indication should have been sent and the second one queued.
  EXPECT_EQ(1u, chan_count);

  EXPECT_FALSE(closed);
  EXPECT_EQ(0u, err_cb_count);

  // Make the request timeout.
  RunLoopFor(kTransactionTimeout);

  EXPECT_TRUE(closed);
  EXPECT_EQ(kTransactionCount, err_cb_count);
}

TEST_F(BearerTest, IndicationTimeout) {
  // We expect the channel to be closed and the pending transaction to end in an
  // error.
  bool closed = false;
  bool err_cb_called = false;

  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_called](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kTimedOut), error);
    EXPECT_EQ(0, handle);

    err_cb_called = true;
  };

  bearer()->StartTransaction(NewBuffer(kIndication, 'T', 'e', 's', 't'), cb);

  RunLoopFor(kTransactionTimeout);

  EXPECT_TRUE(closed);
  EXPECT_TRUE(err_cb_called);
}

// Queue many indications but make sure that FakeChannel only receives one.
TEST_F(BearerTest, IndicationTimeoutMany) {
  constexpr unsigned int kTransactionCount = 2;
  constexpr uint8_t kIndValue1 = 1;
  constexpr uint8_t kIndValue2 = 2;

  unsigned int chan_count = 0;
  auto chan_cb = [kIndValue1, &chan_count](auto cb_packet) {
    chan_count++;
    // This should only be called once and for the first request.
    EXPECT_EQ(kIndValue1, (*cb_packet)[1]);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool closed = false;
  unsigned int err_cb_count = 0u;

  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_count](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kTimedOut), error);
    EXPECT_EQ(0, handle);

    err_cb_count++;
  };

  bearer()->StartTransaction(NewBuffer(kIndication, kIndValue1), cb);
  bearer()->StartTransaction(NewBuffer(kIndication, kIndValue2), cb);

  RunLoopUntilIdle();

  // The first indication should have been sent and the second one queued.
  EXPECT_EQ(1u, chan_count);

  EXPECT_FALSE(closed);
  EXPECT_EQ(0u, err_cb_count);

  // Make the request timeout.
  RunLoopFor(kTransactionTimeout);

  EXPECT_TRUE(closed);
  EXPECT_EQ(kTransactionCount, err_cb_count);
}

TEST_F(BearerTest, ReceiveEmptyPacket) {
  bool closed = false;
  bearer()->set_closed_callback([&closed] { closed = true; });

  fake_chan()->Receive(BufferView());

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
}

TEST_F(BearerTest, ReceiveResponseWithoutRequest) {
  bool closed = false;
  bearer()->set_closed_callback([&closed] { closed = true; });

  fake_chan()->Receive(StaticByteBuffer(kTestResponse));

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
}

TEST_F(BearerTest, ReceiveConfirmationWithoutIndication) {
  bool closed = false;
  bearer()->set_closed_callback([&closed] { closed = true; });

  fake_chan()->Receive(StaticByteBuffer(kConfirmation));

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
}

TEST_F(BearerTest, SendRequestWrongResponse) {
  unsigned int count = 0;
  auto chan_cb = [this, &count](auto cb_packet) {
    count++;
    // This should only be called once and for the first request.
    EXPECT_EQ(kTestRequest, (*cb_packet)[0]);

    // Send back the wrong response.
    fake_chan()->Receive(StaticByteBuffer(kTestResponse2));
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool err_cb_called = false;
  bool closed = false;

  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_called](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kFailed), error);
    EXPECT_EQ(0, handle);

    err_cb_called = true;
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
  EXPECT_TRUE(err_cb_called);
  EXPECT_EQ(1u, count);
}

TEST_F(BearerTest, SendRequestErrorResponseTooShort) {
  StaticByteBuffer malformed_error_rsp(
      // Opcode: error response
      kErrorResponse,

      // Parameters are too short (by 1 byte). Contents are unimportant, as the
      // PDU should be rejected.
      1, 2, 3);

  bool chan_cb_called = false;
  auto chan_cb = [this, &chan_cb_called, &malformed_error_rsp](auto cb_packet) {
    ASSERT_FALSE(chan_cb_called);
    EXPECT_EQ(kTestRequest, (*cb_packet)[0]);

    chan_cb_called = true;
    fake_chan()->Receive(malformed_error_rsp);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool err_cb_called = false;
  bool closed = false;

  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_called](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kFailed), error);
    EXPECT_EQ(0, handle);

    err_cb_called = true;
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
  EXPECT_TRUE(err_cb_called);
  EXPECT_TRUE(chan_cb_called);
}

TEST_F(BearerTest, SendRequestErrorResponseTooLong) {
  StaticByteBuffer malformed_error_rsp(
      // Opcode: error response
      kErrorResponse,

      // Parameters are too long (by 1 byte). Contents are unimportant, as the
      // PDU should be rejected.
      1, 2, 3, 4, 5);

  bool chan_cb_called = false;
  auto chan_cb = [this, &chan_cb_called, &malformed_error_rsp](auto cb_packet) {
    ASSERT_FALSE(chan_cb_called);
    EXPECT_EQ(kTestRequest, (*cb_packet)[0]);

    chan_cb_called = true;
    fake_chan()->Receive(malformed_error_rsp);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool err_cb_called = false;
  bool closed = false;

  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_called](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kFailed), error);
    EXPECT_EQ(0, handle);

    err_cb_called = true;
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
  EXPECT_TRUE(err_cb_called);
  EXPECT_TRUE(chan_cb_called);
}

TEST_F(BearerTest, SendRequestErrorResponseWrongOpCode) {
  StaticByteBuffer error_rsp(
      // Opcode: error response
      kErrorResponse,

      // request opcode: non-matching opcode in error response
      kTestRequest2,

      // handle, should be ignored
      0x00, 0x00,

      // error code:
      ErrorCode::kRequestNotSupported);

  bool chan_cb_called = false;
  auto chan_cb = [this, &chan_cb_called, &error_rsp](auto cb_packet) {
    ASSERT_FALSE(chan_cb_called);
    EXPECT_EQ(kTestRequest, (*cb_packet)[0]);

    chan_cb_called = true;
    fake_chan()->Receive(error_rsp);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool err_cb_called = false;
  bool closed = false;

  bearer()->set_closed_callback([&closed] { closed = true; });

  auto cb = [&err_cb_called](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(HostError::kFailed), error);
    EXPECT_EQ(0, handle);

    err_cb_called = true;
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
  EXPECT_TRUE(err_cb_called);
  EXPECT_TRUE(chan_cb_called);
}

TEST_F(BearerTest, SendRequestErrorResponse) {
  StaticByteBuffer error_rsp(
      // Opcode: error response
      kErrorResponse,

      // request opcode
      kTestRequest,

      // handle (0x0001)
      0x01, 0x00,

      // error code:
      ErrorCode::kRequestNotSupported);

  bool chan_cb_called = false;
  auto chan_cb = [this, &chan_cb_called, &error_rsp](auto cb_packet) {
    ASSERT_FALSE(chan_cb_called);
    EXPECT_EQ(kTestRequest, (*cb_packet)[0]);

    chan_cb_called = true;
    fake_chan()->Receive(error_rsp);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool err_cb_called = false;
  auto cb = [&err_cb_called](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(ErrorCode::kRequestNotSupported), error);
    EXPECT_EQ(0x0001, handle);

    err_cb_called = true;
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  RunLoopUntilIdle();
  EXPECT_TRUE(err_cb_called);
  EXPECT_TRUE(chan_cb_called);

  // The channel should remain open
  EXPECT_TRUE(bearer()->is_open());
}

TEST_F(BearerTest, SendRequestSuccess) {
  StaticByteBuffer response(kTestResponse, 'T', 'e', 's', 't');

  bool chan_cb_called = false;
  auto chan_cb = [this, &chan_cb_called, &response](auto cb_packet) {
    ASSERT_FALSE(chan_cb_called);
    EXPECT_EQ(kTestRequest, (*cb_packet)[0]);

    chan_cb_called = true;
    fake_chan()->Receive(response);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool cb_called = false;
  auto cb = [&cb_called, &response](Bearer::TransactionResult result) {
    ASSERT_FALSE(cb_called);
    if (result.is_error()) {
      return;
    }

    cb_called = true;
    EXPECT_TRUE(ContainersEqual(response, result.value().data()));
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  RunLoopUntilIdle();
  EXPECT_TRUE(chan_cb_called);
  EXPECT_TRUE(cb_called);

  // The channel should remain open
  EXPECT_TRUE(bearer()->is_open());
}

// Closing the L2CAP channel while ATT requests have been queued will cause the
// error callbacks to be called. The code should fail gracefully if one of these
// callbacks deletes the attribute bearer.
TEST_F(BearerTest, CloseChannelAndDeleteBearerWhileRequestsArePending) {
  // We expect the callback to be called 3 times since we queue 3 transactions
  // below.
  constexpr size_t kExpectedCount = 3;

  size_t cb_error_count = 0;
  auto cb = [this, &cb_error_count](Bearer::TransactionResult result) {
    if (result.is_ok()) {
      return;
    }
    cb_error_count++;

    // Delete the bearer on the first callback. The remaining callbacks should
    // still run gracefully.
    DeleteBearer();
  };

  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);
  bearer()->StartTransaction(NewBuffer(kTestRequest), cb);

  fake_chan()->Close();
  EXPECT_EQ(kExpectedCount, cb_error_count);
}

TEST_F(BearerTest, SendManyRequests) {
  const StaticByteBuffer response1(kTestResponse, 'f', 'o', 'o');
  const StaticByteBuffer response2(kErrorResponse,

                                   // request opcode
                                   kTestRequest2,

                                   // handle (0x0001)
                                   0x01, 0x00,

                                   // error code:
                                   ErrorCode::kRequestNotSupported);
  const StaticByteBuffer response3(kTestResponse3, 'b', 'a', 'r');

  auto chan_cb = [&, this](auto cb_packet) {
    OpCode opcode = (*cb_packet)[0];

    if (opcode == kTestRequest) {
      fake_chan()->Receive(response1);
    } else if (opcode == kTestRequest2) {
      fake_chan()->Receive(response2);
    } else if (opcode == kTestRequest3) {
      fake_chan()->Receive(response3);
    }
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool called_1 = false, called_2 = false, called_3 = false;

  // We expect each callback to be called in the order that we send the corresponding request.
  auto callback1 = [&called_1, &called_2, &called_3, &response1](Bearer::TransactionResult result) {
    EXPECT_FALSE(called_2);
    EXPECT_FALSE(called_3);
    called_1 = true;

    // First request should've succeeded
    ASSERT_EQ(fitx::ok(), result);
    EXPECT_TRUE(ContainersEqual(response1, result.value().data()));
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest), callback1);

  auto callback2 = [&called_1, &called_2, &called_3](Bearer::TransactionResult result) {
    EXPECT_TRUE(called_1);
    EXPECT_FALSE(called_3);
    called_2 = true;

    // Second request should've failed
    ASSERT_EQ(fitx::failed(), result);
    const auto& [error, handle] = result.error_value();
    EXPECT_EQ(Error(ErrorCode::kRequestNotSupported), error);
    EXPECT_EQ(0x0001, handle);
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest2), callback2);

  auto callback3 = [&called_1, &called_2, &called_3, &response3](Bearer::TransactionResult result) {
    EXPECT_TRUE(called_1);
    EXPECT_TRUE(called_2);
    called_3 = true;

    // Third request should've succeeded
    ASSERT_EQ(fitx::ok(), result);
    EXPECT_TRUE(ContainersEqual(response3, result.value().data()));
  };
  bearer()->StartTransaction(NewBuffer(kTestRequest3), callback3);

  RunLoopUntilIdle();

  EXPECT_TRUE(bearer()->is_open());
}

// An indication transaction can only fail in a circumstance that would shut
// down the bearer (e.g. a transaction timeout or an empty PDU). Otherwise,
// Bearer will only complete an indication transaction when it receives a
// confirmation PDU.
//
// NOTE: Bearer only looks at the opcode of a PDU and ignores the payload, so a
// malformed confirmation payload is not considered an error at this layer.
TEST_F(BearerTest, SendIndicationSuccess) {
  // Even though this is a malformed confirmation PDU it will not be rejected by
  // Bearer.
  StaticByteBuffer conf(kConfirmation, 'T', 'e', 's', 't');

  bool chan_cb_called = false;
  auto chan_cb = [this, &chan_cb_called, &conf](auto cb_packet) {
    ASSERT_FALSE(chan_cb_called);
    EXPECT_EQ(kIndication, (*cb_packet)[0]);

    chan_cb_called = true;
    fake_chan()->Receive(conf);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  bool cb_called = false;
  auto cb = [&cb_called, &conf](Bearer::TransactionResult result) {
    ASSERT_FALSE(cb_called);

    cb_called = true;
    EXPECT_TRUE(ContainersEqual(conf, result.value().data()));
  };
  bearer()->StartTransaction(NewBuffer(kIndication), cb);

  RunLoopUntilIdle();
  EXPECT_TRUE(chan_cb_called);
  EXPECT_TRUE(cb_called);

  // The channel should remain open
  EXPECT_TRUE(bearer()->is_open());
}

TEST_F(BearerTest, SendWithoutResponseErrorClosed) {
  bearer()->ShutDown();
  ASSERT_FALSE(bearer()->is_open());

  EXPECT_FALSE(bearer()->SendWithoutResponse(NewBuffer(kTestCommand)));
}

TEST_F(BearerTest, SendWithoutResponseInvalidPacket) {
  // Empty
  EXPECT_DEATH_IF_SUPPORTED(
      [[maybe_unused]] auto _ = bearer()->SendWithoutResponse(std::make_unique<BufferView>()),
      "bad length");

  // Exceeds MTU
  bearer()->set_mtu(1);
  EXPECT_DEATH_IF_SUPPORTED(
      [[maybe_unused]] auto _ = bearer()->SendWithoutResponse(NewBuffer(kTestCommand, 2)),
      "bad length");
}

TEST_F(BearerTest, SendWithoutResponseWrongMethodType) {
  EXPECT_DEATH_IF_SUPPORTED(
      [[maybe_unused]] auto _ = bearer()->SendWithoutResponse(NewBuffer(kTestRequest)),
      "requires callback");
  EXPECT_DEATH_IF_SUPPORTED(
      [[maybe_unused]] auto _ = bearer()->SendWithoutResponse(NewBuffer(kTestResponse)),
      "unsupported opcode");
  EXPECT_DEATH_IF_SUPPORTED(
      [[maybe_unused]] auto _ = bearer()->SendWithoutResponse(NewBuffer(kIndication)),
      "requires callback");
}

TEST_F(BearerTest, SendWithoutResponseCorrectMethodType) {
  EXPECT_TRUE(bearer()->SendWithoutResponse(NewBuffer(kNotification)));
  EXPECT_TRUE(bearer()->SendWithoutResponse(NewBuffer(kTestCommand)));
  EXPECT_TRUE(bearer()->SendWithoutResponse(NewBuffer(kTestRequest | kCommandFlag)));

  // Any opcode is accepted as long as it has the command flag set.
  EXPECT_TRUE(bearer()->SendWithoutResponse(NewBuffer(kInvalidOpCode | kCommandFlag)));
}

TEST_F(BearerTest, SendWithoutResponseMany) {
  // Everything should go through without any flow control.
  constexpr unsigned int kExpectedCount = 10;
  unsigned int chan_cb_count = 0u;

  auto chan_cb = [&chan_cb_count](auto cb_packet) {
    OpCode opcode = (*cb_packet)[0];
    EXPECT_TRUE(kCommandFlag & opcode || opcode == kIndication);

    chan_cb_count++;
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  for (OpCode opcode = 0; opcode < kExpectedCount; opcode++) {
    // Everything
    EXPECT_TRUE(bearer()->SendWithoutResponse(NewBuffer(opcode | kCommandFlag)));
  }

  RunLoopUntilIdle();
  EXPECT_EQ(kExpectedCount, chan_cb_count);
}

TEST_F(BearerTest, RegisterHandlerErrorClosed) {
  bearer()->ShutDown();
  EXPECT_FALSE(bearer()->is_open());
  EXPECT_EQ(Bearer::kInvalidHandlerId, bearer()->RegisterHandler(kWriteRequest, NopHandler));
  EXPECT_EQ(Bearer::kInvalidHandlerId, bearer()->RegisterHandler(kIndication, NopHandler));
}

TEST_F(BearerTest, RegisterHandlerErrorAlreadyRegistered) {
  EXPECT_NE(Bearer::kInvalidHandlerId, bearer()->RegisterHandler(kIndication, NopHandler));
  EXPECT_EQ(Bearer::kInvalidHandlerId, bearer()->RegisterHandler(kIndication, NopHandler));
}

TEST_F(BearerTest, UnregisterHandler) {
  auto id0 = bearer()->RegisterHandler(kNotification, NopHandler);
  EXPECT_NE(Bearer::kInvalidHandlerId, id0);

  bearer()->UnregisterHandler(id0);

  // It should be possible to register new handlers for the same opcodes.
  id0 = bearer()->RegisterHandler(kNotification, NopHandler);
  EXPECT_NE(Bearer::kInvalidHandlerId, id0);
}

TEST_F(BearerTest, RemoteTransactionNoHandler) {
  StaticByteBuffer error_rsp(
      // opcode
      kErrorResponse,

      // request opcode
      kTestRequest,

      // handle
      0x00, 0x00,

      // error code
      ErrorCode::kRequestNotSupported);

  bool received_error_rsp = false;
  auto chan_cb = [&received_error_rsp, &error_rsp](auto packet) {
    received_error_rsp = true;
    EXPECT_TRUE(ContainersEqual(error_rsp, *packet));
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());
  fake_chan()->Receive(StaticByteBuffer(kTestRequest));

  RunLoopUntilIdle();
  EXPECT_TRUE(received_error_rsp);
}

TEST_F(BearerTest, RemoteTransactionSeqProtocolError) {
  int request_count = 0;
  auto handler = [&request_count](auto id, const PacketReader& packet) {
    EXPECT_EQ(kTestRequest, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    request_count++;
  };

  bearer()->RegisterHandler(kTestRequest, handler);
  fake_chan()->Receive(StaticByteBuffer(kTestRequest));

  RunLoopUntilIdle();
  ASSERT_EQ(1, request_count);

  // Receiving a second request before sending a response should close the
  // bearer.
  bool closed = false;
  bearer()->set_closed_callback([&closed] { closed = true; });

  fake_chan()->Receive(StaticByteBuffer(kTestRequest));

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
  EXPECT_EQ(1, request_count);
  EXPECT_FALSE(bearer()->is_open());
}

TEST_F(BearerTest, RemoteIndicationSeqProtocolError) {
  int ind_count = 0;
  auto handler = [&ind_count](auto id, const PacketReader& packet) {
    EXPECT_EQ(kIndication, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    ind_count++;
  };

  bearer()->RegisterHandler(kIndication, handler);
  fake_chan()->Receive(StaticByteBuffer(kIndication));

  RunLoopUntilIdle();
  ASSERT_EQ(1, ind_count);

  // Receiving a second indication before sending a confirmation should close
  // the bearer.
  bool closed = false;
  bearer()->set_closed_callback([&closed] { closed = true; });

  fake_chan()->Receive(StaticByteBuffer(kIndication));

  RunLoopUntilIdle();
  EXPECT_TRUE(closed);
  EXPECT_EQ(1, ind_count);
  EXPECT_FALSE(bearer()->is_open());
}

TEST_F(BearerTest, ReplyInvalidPacket) {
  // Empty
  EXPECT_FALSE(bearer()->Reply(0, std::make_unique<BufferView>()));

  // Exceeds MTU.
  bearer()->set_mtu(1);
  EXPECT_FALSE(bearer()->Reply(0, NewBuffer(kTestRequest, 2)));
}

TEST_F(BearerTest, ReplyInvalidId) {
  EXPECT_FALSE(bearer()->Reply(Bearer::kInvalidTransactionId, NewBuffer(kTestResponse)));

  // The ID is valid but doesn't correspond to an active transaction.
  EXPECT_FALSE(bearer()->Reply(1u, NewBuffer(kTestResponse)));
}

TEST_F(BearerTest, ReplyWrongOpCode) {
  Bearer::TransactionId id;
  bool handler_called = false;
  auto handler = [&id, &handler_called](auto cb_id, const PacketReader& packet) {
    EXPECT_EQ(kTestRequest, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    handler_called = true;
    id = cb_id;
  };

  bearer()->RegisterHandler(kTestRequest, handler);
  fake_chan()->Receive(StaticByteBuffer(kTestRequest));

  RunLoopUntilIdle();
  ASSERT_TRUE(handler_called);

  EXPECT_FALSE(bearer()->Reply(id, NewBuffer(kTestResponse2)));
}

TEST_F(BearerTest, ReplyToIndicationWrongOpCode) {
  Bearer::TransactionId id;
  bool handler_called = false;
  auto handler = [&id, &handler_called](auto cb_id, const PacketReader& packet) {
    EXPECT_EQ(kIndication, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    handler_called = true;
    id = cb_id;
  };

  bearer()->RegisterHandler(kIndication, handler);
  fake_chan()->Receive(StaticByteBuffer(kIndication));

  RunLoopUntilIdle();
  ASSERT_TRUE(handler_called);

  EXPECT_FALSE(bearer()->Reply(id, NewBuffer(kTestResponse)));
}

TEST_F(BearerTest, ReplyWithResponse) {
  bool response_sent = false;
  auto chan_cb = [&response_sent](auto packet) {
    response_sent = true;

    EXPECT_EQ(kTestResponse, (*packet)[0]);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  Bearer::TransactionId id;
  bool handler_called = false;
  auto handler = [&id, &handler_called](auto cb_id, const PacketReader& packet) {
    EXPECT_EQ(kTestRequest, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    handler_called = true;
    id = cb_id;
  };

  bearer()->RegisterHandler(kTestRequest, handler);
  fake_chan()->Receive(StaticByteBuffer(kTestRequest));

  RunLoopUntilIdle();
  ASSERT_TRUE(handler_called);

  EXPECT_TRUE(bearer()->Reply(id, NewBuffer(kTestResponse)));

  // The transaction is marked as complete.
  EXPECT_FALSE(bearer()->Reply(id, NewBuffer(kTestResponse)));
  EXPECT_FALSE(bearer()->ReplyWithError(id, 0, ErrorCode::kUnlikelyError));

  RunLoopUntilIdle();
  EXPECT_TRUE(response_sent);
}

TEST_F(BearerTest, IndicationConfirmation) {
  bool conf_sent = false;
  auto chan_cb = [&conf_sent](auto packet) {
    conf_sent = true;
    EXPECT_EQ(kConfirmation, (*packet)[0]);
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  Bearer::TransactionId id;
  bool handler_called = false;
  auto handler = [&id, &handler_called](auto cb_id, const PacketReader& packet) {
    EXPECT_EQ(kIndication, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    handler_called = true;
    id = cb_id;
  };

  bearer()->RegisterHandler(kIndication, handler);
  fake_chan()->Receive(StaticByteBuffer(kIndication));

  RunLoopUntilIdle();
  ASSERT_TRUE(handler_called);

  EXPECT_TRUE(bearer()->Reply(id, NewBuffer(kConfirmation)));

  // The transaction is marked as complete.
  EXPECT_FALSE(bearer()->Reply(id, NewBuffer(kConfirmation)));

  RunLoopUntilIdle();
  EXPECT_TRUE(conf_sent);
}

TEST_F(BearerTest, ReplyWithErrorInvalidId) {
  EXPECT_FALSE(bearer()->ReplyWithError(0, 0, ErrorCode::kUnlikelyError));
}

TEST_F(BearerTest, IndicationReplyWithError) {
  Bearer::TransactionId id;
  bool handler_called = false;
  auto handler = [&id, &handler_called](auto cb_id, const PacketReader& packet) {
    EXPECT_EQ(kIndication, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    handler_called = true;
    id = cb_id;
  };

  bearer()->RegisterHandler(kIndication, handler);
  fake_chan()->Receive(StaticByteBuffer(kIndication));

  RunLoopUntilIdle();
  ASSERT_TRUE(handler_called);

  // Cannot reply to an indication with error.
  EXPECT_FALSE(bearer()->ReplyWithError(id, 0, ErrorCode::kUnlikelyError));
}

TEST_F(BearerTest, ReplyWithError) {
  bool response_sent = false;
  auto chan_cb = [&response_sent](auto packet) {
    response_sent = true;

    // The error response that we send below
    StaticByteBuffer expected(kErrorResponse, kTestRequest, 0x00, 0x00, ErrorCode::kUnlikelyError);
    EXPECT_TRUE(ContainersEqual(expected, *packet));
  };
  fake_chan()->SetSendCallback(chan_cb, dispatcher());

  Bearer::TransactionId id;
  bool handler_called = false;
  auto handler = [&id, &handler_called](auto cb_id, const PacketReader& packet) {
    EXPECT_EQ(kTestRequest, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    handler_called = true;
    id = cb_id;
  };

  bearer()->RegisterHandler(kTestRequest, handler);
  fake_chan()->Receive(StaticByteBuffer(kTestRequest));

  RunLoopUntilIdle();
  ASSERT_TRUE(handler_called);

  EXPECT_TRUE(bearer()->ReplyWithError(id, 0, ErrorCode::kUnlikelyError));

  // The transaction is marked as complete.
  EXPECT_FALSE(bearer()->Reply(id, NewBuffer(kTestResponse)));
  EXPECT_FALSE(bearer()->ReplyWithError(id, 0, ErrorCode::kUnlikelyError));

  RunLoopUntilIdle();
  EXPECT_TRUE(response_sent);
}

// Requests and indications have independent flow control
TEST_F(BearerTest, RequestAndIndication) {
  Bearer::TransactionId req_id, ind_id;

  int req_count = 0;
  int ind_count = 0;
  auto req_handler = [&req_id, &req_count](auto id, const auto& packet) {
    EXPECT_EQ(kTestRequest, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    req_count++;
    req_id = id;
  };
  auto ind_handler = [&ind_id, &ind_count](auto id, const auto& packet) {
    EXPECT_EQ(kIndication, packet.opcode());
    EXPECT_EQ(0u, packet.payload_size());

    ind_count++;
    ind_id = id;
  };

  bearer()->RegisterHandler(kTestRequest, req_handler);
  bearer()->RegisterHandler(kIndication, ind_handler);

  fake_chan()->Receive(StaticByteBuffer(kTestRequest));
  fake_chan()->Receive(StaticByteBuffer(kIndication));

  RunLoopUntilIdle();
  EXPECT_EQ(1, req_count);
  ASSERT_EQ(1, ind_count);

  // Opcodes for the wrong transaction should be rejected.
  EXPECT_FALSE(bearer()->Reply(ind_id, NewBuffer(kTestResponse)));
  EXPECT_FALSE(bearer()->Reply(req_id, NewBuffer(kConfirmation)));

  // It should be possible to end two distinct transactions.
  EXPECT_TRUE(bearer()->Reply(req_id, NewBuffer(kTestResponse)));
  EXPECT_TRUE(bearer()->Reply(ind_id, NewBuffer(kConfirmation)));
}

// Test receipt of non-transactional PDUs.
TEST_F(BearerTest, RemotePDUWithoutResponse) {
  int cmd_count = 0;
  auto cmd_handler = [&cmd_count](auto tid, const auto& packet) {
    EXPECT_EQ(Bearer::kInvalidTransactionId, tid);
    EXPECT_EQ(kWriteCommand, packet.opcode());
    cmd_count++;
  };
  bearer()->RegisterHandler(kWriteCommand, cmd_handler);

  int not_count = 0;
  auto not_handler = [&not_count](auto tid, const auto& packet) {
    EXPECT_EQ(Bearer::kInvalidTransactionId, tid);
    EXPECT_EQ(kNotification, packet.opcode());
    not_count++;
  };
  bearer()->RegisterHandler(kNotification, not_handler);

  fake_chan()->Receive(StaticByteBuffer(kTestCommand));
  fake_chan()->Receive(StaticByteBuffer(kNotification));

  RunLoopUntilIdle();
  EXPECT_EQ(1, cmd_count);
  EXPECT_EQ(1, not_count);
}

class BearerTestSecurity : public BearerTest {
 protected:
  void SetUp() override {
    BearerTest::SetUp();

    fake_chan()->SetSecurityCallback(
        [this](hci_spec::ConnectionHandle handle, sm::SecurityLevel level,
               sm::ResultFunction<> callback) {
          security_request_count_++;
          requested_security_level_ = level;

          ASSERT_FALSE(security_responder_) << "Security request received while one was pending";
          security_responder_ = std::move(callback);
        },
        dispatcher());
  }

  // Sets up the fake channel to send an error response to all packets it
  // receives.
  void SetUpErrorResponder(ErrorCode ecode, Handle handle = 1) {
    fake_chan()->SetSendCallback(
        [this, ecode, handle](auto packet) {
          att_request_count_++;
          fake_chan()->Receive(StaticByteBuffer(kErrorResponse,  // opcode (Error Response)
                                                kTestRequest,    // request opcode
                                                LowerBits(handle),
                                                UpperBits(handle),  // handle
                                                ecode               // error code
                                                ));
        },
        dispatcher());
  }

  // Sets up the fake channel to respond with the given |response| opcode to all
  // requests that it receives. The PDU contains no additional payload as it is
  // not needed for this test fixture.
  void SetUpResponder() {
    fake_chan()->SetSendCallback(
        [this](auto packet) {
          att_request_count_++;
          fake_chan()->Receive(StaticByteBuffer(kTestResponse));
        },
        dispatcher());
  }

  // Resolves the currently pending security request.
  void ResolvePendingSecurityRequest(sm::Result<> status) {
    ASSERT_TRUE(security_responder_);

    if (status.is_ok()) {
      fake_chan()->set_security(
          sm::SecurityProperties(requested_security_level_, 16, /*secure_connections=*/false));
    }

    // Clear the responder before invoking it.
    auto f = std::move(security_responder_);
    f(status);
  }

  void SendRequest() {
    bearer()->StartTransaction(NewBuffer(kTestRequest), [this](auto result) {
      if (result.is_ok()) {
        request_success_count_++;
        last_request_status_ = fitx::ok();
      } else {
        request_error_count_++;
        last_request_status_ = fitx::error(result.error_value().first);
      }
    });
  }

  const Result<>& last_request_status() const { return last_request_status_; }
  size_t request_success_count() const { return request_success_count_; }
  size_t request_error_count() const { return request_error_count_; }
  size_t att_request_count() const { return att_request_count_; }

  size_t security_request_count() const { return security_request_count_; }
  sm::SecurityLevel requested_security_level() const { return requested_security_level_; }

 private:
  Result<> last_request_status_ = fitx::ok();
  size_t request_success_count_ = 0u;
  size_t request_error_count_ = 0u;

  size_t att_request_count_ = 0u;
  sm::SecurityLevel requested_security_level_ = sm::SecurityLevel::kNoSecurity;
  size_t security_request_count_ = 0u;

  sm::ResultFunction<> security_responder_;
};

TEST_F(BearerTestSecurity, SecurityUpgradeAfterInsufficientAuthentication) {
  // Configure the endpoint to respond with an authentication error.
  SetUpErrorResponder(ErrorCode::kInsufficientAuthentication);
  SendRequest();
  RunLoopUntilIdle();

  // At this stage the remote device should have received the request and
  // responded with "Insufficient Authentication". Since the link was not
  // encrypted, the Bearer should have requested a security upgrade without
  // requiring MITM protection.
  EXPECT_EQ(1u, att_request_count());
  EXPECT_EQ(1u, security_request_count());
  EXPECT_EQ(sm::SecurityLevel::kEncrypted, requested_security_level());

  // The request should be still unresolved.
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(0u, request_error_count());

  // Configure the endpoint to respond with success and notify the Bearer of the
  // security upgrade. The Bearer should re-send the request.
  SetUpResponder();
  ResolvePendingSecurityRequest(fitx::ok());
  RunLoopUntilIdle();

  // We should have received the same request again.
  EXPECT_EQ(2u, att_request_count());
  EXPECT_EQ(1u, security_request_count());
  EXPECT_EQ(1u, request_success_count());
  EXPECT_EQ(0u, request_error_count());
}

TEST_F(BearerTestSecurity, SecurityUpgradeWithMitmAfterInsufficientAuthentication) {
  // Configure the channel to be already encrypted.
  fake_chan()->set_security(
      sm::SecurityProperties(sm::SecurityLevel::kEncrypted, 16, /*secure_connections=*/false));

  // Configure the endpoint to respond with an authentication error.
  SetUpErrorResponder(ErrorCode::kInsufficientAuthentication);
  SendRequest();
  RunLoopUntilIdle();

  // At this stage the remote device should have received the request and
  // responded with "Insufficient Authentication". Since the link was already
  // encrypted, the Bearer should have requested a security upgrade with MITM
  // protection.
  EXPECT_EQ(1u, att_request_count());
  EXPECT_EQ(1u, security_request_count());
  EXPECT_EQ(sm::SecurityLevel::kAuthenticated, requested_security_level());

  // The request should be still unresolved.
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(0u, request_error_count());

  // Configure the endpoint to respond with success and notify the Bearer of the
  // security upgrade. The Bearer should re-send the request.
  SetUpResponder();
  ResolvePendingSecurityRequest(fitx::ok());
  RunLoopUntilIdle();

  // We should have received the same request again.
  EXPECT_EQ(2u, att_request_count());
  EXPECT_EQ(1u, security_request_count());
  EXPECT_EQ(1u, request_success_count());
  EXPECT_EQ(0u, request_error_count());
  EXPECT_EQ(fitx::ok(), last_request_status());
}

TEST_F(BearerTestSecurity, SecurityUpgradeFailsAfterAuthError) {
  // Configure the endpoint to respond with an authentication error.
  SetUpErrorResponder(ErrorCode::kInsufficientAuthentication);
  SendRequest();
  RunLoopUntilIdle();

  // At this stage the remote device should have received the request and
  // responded with "Insufficient Authentication". Since the link was not
  // encrypted, the Bearer should have requested a security upgrade without
  // requiring MITM protection.
  EXPECT_EQ(1u, att_request_count());
  EXPECT_EQ(1u, security_request_count());
  EXPECT_EQ(sm::SecurityLevel::kEncrypted, requested_security_level());

  // The request should be still unresolved.
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(0u, request_error_count());

  // Configure the endpoint to respond with success and notify the Bearer of the
  // security upgrade. The Bearer should re-send the request.
  SetUpResponder();
  ResolvePendingSecurityRequest(ToResult(HostError::kFailed));
  RunLoopUntilIdle();

  // The request should not have been retried and failed with the original
  // error.
  EXPECT_EQ(1u, att_request_count());
  EXPECT_EQ(1u, security_request_count());
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(1u, request_error_count());
  EXPECT_EQ(ToResult(ErrorCode::kInsufficientAuthentication), last_request_status());
}

TEST_F(BearerTestSecurity, NoSecurityUpgradeIfAlreadyRetried) {
  // Configure the endpoint to respond with an authentication error.
  SetUpErrorResponder(ErrorCode::kInsufficientAuthentication);
  SendRequest();
  RunLoopUntilIdle();

  // At this stage the remote device should have received the request and
  // responded with "Insufficient Authentication". Since the link was not
  // encrypted, the Bearer should have requested a security upgrade without
  // requiring MITM protection.
  EXPECT_EQ(1u, att_request_count());
  EXPECT_EQ(1u, security_request_count());
  EXPECT_EQ(sm::SecurityLevel::kEncrypted, requested_security_level());

  // The request should be still unresolved.
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(0u, request_error_count());

  // Resolve the pending security request with success while the channel is
  // configured to respond with "Insufficient Authentication". The Bearer should
  // re-send the request.
  ResolvePendingSecurityRequest(fitx::ok());
  RunLoopUntilIdle();

  // The request should have been retried once. The "Insufficient
  // Authentication" error received while the link is encrypted should result in
  // a second security request at the next security level.
  EXPECT_EQ(2u, att_request_count());
  EXPECT_EQ(2u, security_request_count());
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(0u, request_error_count());

  // Resolve the pending security request with success while the channel is
  // configured to respond with "Insufficient Authentication. The Bearer should
  // retry the request one last time.
  ResolvePendingSecurityRequest(fitx::ok());
  RunLoopUntilIdle();

  // The request should have failed without retrying the request a third time as
  // the highest security level has been reached.
  EXPECT_EQ(3u, att_request_count());
  EXPECT_EQ(2u, security_request_count());
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(1u, request_error_count());
  EXPECT_EQ(ToResult(ErrorCode::kInsufficientAuthentication), last_request_status());
}

TEST_F(BearerTestSecurity, NoSecurityUpgradeIfChannelAlreadyEncrypted) {
  // Configure the channel to be already encrypted.
  fake_chan()->set_security(
      sm::SecurityProperties(sm::SecurityLevel::kEncrypted, 16, /*secure_connections=*/false));

  // Configure the endpoint to respond with an encryption error.
  SetUpErrorResponder(ErrorCode::kInsufficientEncryption);
  SendRequest();
  RunLoopUntilIdle();

  // No security upgrade should have been requested since the channel was
  // sufficiently encrypted.
  EXPECT_EQ(1u, att_request_count());
  EXPECT_EQ(0u, security_request_count());
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(1u, request_error_count());
  EXPECT_EQ(ToResult(ErrorCode::kInsufficientEncryption), last_request_status());
}

TEST_F(BearerTestSecurity, NoSecurityUpgradeIfChannelAlreadyEncryptedWithMitm) {
  // Configure the channel to be already encrypted with MITM protection
  fake_chan()->set_security(
      sm::SecurityProperties(sm::SecurityLevel::kAuthenticated, 16, /*secure_connections=*/false));

  // Configure the endpoint to respond with an authentication error.
  SetUpErrorResponder(ErrorCode::kInsufficientAuthentication);
  SendRequest();
  RunLoopUntilIdle();

  // No security upgrade should have been requested since the channel was
  // sufficiently encrypted.
  EXPECT_EQ(1u, att_request_count());
  EXPECT_EQ(0u, security_request_count());
  EXPECT_EQ(0u, request_success_count());
  EXPECT_EQ(1u, request_error_count());
  EXPECT_EQ(ToResult(ErrorCode::kInsufficientAuthentication), last_request_status());
}

}  // namespace
}  // namespace bt::att
