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

#include "src/connectivity/bluetooth/core/bt-host/common/status.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/data/fake_domain.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/fake_pairing_delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/peer_cache.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/status.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/util.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_peer.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_packets.h"
#include "src/lib/fxl/memory/ref_ptr.h"

namespace bt {
namespace gap {
namespace {

using bt::hci::AuthRequirements;
using bt::hci::IOCapability;
using bt::testing::CommandTransaction;

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

constexpr hci::ConnectionHandle kConnectionHandle = 0x0BAA;
constexpr hci::ConnectionHandle kConnectionHandle2 = 0x0BAB;
const DeviceAddress kLocalDevAddr(DeviceAddress::Type::kBREDR, {0});
const DeviceAddress kTestDevAddr(DeviceAddress::Type::kBREDR, {1});
const DeviceAddress kTestDevAddrLe(DeviceAddress::Type::kLEPublic, {2});
const DeviceAddress kTestDevAddr2(DeviceAddress::Type::kBREDR, {3});
constexpr uint32_t kPasskey = 123456;
const hci::LinkKey kRawKey({0xc0, 0xde, 0xfa, 0x57, 0x4b, 0xad, 0xf0, 0x0d, 0xa7, 0x60, 0x06, 0x1e,
                            0xca, 0x1e, 0xca, 0xfe},
                           0, 0);
const sm::LTK kLinkKey(sm::SecurityProperties(hci::LinkKeyType::kAuthenticatedCombination192),
                       kRawKey);

// A default size for PDUs when generating responses for testing.
const uint16_t PDU_MAX = 0xFFF;

#define TEST_DEV_ADDR_BYTES_LE 0x01, 0x00, 0x00, 0x00, 0x00, 0x00

// clang-format off

const auto kReadScanEnable = CreateStaticByteBuffer(
    LowerBits(hci::kReadScanEnable), UpperBits(hci::kReadScanEnable),
    0x00  // No parameters
);

#define READ_SCAN_ENABLE_RSP(scan_enable)                                    \
  CreateStaticByteBuffer(hci::kCommandCompleteEventCode, 0x05, 0xF0,         \
                                 LowerBits(hci::kReadScanEnable),            \
                                 UpperBits(hci::kReadScanEnable),            \
                                 hci::kSuccess, (scan_enable))

const auto kReadScanEnableRspNone = READ_SCAN_ENABLE_RSP(0x00);
const auto kReadScanEnableRspInquiry = READ_SCAN_ENABLE_RSP(0x01);
const auto kReadScanEnableRspPage = READ_SCAN_ENABLE_RSP(0x02);
const auto kReadScanEnableRspBoth = READ_SCAN_ENABLE_RSP(0x03);

#undef READ_SCAN_ENABLE_RSP

#define WRITE_SCAN_ENABLE_CMD(scan_enable)                               \
  CreateStaticByteBuffer(LowerBits(hci::kWriteScanEnable),               \
                                 UpperBits(hci::kWriteScanEnable), 0x01, \
                                 (scan_enable))

const auto kWriteScanEnableNone = WRITE_SCAN_ENABLE_CMD(0x00);
const auto kWriteScanEnableInq = WRITE_SCAN_ENABLE_CMD(0x01);
const auto kWriteScanEnablePage = WRITE_SCAN_ENABLE_CMD(0x02);
const auto kWriteScanEnableBoth = WRITE_SCAN_ENABLE_CMD(0x03);

#undef WRITE_SCAN_ENABLE_CMD

#define COMMAND_COMPLETE_RSP(opcode)                                         \
  CreateStaticByteBuffer(hci::kCommandCompleteEventCode, 0x04, 0xF0,         \
                                 LowerBits((opcode)), UpperBits((opcode)),   \
                                 hci::kSuccess);

const auto kWriteScanEnableRsp = COMMAND_COMPLETE_RSP(hci::kWriteScanEnable);

const auto kWritePageScanActivity = CreateStaticByteBuffer(
    LowerBits(hci::kWritePageScanActivity),
    UpperBits(hci::kWritePageScanActivity),
    0x04,  // parameter_total_size (4 bytes)
    0x00, 0x08,  // 1.28s interval (R1)
    0x11, 0x00  // 10.625ms window (R1)
);

const auto kWritePageScanActivityRsp =
    COMMAND_COMPLETE_RSP(hci::kWritePageScanActivity);

const auto kWritePageScanType = CreateStaticByteBuffer(
    LowerBits(hci::kWritePageScanType), UpperBits(hci::kWritePageScanType),
    0x01,  // parameter_total_size (1 byte)
    0x01   // Interlaced scan
);

const auto kWritePageScanTypeRsp =
    COMMAND_COMPLETE_RSP(hci::kWritePageScanType);


#define COMMAND_STATUS_RSP(opcode, statuscode)                       \
  CreateStaticByteBuffer(hci::kCommandStatusEventCode, 0x04,         \
                                 (statuscode), 0xF0,                 \
                                 LowerBits((opcode)), UpperBits((opcode)));

// clang-format on

const auto kConnectionRequest = testing::ConnectionRequestPacket(kTestDevAddr);

const auto kAcceptConnectionRequest = testing::AcceptConnectionRequestPacket(kTestDevAddr);

const auto kAcceptConnectionRequestRsp =
    COMMAND_STATUS_RSP(hci::kAcceptConnectionRequest, hci::StatusCode::kSuccess);

const auto kConnectionComplete = testing::ConnectionCompletePacket(kTestDevAddr, kConnectionHandle);

const auto kConnectionCompleteError =
    CreateStaticByteBuffer(hci::kConnectionCompleteEventCode,
                           0x0B,  // parameter_total_size (11 byte payload)
                           hci::StatusCode::kConnectionFailedToBeEstablished,  // status
                           0x00, 0x00,                                         // connection_handle
                           TEST_DEV_ADDR_BYTES_LE,                             // peer address
                           0x01,                                               // link_type (ACL)
                           0x00  // encryption not enabled
    );

const auto kConnectionCompleteCanceled =
    CreateStaticByteBuffer(hci::kConnectionCompleteEventCode,
                           0x0B,  // parameter_total_size (11 byte payload)
                           hci::StatusCode::kUnknownConnectionId,  // status
                           0x00, 0x00,                             // connection_handle
                           TEST_DEV_ADDR_BYTES_LE,                 // peer address
                           0x01,                                   // link_type (ACL)
                           0x00                                    // encryption not enabled
    );

const auto kCreateConnection =
    CreateStaticByteBuffer(LowerBits(hci::kCreateConnection), UpperBits(hci::kCreateConnection),
                           0x0d,                    // parameter_total_size (13 bytes)
                           TEST_DEV_ADDR_BYTES_LE,  // peer address
                           LowerBits(hci::kEnableAllPacketTypes),  // allowable packet types
                           UpperBits(hci::kEnableAllPacketTypes),  // allowable packet types
                           0x02,                                   // page_scan_repetition_mode (R2)
                           0x00,                                   // reserved
                           0x00, 0x00,                             // clock_offset
                           0x00                                    // allow_role_switch (don't)
    );

const auto kCreateConnectionRsp =
    COMMAND_STATUS_RSP(hci::kCreateConnection, hci::StatusCode::kSuccess);

const auto kCreateConnectionRspError =
    COMMAND_STATUS_RSP(hci::kCreateConnection, hci::StatusCode::kConnectionFailedToBeEstablished);

const auto kCreateConnectionCancel = CreateStaticByteBuffer(LowerBits(hci::kCreateConnectionCancel),
                                                            UpperBits(hci::kCreateConnectionCancel),
                                                            0x06,  // parameter_total_size (6 bytes)
                                                            TEST_DEV_ADDR_BYTES_LE  // peer address
);

const auto kCreateConnectionCancelRsp = COMMAND_COMPLETE_RSP(hci::kCreateConnectionCancel);

const auto kRemoteNameRequest =
    CreateStaticByteBuffer(LowerBits(hci::kRemoteNameRequest), UpperBits(hci::kRemoteNameRequest),
                           0x0a,                    // parameter_total_size (10 bytes)
                           TEST_DEV_ADDR_BYTES_LE,  // peer address
                           0x00,                    // page_scan_repetition_mode (R0)
                           0x00,                    // reserved
                           0x00, 0x00               // clock_offset
    );
const auto kRemoteNameRequestRsp =
    COMMAND_STATUS_RSP(hci::kRemoteNameRequest, hci::StatusCode::kSuccess);

const auto kRemoteNameRequestComplete =
    CreateStaticByteBuffer(hci::kRemoteNameRequestCompleteEventCode,
                           0x20,                       // parameter_total_size (32)
                           hci::StatusCode::kSuccess,  // status
                           TEST_DEV_ADDR_BYTES_LE,     // peer address
                           'F', 'u', 'c', 'h', 's', 'i', 'a', 0xF0, 0x9F, 0x92, 0x96, 0x00, 0x14,
                           0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
                           // remote name (Fuchsia 💖)
                           // Everything after the 0x00 should be ignored.
    );
const auto kReadRemoteVersionInfo = CreateStaticByteBuffer(LowerBits(hci::kReadRemoteVersionInfo),
                                                           UpperBits(hci::kReadRemoteVersionInfo),
                                                           0x02,  // Parameter_total_size (2 bytes)
                                                           0xAA, 0x0B  // connection_handle
);

const auto kReadRemoteVersionInfoRsp =
    COMMAND_STATUS_RSP(hci::kReadRemoteVersionInfo, hci::StatusCode::kSuccess);

const auto kRemoteVersionInfoComplete =
    CreateStaticByteBuffer(hci::kReadRemoteVersionInfoCompleteEventCode,
                           0x08,                       // parameter_total_size (8 bytes)
                           hci::StatusCode::kSuccess,  // status
                           0xAA, 0x0B,                 // connection_handle
                           hci::HCIVersion::k4_2,      // lmp_version
                           0xE0, 0x00,                 // manufacturer_name (Google)
                           0xAD, 0xDE                  // lmp_subversion (anything)
    );

const auto kReadRemoteSupportedFeatures = CreateStaticByteBuffer(
    LowerBits(hci::kReadRemoteSupportedFeatures), UpperBits(hci::kReadRemoteSupportedFeatures),
    0x02,       // parameter_total_size (2 bytes)
    0xAA, 0x0B  // connection_handle
);

const auto kReadRemoteSupportedFeaturesRsp =
    COMMAND_STATUS_RSP(hci::kReadRemoteSupportedFeatures, hci::StatusCode::kSuccess);

const auto kReadRemoteSupportedFeaturesComplete =
    CreateStaticByteBuffer(hci::kReadRemoteSupportedFeaturesCompleteEventCode,
                           0x0B,                       // parameter_total_size (11 bytes)
                           hci::StatusCode::kSuccess,  // status
                           0xAA, 0x0B,                 // connection_handle,
                           0xFF, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80
                           // lmp_features
                           // Set: 3 slot packets, 5 slot packets, Encryption, Timing Accuracy,
                           // Role Switch, Hold Mode, Sniff Mode, LE Supported, Extended Features
    );

const auto kReadRemoteExtended1 = CreateStaticByteBuffer(
    LowerBits(hci::kReadRemoteExtendedFeatures), UpperBits(hci::kReadRemoteExtendedFeatures),
    0x03,        // parameter_total_size (3 bytes)
    0xAA, 0x0B,  // connection_handle
    0x01         // page_number (1)
);

const auto kReadRemoteExtendedFeaturesRsp =
    COMMAND_STATUS_RSP(hci::kReadRemoteExtendedFeatures, hci::StatusCode::kSuccess);

const auto kReadRemoteExtended1Complete =
    CreateStaticByteBuffer(hci::kReadRemoteExtendedFeaturesCompleteEventCode,
                           0x0D,                       // parameter_total_size (13 bytes)
                           hci::StatusCode::kSuccess,  // status
                           0xAA, 0x0B,                 // connection_handle,
                           0x01,                       // page_number
                           0x03,                       // max_page_number (3 pages)
                           0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
                           // lmp_features
                           // Set: Secure Simple Pairing (Host Support), LE Supported (Host),
                           //  SimultaneousLEAndBREDR, Secure Connections (Host Support)
    );

const auto kReadRemoteExtended2 = CreateStaticByteBuffer(
    LowerBits(hci::kReadRemoteExtendedFeatures), UpperBits(hci::kReadRemoteExtendedFeatures),
    0x03,        // parameter_total_size (3 bytes)
    0xAA, 0x0B,  // connection_handle
    0x02         // page_number (2)
);

const auto kReadRemoteExtended2Complete =
    CreateStaticByteBuffer(hci::kReadRemoteExtendedFeaturesCompleteEventCode,
                           0x0D,                       // parameter_total_size (13 bytes)
                           hci::StatusCode::kSuccess,  // status
                           0xAA, 0x0B,                 // connection_handle,
                           0x02,                       // page_number
                           0x03,                       // max_page_number (3 pages)
                           0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xFF, 0x00
                           // lmp_features  - All the bits should be ignored.
    );

const auto kDisconnect = testing::DisconnectPacket(kConnectionHandle);

const auto kDisconnectRsp = COMMAND_STATUS_RSP(hci::kDisconnect, hci::StatusCode::kSuccess);

const auto kDisconnectionComplete =
    CreateStaticByteBuffer(hci::kDisconnectionCompleteEventCode,
                           0x04,                       // parameter_total_size (4 bytes)
                           hci::StatusCode::kSuccess,  // status
                           0xAA, 0x0B,                 // connection_handle
                           0x13                        // Reason (Remote User Terminated Connection)
    );

const auto kAuthenticationRequested = CreateStaticByteBuffer(
    LowerBits(hci::kAuthenticationRequested), UpperBits(hci::kAuthenticationRequested),
    0x02,       // parameter_total_size (2 bytes)
    0xAA, 0x0B  // Connection_Handle
);

const auto kAuthenticationRequestedStatus =
    COMMAND_STATUS_RSP(hci::kAuthenticationRequested, hci::StatusCode::kSuccess);

const auto kAuthenticationComplete = CreateStaticByteBuffer(hci::kAuthenticationCompleteEventCode,
                                                            0x03,  // parameter_total_size (3 bytes)
                                                            hci::StatusCode::kSuccess,  // status
                                                            0xAA, 0x0B  // connection_handle
);

const auto kAuthenticationCompleteFailed =
    CreateStaticByteBuffer(hci::kAuthenticationCompleteEventCode,
                           0x03,                                 // parameter_total_size (3 bytes)
                           hci::StatusCode::kPairingNotAllowed,  // status
                           0xAA, 0x0B                            // connection_handle
    );

const auto kLinkKeyRequest = CreateStaticByteBuffer(hci::kLinkKeyRequestEventCode,
                                                    0x06,  // parameter_total_size (6 bytes)
                                                    TEST_DEV_ADDR_BYTES_LE  // peer address
);

const auto kLinkKeyRequestNegativeReply = CreateStaticByteBuffer(
    LowerBits(hci::kLinkKeyRequestNegativeReply), UpperBits(hci::kLinkKeyRequestNegativeReply),
    0x06,                   // parameter_total_size (6 bytes)
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

const auto kLinkKeyRequestNegativeReplyRsp = CreateStaticByteBuffer(
    hci::kCommandCompleteEventCode, 0x0A, 0xF0, LowerBits(hci::kLinkKeyRequestNegativeReply),
    UpperBits(hci::kLinkKeyRequestNegativeReply),
    hci::kSuccess,          // status
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

auto MakeIoCapabilityResponse(IOCapability io_cap, AuthRequirements auth_req) {
  return CreateStaticByteBuffer(hci::kIOCapabilityResponseEventCode,
                                0x09,                    // parameter_total_size (9 bytes)
                                TEST_DEV_ADDR_BYTES_LE,  // address
                                io_cap,
                                0x00,  // OOB authentication data not present
                                auth_req);
}

const auto kIoCapabilityRequest = CreateStaticByteBuffer(hci::kIOCapabilityRequestEventCode,
                                                         0x06,  // parameter_total_size (6 bytes)
                                                         TEST_DEV_ADDR_BYTES_LE  // address
);

auto MakeIoCapabilityRequestReply(IOCapability io_cap, AuthRequirements auth_req) {
  return CreateStaticByteBuffer(LowerBits(hci::kIOCapabilityRequestReply),
                                UpperBits(hci::kIOCapabilityRequestReply),
                                0x09,                    // parameter_total_size (9 bytes)
                                TEST_DEV_ADDR_BYTES_LE,  // peer address
                                io_cap,
                                0x00,  // No OOB data present
                                auth_req);
}

const auto kIoCapabilityRequestReplyRsp = CreateStaticByteBuffer(
    hci::kCommandCompleteEventCode, 0x0A, 0xF0, LowerBits(hci::kIOCapabilityRequestReply),
    UpperBits(hci::kIOCapabilityRequestReply),
    hci::kSuccess,          // status
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

const auto kIoCapabilityRequestNegativeReply =
    CreateStaticByteBuffer(LowerBits(hci::kIOCapabilityRequestNegativeReply),
                           UpperBits(hci::kIOCapabilityRequestNegativeReply),
                           0x07,                    // parameter_total_size (7 bytes)
                           TEST_DEV_ADDR_BYTES_LE,  // peer address
                           hci::StatusCode::kPairingNotAllowed);

const auto kIoCapabilityRequestNegativeReplyRsp = CreateStaticByteBuffer(
    hci::kCommandCompleteEventCode, 0x0A, 0xF0, LowerBits(hci::kIOCapabilityRequestNegativeReply),
    UpperBits(hci::kIOCapabilityRequestNegativeReply),
    hci::kSuccess,            // status
    TEST_DEV_ADDR_BYTES_LE);  // peer address

auto MakeUserConfirmationRequest(uint32_t passkey) {
  const auto passkey_bytes = ToBytes(kPasskey);
  return CreateStaticByteBuffer(hci::kUserConfirmationRequestEventCode,
                                0x0A,                    // parameter_total_size (10 byte payload)
                                TEST_DEV_ADDR_BYTES_LE,  // peer address
                                passkey_bytes[0], passkey_bytes[1], passkey_bytes[2],
                                0x00  // numeric value
  );
}

const auto kUserConfirmationRequestReply = CreateStaticByteBuffer(
    LowerBits(hci::kUserConfirmationRequestReply), UpperBits(hci::kUserConfirmationRequestReply),
    0x06,                   // parameter_total_size (6 bytes)
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

const auto kUserConfirmationRequestReplyRsp =
    COMMAND_COMPLETE_RSP(hci::kUserConfirmationRequestReply);

const auto kUserConfirmationRequestNegativeReply =
    CreateStaticByteBuffer(LowerBits(hci::kUserConfirmationRequestNegativeReply),
                           UpperBits(hci::kUserConfirmationRequestNegativeReply),
                           0x06,                   // parameter_total_size (6 bytes)
                           TEST_DEV_ADDR_BYTES_LE  // peer address
    );

const auto kUserConfirmationRequestNegativeReplyRsp =
    COMMAND_COMPLETE_RSP(hci::kUserConfirmationRequestNegativeReply);

const auto kSimplePairingCompleteSuccess =
    CreateStaticByteBuffer(hci::kSimplePairingCompleteEventCode,
                           0x07,                   // parameter_total_size (7 byte payload)
                           0x00,                   // status (success)
                           TEST_DEV_ADDR_BYTES_LE  // peer address
    );

const auto kSimplePairingCompleteError =
    CreateStaticByteBuffer(hci::kSimplePairingCompleteEventCode,
                           0x07,                   // parameter_total_size (7 byte payload)
                           0x05,                   // status (authentication failure)
                           TEST_DEV_ADDR_BYTES_LE  // peer address
    );

const auto kLinkKeyNotification =
    CreateStaticByteBuffer(hci::kLinkKeyNotificationEventCode,
                           0x17,                    // parameter_total_size (17 bytes)
                           TEST_DEV_ADDR_BYTES_LE,  // peer address
                           0xc0, 0xde, 0xfa, 0x57, 0x4b, 0xad, 0xf0, 0x0d, 0xa7, 0x60, 0x06, 0x1e,
                           0xca, 0x1e, 0xca, 0xfe,  // link key
                           0x05  // key type (Authenticated Combination Key generated from P-192)
    );

const auto kLinkKeyRequestReply = CreateStaticByteBuffer(
    LowerBits(hci::kLinkKeyRequestReply), UpperBits(hci::kLinkKeyRequestReply),
    0x16,                    // parameter_total_size (22 bytes)
    TEST_DEV_ADDR_BYTES_LE,  // peer address
    0xc0, 0xde, 0xfa, 0x57, 0x4b, 0xad, 0xf0, 0x0d, 0xa7, 0x60, 0x06, 0x1e, 0xca, 0x1e, 0xca,
    0xfe  // link key
);

const auto kLinkKeyRequestReplyRsp = CreateStaticByteBuffer(
    hci::kCommandCompleteEventCode, 0x0A, 0xF0, LowerBits(hci::kLinkKeyRequestReply),
    UpperBits(hci::kLinkKeyRequestReply),
    hci::kSuccess,          // status
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

const auto kLinkKeyNotificationChanged =
    CreateStaticByteBuffer(hci::kLinkKeyNotificationEventCode,
                           0x17,                    // parameter_total_size (17 bytes)
                           TEST_DEV_ADDR_BYTES_LE,  // peer address
                           0xfa, 0xce, 0xb0, 0x0c, 0xa5, 0x1c, 0xcd, 0x15, 0xea, 0x5e, 0xfe, 0xdb,
                           0x1d, 0x0d, 0x0a, 0xd5,  // link key
                           0x06                     // key type (Changed Combination Key)
    );

const auto kLinkKeyRequestReplyChanged = CreateStaticByteBuffer(
    LowerBits(hci::kLinkKeyRequestReply), UpperBits(hci::kLinkKeyRequestReply),
    0x16,                    // parameter_total_size (22 bytes)
    TEST_DEV_ADDR_BYTES_LE,  // peer address
    0xfa, 0xce, 0xb0, 0x0c, 0xa5, 0x1c, 0xcd, 0x15, 0xea, 0x5e, 0xfe, 0xdb, 0x1d, 0x0d, 0x0a,
    0xd5  // link key
);

const auto kSetConnectionEncryption = CreateStaticByteBuffer(
    LowerBits(hci::kSetConnectionEncryption), UpperBits(hci::kSetConnectionEncryption),
    0x03,        // parameter total size
    0xAA, 0x0B,  // connection handle
    0x01         // encryption enable
);

const auto kSetConnectionEncryptionRsp =
    COMMAND_STATUS_RSP(hci::kSetConnectionEncryption, hci::StatusCode::kSuccess);

const auto kEncryptionChangeEvent = CreateStaticByteBuffer(hci::kEncryptionChangeEventCode,
                                                           4,           // parameter total size
                                                           0x00,        // status
                                                           0xAA, 0x0B,  // connection handle
                                                           0x01         // encryption enabled
);

const auto kReadEncryptionKeySize = CreateStaticByteBuffer(LowerBits(hci::kReadEncryptionKeySize),
                                                           UpperBits(hci::kReadEncryptionKeySize),
                                                           0x02,       // parameter size
                                                           0xAA, 0x0B  // connection handle
);

const auto kReadEncryptionKeySizeRsp = CreateStaticByteBuffer(
    hci::kCommandCompleteEventCode,
    0x07,  // parameters total size
    0xFF,  // num command packets allowed (255)
    LowerBits(hci::kReadEncryptionKeySize), UpperBits(hci::kReadEncryptionKeySize),
    hci::kSuccess,  // status
    0xAA, 0x0B,     // connection handle
    0x10            // encryption key size: 16
);

auto MakeUserPasskeyRequestReply(uint32_t passkey) {
  const auto passkey_bytes = ToBytes(kPasskey);
  return CreateStaticByteBuffer(LowerBits(hci::kUserPasskeyRequestReply),
                                UpperBits(hci::kUserPasskeyRequestReply),
                                0x0A,                    // parameter_total_size (10 bytes)
                                TEST_DEV_ADDR_BYTES_LE,  // peer address
                                passkey_bytes[0], passkey_bytes[1], passkey_bytes[2],
                                0x00  // numeric value
  );
}

const auto kUserPasskeyRequestReplyRsp = CreateStaticByteBuffer(
    hci::kCommandCompleteEventCode, 0x0A, 0xF0, LowerBits(hci::kUserPasskeyRequestReply),
    UpperBits(hci::kUserPasskeyRequestReply),
    hci::kSuccess,          // status
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

auto MakeUserPasskeyNotification(uint32_t passkey) {
  const auto passkey_bytes = ToBytes(kPasskey);
  return CreateStaticByteBuffer(hci::kUserPasskeyNotificationEventCode,
                                0x0A,                    // parameter_total_size (10 byte payload)
                                TEST_DEV_ADDR_BYTES_LE,  // peer address
                                passkey_bytes[0], passkey_bytes[1], passkey_bytes[2],
                                0x00  // numeric value
  );
}

const hci::DataBufferInfo kBrEdrBufferInfo(1024, 1);
const hci::DataBufferInfo kLeBufferInfo(1024, 1);

constexpr l2cap::ChannelParameters kChannelParams;

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

  void SetUp() override {
    TestingBase::SetUp();
    InitializeACLDataChannel(kBrEdrBufferInfo, kLeBufferInfo);

    peer_cache_ =
        std::make_unique<PeerCache>(inspector_.GetRoot().CreateChild(PeerCache::kInspectNodeName));
    data_domain_ = data::testing::FakeDomain::Create();

    connection_manager_ = std::make_unique<BrEdrConnectionManager>(
        transport()->WeakPtr(), peer_cache_.get(), kLocalDevAddr, data_domain_, true);

    StartTestDevice();

    test_device()->SetTransactionCallback([this] { transaction_count_++; },
                                          async_get_default_dispatcher());
  }

  void TearDown() override {
    // Don't trigger the transaction callback when cleaning up the manager.
    test_device()->ClearTransactionCallback();
    if (connection_manager_ != nullptr) {
      // deallocating the connection manager disables connectivity.
      test_device()->QueueCommandTransaction(
          CommandTransaction(kReadScanEnable, {&kReadScanEnableRspBoth}));
      test_device()->QueueCommandTransaction(
          CommandTransaction(kWriteScanEnableInq, {&kWriteScanEnableRsp}));
      connection_manager_ = nullptr;
    }
    RunLoopUntilIdle();
    test_device()->Stop();
    data_domain_ = nullptr;
    peer_cache_ = nullptr;
    TestingBase::TearDown();
  }

 protected:
  static constexpr const int kIncomingConnTransactions = 6;
  static constexpr const int kDisconnectionTransactions = 1;

  BrEdrConnectionManager* connmgr() const { return connection_manager_.get(); }
  void SetConnectionManager(std::unique_ptr<BrEdrConnectionManager> mgr) {
    connection_manager_ = std::move(mgr);
  }

  PeerCache* peer_cache() const { return peer_cache_.get(); }

  data::testing::FakeDomain* data_domain() const { return data_domain_.get(); }

  int transaction_count() const { return transaction_count_; }

  // Add expectations and simulated responses for the outbound commands sent
  // after an inbound Connection Request Event is received. Results in
  // |kIncomingConnTransactions| transactions.

  void QueueSuccessfulIncomingConn(DeviceAddress addr = kTestDevAddr,
                                   hci::ConnectionHandle handle = kConnectionHandle) const {
    const auto connection_complete = testing::ConnectionCompletePacket(addr, handle);
    test_device()->QueueCommandTransaction(
        CommandTransaction(testing::AcceptConnectionRequestPacket(addr),
                           {&kAcceptConnectionRequestRsp, &connection_complete}));
    QueueSuccessfulInterrogation(addr, handle);
  }

  void QueueSuccessfulCreateConnection(Peer* peer, hci::ConnectionHandle conn) const {
    const DynamicByteBuffer complete_packet =
        testing::ConnectionCompletePacket(peer->address(), conn);
    test_device()->QueueCommandTransaction(
        CommandTransaction(testing::CreateConnectionPacket(peer->address()),
                           {&kCreateConnectionRsp, &complete_packet}));
  }

  void QueueSuccessfulInterrogation(DeviceAddress addr, hci::ConnectionHandle conn) const {
    const DynamicByteBuffer remote_name_complete_packet =
        testing::RemoteNameRequestCompletePacket(addr);
    const DynamicByteBuffer remote_version_complete_packet =
        testing::ReadRemoteVersionInfoCompletePacket(conn);
    const DynamicByteBuffer remote_supported_complete_packet =
        testing::ReadRemoteSupportedFeaturesCompletePacket(conn, true);
    const DynamicByteBuffer remote_extended1_complete_packet =
        testing::ReadRemoteExtended1CompletePacket(conn);
    const DynamicByteBuffer remote_extended2_complete_packet =
        testing::ReadRemoteExtended2CompletePacket(conn);

    test_device()->QueueCommandTransaction(
        CommandTransaction(testing::RemoteNameRequestPacket(addr),
                           {&kRemoteNameRequestRsp, &remote_name_complete_packet}));
    test_device()->QueueCommandTransaction(
        CommandTransaction(testing::ReadRemoteVersionInfoPacket(conn),
                           {&kReadRemoteVersionInfoRsp, &remote_version_complete_packet}));
    test_device()->QueueCommandTransaction(
        CommandTransaction(testing::ReadRemoteSupportedFeaturesPacket(conn),
                           {&kReadRemoteSupportedFeaturesRsp, &remote_supported_complete_packet}));
    test_device()->QueueCommandTransaction(
        CommandTransaction(testing::ReadRemoteExtended1Packet(conn),
                           {&kReadRemoteExtendedFeaturesRsp, &remote_extended1_complete_packet}));
    test_device()->QueueCommandTransaction(
        CommandTransaction(testing::ReadRemoteExtended2Packet(conn),
                           {&kReadRemoteExtendedFeaturesRsp, &remote_extended2_complete_packet}));
  }

  void QueueSuccessfulPairing() {
    test_device()->QueueCommandTransaction(CommandTransaction(
        kAuthenticationRequested, {&kAuthenticationRequestedStatus, &kLinkKeyRequest}));
    test_device()->QueueCommandTransaction(CommandTransaction(
        kLinkKeyRequestNegativeReply, {&kLinkKeyRequestNegativeReplyRsp, &kIoCapabilityRequest}));
    const auto kIoCapabilityResponse = MakeIoCapabilityResponse(
        IOCapability::kDisplayYesNo, AuthRequirements::kMITMGeneralBonding);
    const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
    test_device()->QueueCommandTransaction(CommandTransaction(
        MakeIoCapabilityRequestReply(IOCapability::kDisplayYesNo,
                                     AuthRequirements::kMITMGeneralBonding),
        {&kIoCapabilityRequestReplyRsp, &kIoCapabilityResponse, &kUserConfirmationRequest}));
    test_device()->QueueCommandTransaction(
        CommandTransaction(kUserConfirmationRequestReply,
                           {&kUserConfirmationRequestReplyRsp, &kSimplePairingCompleteSuccess,
                            &kLinkKeyNotification, &kAuthenticationComplete}));
    test_device()->QueueCommandTransaction(CommandTransaction(
        kSetConnectionEncryption, {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent}));
    test_device()->QueueCommandTransaction(
        CommandTransaction(kReadEncryptionKeySize, {&kReadEncryptionKeySizeRsp}));
  }

  void QueueDisconnection(
      hci::ConnectionHandle conn,
      hci::StatusCode reason = hci::StatusCode::kRemoteUserTerminatedConnection) const {
    const DynamicByteBuffer disconnect_complete =
        testing::DisconnectionCompletePacket(conn, reason);
    test_device()->QueueCommandTransaction(CommandTransaction(
        testing::DisconnectPacket(conn, reason), {&kDisconnectRsp, &disconnect_complete}));
  }

 private:
  inspect::Inspector inspector_;
  std::unique_ptr<BrEdrConnectionManager> connection_manager_;
  std::unique_ptr<PeerCache> peer_cache_;
  fbl::RefPtr<data::testing::FakeDomain> data_domain_;
  int transaction_count_ = 0;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BrEdrConnectionManagerTest);
};

using GAP_BrEdrConnectionManagerTest = BrEdrConnectionManagerTest;

TEST_F(GAP_BrEdrConnectionManagerTest, DisableConnectivity) {
  size_t cb_count = 0;
  auto cb = [&cb_count](const auto& status) {
    cb_count++;
    EXPECT_TRUE(status);
  };

  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspPage}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnableNone, {&kWriteScanEnableRsp}));

  connmgr()->SetConnectable(false, cb);

  RunLoopUntilIdle();

  EXPECT_EQ(1u, cb_count);

  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspBoth}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnableInq, {&kWriteScanEnableRsp}));

  connmgr()->SetConnectable(false, cb);

  RunLoopUntilIdle();

  EXPECT_EQ(2u, cb_count);
}

TEST_F(GAP_BrEdrConnectionManagerTest, EnableConnectivity) {
  size_t cb_count = 0;
  auto cb = [&cb_count](const auto& status) {
    cb_count++;
    EXPECT_TRUE(status);
  };

  test_device()->QueueCommandTransaction(
      CommandTransaction(kWritePageScanActivity, {&kWritePageScanActivityRsp}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWritePageScanType, {&kWritePageScanTypeRsp}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspNone}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnablePage, {&kWriteScanEnableRsp}));

  connmgr()->SetConnectable(true, cb);

  RunLoopUntilIdle();

  EXPECT_EQ(1u, cb_count);

  test_device()->QueueCommandTransaction(
      CommandTransaction(kWritePageScanActivity, {&kWritePageScanActivityRsp}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWritePageScanType, {&kWritePageScanTypeRsp}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspInquiry}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnableBoth, {&kWriteScanEnableRsp}));

  connmgr()->SetConnectable(true, cb);

  RunLoopUntilIdle();

  EXPECT_EQ(2u, cb_count);
}

// Test: An incoming connection request should trigger an acceptance and
// interrogation should allow a peer that only report the first Extended
// Features page.
TEST_F(GAP_BrEdrConnectionManagerTest, IncomingConnection_BrokenExtendedPageResponse) {
  test_device()->QueueCommandTransaction(CommandTransaction(
      kAcceptConnectionRequest, {&kAcceptConnectionRequestRsp, &kConnectionComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kRemoteNameRequest, {&kRemoteNameRequestRsp, &kRemoteNameRequestComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteVersionInfo, {&kReadRemoteVersionInfoRsp, &kRemoteVersionInfoComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteSupportedFeatures,
      {&kReadRemoteSupportedFeaturesRsp, &kReadRemoteSupportedFeaturesComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteExtended1, {&kReadRemoteExtendedFeaturesRsp, &kReadRemoteExtended1Complete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteExtended2, {&kReadRemoteExtendedFeaturesRsp, &kReadRemoteExtended1Complete}));

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(6, transaction_count());

  // When we deallocate the connection manager next, we should disconnect.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kDisconnect, {&kDisconnectRsp, &kDisconnectionComplete}));

  // deallocating the connection manager disables connectivity.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspBoth}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnableInq, {&kWriteScanEnableRsp}));

  SetConnectionManager(nullptr);

  RunLoopUntilIdle();

  EXPECT_EQ(9, transaction_count());
}

// Test: An incoming connection request should trigger an acceptance and an
// interrogation to discover capabilities.
TEST_F(GAP_BrEdrConnectionManagerTest, IncomingConnectionSuccess) {
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));
  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  // When we deallocate the connection manager next, we should disconnect.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kDisconnect, {&kDisconnectRsp, &kDisconnectionComplete}));

  // deallocating the connection manager disables connectivity.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspBoth}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnableInq, {&kWriteScanEnableRsp}));

  SetConnectionManager(nullptr);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 3, transaction_count());
}

// Test: An incoming connection request should upgrade a known LE peer with a
// matching address to a dual mode peer.
TEST_F(GAP_BrEdrConnectionManagerTest, IncomingConnectionUpgradesKnownLowEnergyPeerToDualMode) {
  const DeviceAddress le_alias_addr(DeviceAddress::Type::kLEPublic, kTestDevAddr.value());
  Peer* const peer = peer_cache()->NewPeer(le_alias_addr, true);
  ASSERT_TRUE(peer);
  ASSERT_EQ(TechnologyType::kLowEnergy, peer->technology());

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  ASSERT_EQ(peer, peer_cache()->FindByAddress(kTestDevAddr));
  EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));
  EXPECT_EQ(TechnologyType::kDualMode, peer->technology());

  // Prepare for disconnection upon teardown.
  QueueDisconnection(kConnectionHandle);
}

// Test: A remote disconnect should correctly remove the connection.
TEST_F(GAP_BrEdrConnectionManagerTest, RemoteDisconnect) {
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunLoopUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  // Remote end disconnects.
  test_device()->SendCommandChannelPacket(kDisconnectionComplete);

  RunLoopUntilIdle();

  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));

  // deallocating the connection manager disables connectivity.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspBoth}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnableInq, {&kWriteScanEnableRsp}));

  SetConnectionManager(nullptr);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 2, transaction_count());
}

const auto kRemoteNameRequestCompleteFailed =
    CreateStaticByteBuffer(hci::kRemoteNameRequestCompleteEventCode,
                           0x01,  // parameter_total_size (1 bytes)
                           hci::StatusCode::kHardwareFailure);

const auto kReadRemoteSupportedFeaturesCompleteFailed =
    CreateStaticByteBuffer(hci::kReadRemoteSupportedFeaturesCompleteEventCode,
                           0x01,  // parameter_total_size (1 bytes)
                           hci::StatusCode::kHardwareFailure);

// Test: if the interrogation fails, we disconnect.
//  - Receiving extra responses after a command fails will not fail
//  - We don't query extended features if we don't receive an answer.
TEST_F(GAP_BrEdrConnectionManagerTest, IncomingConnectionFailedInterrogation) {
  test_device()->QueueCommandTransaction(CommandTransaction(
      kAcceptConnectionRequest, {&kAcceptConnectionRequestRsp, &kConnectionComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kRemoteNameRequest, {&kRemoteNameRequestRsp, &kRemoteNameRequestCompleteFailed}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteVersionInfo, {&kReadRemoteVersionInfoRsp, &kRemoteVersionInfoComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteSupportedFeatures,
      {&kReadRemoteSupportedFeaturesRsp, &kReadRemoteSupportedFeaturesCompleteFailed}));

  test_device()->QueueCommandTransaction(
      CommandTransaction(kDisconnect, {&kDisconnectRsp, &kDisconnectionComplete}));

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(5, transaction_count());
}

// Test: replies negative to IO Capability Requests before PairingDelegate is set
TEST_F(GAP_BrEdrConnectionManagerTest, IoCapabilityRequestNegativeReplyWithNoPairingDelegate) {
  test_device()->QueueCommandTransaction(kIoCapabilityRequestNegativeReply,
                                         {&kIoCapabilityRequestNegativeReplyRsp});

  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(1, transaction_count());
}

// Test: replies negative to IO Capability Requests for unconnected peers
TEST_F(GAP_BrEdrConnectionManagerTest, IoCapabilityRequestNegativeReplyWhenNotConnected) {
  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  test_device()->QueueCommandTransaction(kIoCapabilityRequestNegativeReply,
                                         {&kIoCapabilityRequestNegativeReplyRsp});

  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(1, transaction_count());
}

// Test: replies to IO Capability Requests for connected peers
TEST_F(GAP_BrEdrConnectionManagerTest, IoCapabilityRequestReplyWhenConnected) {
  FakePairingDelegate pairing_delegate(sm::IOCapability::kNoInputNoOutput);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  ASSERT_EQ(kIncomingConnTransactions, transaction_count());

  test_device()->QueueCommandTransaction(
      MakeIoCapabilityRequestReply(IOCapability::kNoInputNoOutput,
                                   AuthRequirements::kGeneralBonding),
      {&kIoCapabilityRequestReplyRsp});

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kDisplayOnly, AuthRequirements::kMITMGeneralBonding));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  QueueDisconnection(kConnectionHandle);
}

// Test: Responds to Secure Simple Pairing with user rejection of Numeric Comparison association
TEST_F(GAP_BrEdrConnectionManagerTest, RespondToNumericComparisonPairingAfterUserRejects) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  test_device()->QueueCommandTransaction(
      MakeIoCapabilityRequestReply(IOCapability::kDisplayYesNo,
                                   AuthRequirements::kMITMGeneralBonding),
      {&kIoCapabilityRequestReplyRsp});

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kDisplayOnly, AuthRequirements::kGeneralBonding));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        EXPECT_EQ(kPasskey, passkey);
        EXPECT_EQ(PairingDelegate::DisplayMethod::kComparison, method);
        ASSERT_TRUE(confirm_cb);
        confirm_cb(false);
      });

  test_device()->QueueCommandTransaction(kUserConfirmationRequestNegativeReply,
                                         {&kUserConfirmationRequestNegativeReplyRsp});
  test_device()->SendCommandChannelPacket(MakeUserConfirmationRequest(kPasskey));

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_EQ(sm::Status(HostError::kFailed), status); });

  test_device()->SendCommandChannelPacket(kSimplePairingCompleteError);

  // We disconnect the peer when authentication fails.
  QueueDisconnection(kConnectionHandle);

  RunLoopUntilIdle();
}

const auto kUserPasskeyRequest =
    CreateStaticByteBuffer(hci::kUserPasskeyRequestEventCode,
                           0x06,                   // parameter_total_size (6 byte payload)
                           TEST_DEV_ADDR_BYTES_LE  // peer address
    );

const auto kUserPasskeyRequestNegativeReply =
    CreateStaticByteBuffer(LowerBits(hci::kUserPasskeyRequestNegativeReply),
                           UpperBits(hci::kUserPasskeyRequestNegativeReply),
                           0x06,                   // parameter_total_size (6 bytes)
                           TEST_DEV_ADDR_BYTES_LE  // peer address
    );

const auto kUserPasskeyRequestNegativeReplyRsp = CreateStaticByteBuffer(
    hci::kCommandCompleteEventCode, 0x0A, 0xF0, LowerBits(hci::kUserPasskeyRequestNegativeReply),
    UpperBits(hci::kUserPasskeyRequestNegativeReply),
    hci::kSuccess,          // status
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

// Test: Responds to Secure Simple Pairing as the input side of Passkey Entry association after the
// user declines or provides invalid input
TEST_F(GAP_BrEdrConnectionManagerTest,
       RespondToPasskeyEntryPairingAfterUserProvidesInvalidPasskey) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kKeyboardOnly);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  test_device()->QueueCommandTransaction(
      MakeIoCapabilityRequestReply(IOCapability::kKeyboardOnly,
                                   AuthRequirements::kMITMGeneralBonding),
      {&kIoCapabilityRequestReplyRsp});

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kDisplayOnly, AuthRequirements::kGeneralBonding));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  pairing_delegate.SetRequestPasskeyCallback([](PeerId, auto response_cb) {
    ASSERT_TRUE(response_cb);
    response_cb(-128);  // Negative values indicate rejection.
  });

  test_device()->QueueCommandTransaction(kUserPasskeyRequestNegativeReply,
                                         {&kUserPasskeyRequestNegativeReplyRsp});
  test_device()->SendCommandChannelPacket(kUserPasskeyRequest);

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_EQ(sm::Status(HostError::kFailed), status); });

  test_device()->SendCommandChannelPacket(kSimplePairingCompleteError);

  // We disconnect the peer when authentication fails.
  QueueDisconnection(kConnectionHandle);

  RunLoopUntilIdle();
}

// Test: replies negative to Link Key Requests for unknown and unbonded peers
TEST_F(GAP_BrEdrConnectionManagerTest, LinkKeyRequestAndNegativeReply) {
  test_device()->QueueCommandTransaction(kLinkKeyRequestNegativeReply,
                                         {&kLinkKeyRequestNegativeReplyRsp});

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(1, transaction_count());

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->connected());
  ASSERT_FALSE(peer->bonded());

  test_device()->QueueCommandTransaction(kLinkKeyRequestNegativeReply,
                                         {&kLinkKeyRequestNegativeReplyRsp});

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 2, transaction_count());

  QueueDisconnection(kConnectionHandle);
}

// Test: replies to Link Key Requests for bonded peer
TEST_F(GAP_BrEdrConnectionManagerTest, RecallLinkKeyForBondedPeer) {
  ASSERT_TRUE(
      peer_cache()->AddBondedPeer(BondingData{PeerId(999), kTestDevAddr, {}, {}, kLinkKey}));
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_FALSE(peer->connected());
  ASSERT_TRUE(peer->bonded());

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  ASSERT_TRUE(peer->connected());

  test_device()->QueueCommandTransaction(kLinkKeyRequestReply, {&kLinkKeyRequestReplyRsp});

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  QueueDisconnection(kConnectionHandle);
}

// Test: Responds to Secure Simple Pairing as the input side of Passkey Entry association after the
// user provides the correct passkey
TEST_F(GAP_BrEdrConnectionManagerTest,
       EncryptAfterPasskeyEntryPairingAndUserProvidesAcceptedPasskey) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->connected());
  ASSERT_FALSE(peer->bonded());

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kKeyboardOnly);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  test_device()->QueueCommandTransaction(
      MakeIoCapabilityRequestReply(IOCapability::kKeyboardOnly,
                                   AuthRequirements::kMITMGeneralBonding),
      {&kIoCapabilityRequestReplyRsp});

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kDisplayOnly, AuthRequirements::kGeneralBonding));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  pairing_delegate.SetRequestPasskeyCallback([](PeerId, auto response_cb) {
    ASSERT_TRUE(response_cb);
    response_cb(kPasskey);
  });

  test_device()->QueueCommandTransaction(MakeUserPasskeyRequestReply(kPasskey),
                                         {&kUserPasskeyRequestReplyRsp});
  test_device()->SendCommandChannelPacket(kUserPasskeyRequest);

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  test_device()->SendCommandChannelPacket(kSimplePairingCompleteSuccess);
  test_device()->SendCommandChannelPacket(kLinkKeyNotification);

  test_device()->QueueCommandTransaction(kSetConnectionEncryption,
                                         {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent});
  test_device()->QueueCommandTransaction(kReadEncryptionKeySize, {&kReadEncryptionKeySizeRsp});

  RETURN_IF_FATAL(RunLoopUntilIdle());
  EXPECT_TRUE(peer->bonded());

  QueueDisconnection(kConnectionHandle);
}

// Test: Responds to Secure Simple Pairing as the display side of Passkey Entry association after
// the user provides the correct passkey on the peer
TEST_F(GAP_BrEdrConnectionManagerTest, EncryptAfterPasskeyDisplayPairing) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->connected());
  ASSERT_FALSE(peer->bonded());

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayOnly);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  test_device()->QueueCommandTransaction(
      MakeIoCapabilityRequestReply(IOCapability::kDisplayOnly,
                                   AuthRequirements::kMITMGeneralBonding),
      {&kIoCapabilityRequestReplyRsp});

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kKeyboardOnly, AuthRequirements::kGeneralBonding));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        EXPECT_EQ(kPasskey, passkey);
        EXPECT_EQ(PairingDelegate::DisplayMethod::kPeerEntry, method);
        EXPECT_TRUE(confirm_cb);
      });

  test_device()->SendCommandChannelPacket(MakeUserPasskeyNotification(kPasskey));

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  test_device()->SendCommandChannelPacket(kSimplePairingCompleteSuccess);
  test_device()->SendCommandChannelPacket(kLinkKeyNotification);

  test_device()->QueueCommandTransaction(kSetConnectionEncryption,
                                         {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent});
  test_device()->QueueCommandTransaction(kReadEncryptionKeySize, {&kReadEncryptionKeySizeRsp});

  RETURN_IF_FATAL(RunLoopUntilIdle());
  EXPECT_TRUE(peer->bonded());

  QueueDisconnection(kConnectionHandle);
}

// Test: Responds to Secure Simple Pairing and user confirmation of Numeric Comparison association,
// then bonds and encrypts using resulting link key
TEST_F(GAP_BrEdrConnectionManagerTest, EncryptAndBondAfterNumericComparisonPairingAndUserConfirms) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->connected());
  ASSERT_FALSE(peer->bonded());

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  test_device()->QueueCommandTransaction(
      MakeIoCapabilityRequestReply(IOCapability::kDisplayYesNo,
                                   AuthRequirements::kMITMGeneralBonding),
      {&kIoCapabilityRequestReplyRsp});

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kDisplayYesNo, AuthRequirements::kGeneralBonding));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        EXPECT_EQ(kPasskey, passkey);
        EXPECT_EQ(PairingDelegate::DisplayMethod::kComparison, method);
        ASSERT_TRUE(confirm_cb);
        confirm_cb(true);
      });

  test_device()->QueueCommandTransaction(kUserConfirmationRequestReply,
                                         {&kUserConfirmationRequestReplyRsp});
  test_device()->SendCommandChannelPacket(MakeUserConfirmationRequest(kPasskey));

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  test_device()->SendCommandChannelPacket(kSimplePairingCompleteSuccess);
  test_device()->SendCommandChannelPacket(kLinkKeyNotification);

  test_device()->QueueCommandTransaction(kSetConnectionEncryption,
                                         {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent});
  test_device()->QueueCommandTransaction(kReadEncryptionKeySize, {&kReadEncryptionKeySizeRsp});

  RETURN_IF_FATAL(RunLoopUntilIdle());
  EXPECT_TRUE(peer->bonded());

  test_device()->QueueCommandTransaction(kLinkKeyRequestReply, {&kLinkKeyRequestReplyRsp});
  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunLoopUntilIdle();

  QueueDisconnection(kConnectionHandle);
}

// Test: can't change the link key of an unbonded peer
TEST_F(GAP_BrEdrConnectionManagerTest, UnbondedPeerChangeLinkKey) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->connected());
  ASSERT_FALSE(peer->bonded());

  // Change the link key.
  test_device()->SendCommandChannelPacket(kLinkKeyNotificationChanged);

  RunLoopUntilIdle();
  EXPECT_FALSE(peer->bonded());

  test_device()->QueueCommandTransaction(kLinkKeyRequestNegativeReply, {&kLinkKeyRequestReplyRsp});

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunLoopUntilIdle();

  EXPECT_FALSE(peer->bonded());
  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  QueueDisconnection(kConnectionHandle);
}

const auto kLinkKeyNotificationLegacy =
    CreateStaticByteBuffer(hci::kLinkKeyNotificationEventCode,
                           0x17,                    // parameter_total_size (17 bytes)
                           TEST_DEV_ADDR_BYTES_LE,  // peer address
                           0x41, 0x33, 0x7c, 0x0d, 0xef, 0xee, 0xda, 0xda, 0xba, 0xad, 0x0f, 0xf1,
                           0xce, 0xc0, 0xff, 0xee,  // link key
                           0x00                     // key type (Combination Key)
    );

// Test: don't bond if the link key resulted from legacy pairing
TEST_F(GAP_BrEdrConnectionManagerTest, LegacyLinkKeyNotBonded) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->connected());
  ASSERT_FALSE(peer->bonded());

  test_device()->SendCommandChannelPacket(kLinkKeyNotificationLegacy);

  RunLoopUntilIdle();
  EXPECT_FALSE(peer->bonded());

  test_device()->QueueCommandTransaction(kLinkKeyRequestNegativeReply, {&kLinkKeyRequestReplyRsp});

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunLoopUntilIdle();

  EXPECT_FALSE(peer->bonded());
  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  QueueDisconnection(kConnectionHandle);
}

// Test: if L2CAP gets a link error, we disconnect the connection
TEST_F(GAP_BrEdrConnectionManagerTest, DisconnectOnLinkError) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  // When we deallocate the connection manager next, we should disconnect.
  QueueDisconnection(kConnectionHandle);

  data_domain()->TriggerLinkError(kConnectionHandle);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadScanEnable, {&kReadScanEnableRspBoth}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kWriteScanEnableInq, {&kWriteScanEnableRsp}));

  SetConnectionManager(nullptr);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 3, transaction_count());
}

TEST_F(GAP_BrEdrConnectionManagerTest, ConnectedPeerTimeout) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_TRUE(peer->connected());

  // We want to make sure the connection doesn't expire.
  RunLoopFor(zx::sec(600));

  // Remote end disconnects.
  test_device()->SendCommandChannelPacket(kDisconnectionComplete);

  RunLoopUntilIdle();

  // Peer should still be there, but not connected anymore
  peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_FALSE(peer->connected());
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));
}

TEST_F(GAP_BrEdrConnectionManagerTest, ServiceSearch) {
  size_t search_cb_count = 0;
  auto search_cb = [&](auto id, const auto& attributes) {
    auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
    ASSERT_TRUE(peer);
    ASSERT_EQ(id, peer->identifier());
    ASSERT_EQ(1u, attributes.count(sdp::kServiceId));
    search_cb_count++;
  };

  auto search_id =
      connmgr()->AddServiceSearch(sdp::profile::kAudioSink, {sdp::kServiceId}, search_cb);

  fbl::RefPtr<l2cap::testing::FakeChannel> sdp_chan;
  std::optional<uint32_t> sdp_request_tid;

  data_domain()->set_channel_callback([&sdp_chan, &sdp_request_tid](auto new_chan) {
    new_chan->SetSendCallback(
        [&sdp_request_tid](auto packet) {
          const auto kSearchExpectedParams = CreateStaticByteBuffer(
              // ServiceSearchPattern
              0x35, 0x03,        // Sequence uint8 3 bytes
              0x19, 0x11, 0x0B,  // UUID (kAudioSink)
              0xFF, 0xFF,        // MaxAttributeByteCount (no max)
              // Attribute ID list
              0x35, 0x03,        // Sequence uint8 3 bytes
              0x09, 0x00, 0x03,  // uint16_t (kServiceId)
              0x00               // No continuation state
          );
          // First byte should be type.
          ASSERT_LE(3u, packet->size());
          ASSERT_EQ(sdp::kServiceSearchAttributeRequest, (*packet)[0]);
          ASSERT_EQ(kSearchExpectedParams, packet->view(5));
          sdp_request_tid = (*packet)[1] << 8 || (*packet)[2];
        },
        async_get_default_dispatcher());
    sdp_chan = std::move(new_chan);
  });

  QueueSuccessfulIncomingConn();
  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, 0x40, 0x41,
                                            kChannelParams);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  ASSERT_TRUE(sdp_chan);
  ASSERT_TRUE(sdp_request_tid);
  ASSERT_EQ(0u, search_cb_count);

  sdp::ServiceSearchAttributeResponse rsp;
  rsp.SetAttribute(0, sdp::kServiceId, sdp::DataElement(UUID()));
  auto rsp_ptr =
      rsp.GetPDU(0xFFFF /* max attribute bytes */, *sdp_request_tid, PDU_MAX, BufferView());

  sdp_chan->Receive(*rsp_ptr);

  RunLoopUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

  // Remote end disconnects.
  test_device()->SendCommandChannelPacket(kDisconnectionComplete);

  RunLoopUntilIdle();

  sdp_request_tid.reset();

  EXPECT_TRUE(connmgr()->RemoveServiceSearch(search_id));
  EXPECT_FALSE(connmgr()->RemoveServiceSearch(search_id));

  // Second connection is shortened because we have already interrogated,
  // and we don't search for SDP services because none are registered
  test_device()->QueueCommandTransaction(CommandTransaction(
      kAcceptConnectionRequest, {&kAcceptConnectionRequestRsp, &kConnectionComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteExtended1, {&kReadRemoteExtendedFeaturesRsp, &kReadRemoteExtended1Complete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteExtended2, {&kReadRemoteExtendedFeaturesRsp, &kReadRemoteExtended2Complete}));

  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunLoopUntilIdle();

  // We shouldn't have searched for anything.
  ASSERT_FALSE(sdp_request_tid);
  ASSERT_EQ(1u, search_cb_count);

  QueueDisconnection(kConnectionHandle);
}

TEST_F(GAP_BrEdrConnectionManagerTest, SearchOnReconnect) {
  size_t search_cb_count = 0;
  auto search_cb = [&](auto id, const auto& attributes) {
    auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
    ASSERT_TRUE(peer);
    ASSERT_EQ(id, peer->identifier());
    ASSERT_EQ(1u, attributes.count(sdp::kServiceId));
    search_cb_count++;
  };

  connmgr()->AddServiceSearch(sdp::profile::kAudioSink, {sdp::kServiceId}, search_cb);

  fbl::RefPtr<l2cap::testing::FakeChannel> sdp_chan;
  std::optional<uint32_t> sdp_request_tid;

  data_domain()->set_channel_callback([&sdp_chan, &sdp_request_tid](auto new_chan) {
    new_chan->SetSendCallback(
        [&sdp_request_tid](auto packet) {
          const auto kSearchExpectedParams = CreateStaticByteBuffer(
              // ServiceSearchPattern
              0x35, 0x03,        // Sequence uint8 3 bytes
              0x19, 0x11, 0x0B,  // UUID (kAudioSink)
              0xFF, 0xFF,        // MaxAttributeByteCount (no max)
              // Attribute ID list
              0x35, 0x03,        // Sequence uint8 3 bytes
              0x09, 0x00, 0x03,  // uint16_t (kServiceId)
              0x00               // No continuation state
          );
          // First byte should be type.
          ASSERT_LE(3u, packet->size());
          ASSERT_EQ(sdp::kServiceSearchAttributeRequest, (*packet)[0]);
          ASSERT_EQ(kSearchExpectedParams, packet->view(5));
          sdp_request_tid = (*packet)[1] << 8 || (*packet)[2];
        },
        async_get_default_dispatcher());
    sdp_chan = std::move(new_chan);
  });

  // This test uses a modified peer and interrogation which doesn't use
  // extended pages.
  test_device()->QueueCommandTransaction(CommandTransaction(
      kAcceptConnectionRequest, {&kAcceptConnectionRequestRsp, &kConnectionComplete}));
  const DynamicByteBuffer remote_name_complete_packet =
      testing::RemoteNameRequestCompletePacket(kTestDevAddr);
  const DynamicByteBuffer remote_version_complete_packet =
      testing::ReadRemoteVersionInfoCompletePacket(kConnectionHandle);
  const DynamicByteBuffer remote_supported_complete_packet =
      testing::ReadRemoteSupportedFeaturesCompletePacket(kConnectionHandle, false);

  test_device()->QueueCommandTransaction(
      CommandTransaction(testing::RemoteNameRequestPacket(kTestDevAddr),
                         {&kRemoteNameRequestRsp, &remote_name_complete_packet}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(testing::ReadRemoteVersionInfoPacket(kConnectionHandle),
                         {&kReadRemoteVersionInfoRsp, &remote_version_complete_packet}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(testing::ReadRemoteSupportedFeaturesPacket(kConnectionHandle),
                         {&kReadRemoteSupportedFeaturesRsp, &remote_supported_complete_packet}));

  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, 0x40, 0x41,
                                            kChannelParams);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  ASSERT_TRUE(sdp_chan);
  ASSERT_TRUE(sdp_request_tid);
  ASSERT_EQ(0u, search_cb_count);

  sdp::ServiceSearchAttributeResponse rsp;
  rsp.SetAttribute(0, sdp::kServiceId, sdp::DataElement(UUID()));
  auto rsp_ptr =
      rsp.GetPDU(0xFFFF /* max attribute bytes */, *sdp_request_tid, PDU_MAX, BufferView());

  sdp_chan->Receive(*rsp_ptr);

  RunLoopUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

  // Remote end disconnects.
  test_device()->SendCommandChannelPacket(kDisconnectionComplete);

  RunLoopUntilIdle();

  sdp_request_tid.reset();
  sdp_chan = nullptr;

  // Second connection is shortened because we have already interrogated.
  // We still search for SDP services.
  test_device()->QueueCommandTransaction(CommandTransaction(
      kAcceptConnectionRequest, {&kAcceptConnectionRequestRsp, &kConnectionComplete}));
  // We don't send any interrogation packets, because there is none to be done.

  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, 0x40, 0x41,
                                            kChannelParams);

  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunLoopUntilIdle();

  // We should have searched again.
  ASSERT_TRUE(sdp_chan);
  ASSERT_TRUE(sdp_request_tid);
  ASSERT_EQ(1u, search_cb_count);

  rsp_ptr = rsp.GetPDU(0xFFFF /* max attribute bytes */, *sdp_request_tid, PDU_MAX, BufferView());

  sdp_chan->Receive(*rsp_ptr);

  RunLoopUntilIdle();

  ASSERT_EQ(2u, search_cb_count);

  QueueDisconnection(kConnectionHandle);
}

// Test: when opening an L2CAP channel on an unbonded peer, indicate that we have no link key then
// pair, authenticate, bond, and encrypt the link, then try to open the channel.
TEST_F(GAP_BrEdrConnectionManagerTest, OpenL2capPairsAndEncryptsThenRetries) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());

  std::optional<zx::socket> connected_socket;

  auto socket_cb = [&](auto chan_sock) { connected_socket = std::move(chan_sock.socket); };

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Approve pairing requests.
  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        ASSERT_TRUE(confirm_cb);
        confirm_cb(true);
      });

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  // Initial connection request

  // Pairing initiation and flow that results in bonding then encryption, but verifying the strength
  // of the encryption key doesn't complete
  test_device()->QueueCommandTransaction(CommandTransaction(
      kAuthenticationRequested, {&kAuthenticationRequestedStatus, &kLinkKeyRequest}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kLinkKeyRequestNegativeReply, {&kLinkKeyRequestNegativeReplyRsp, &kIoCapabilityRequest}));
  const auto kIoCapabilityResponse =
      MakeIoCapabilityResponse(IOCapability::kDisplayYesNo, AuthRequirements::kMITMGeneralBonding);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  test_device()->QueueCommandTransaction(CommandTransaction(
      MakeIoCapabilityRequestReply(IOCapability::kDisplayYesNo,
                                   AuthRequirements::kMITMGeneralBonding),
      {&kIoCapabilityRequestReplyRsp, &kIoCapabilityResponse, &kUserConfirmationRequest}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kUserConfirmationRequestReply,
                         {&kUserConfirmationRequestReplyRsp, &kSimplePairingCompleteSuccess,
                          &kLinkKeyNotification, &kAuthenticationComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kSetConnectionEncryption, {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent}));
  test_device()->QueueCommandTransaction(CommandTransaction(kReadEncryptionKeySize, {}));

  connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kChannelParams, socket_cb);

  RETURN_IF_FATAL(RunLoopUntilIdle());

  // We should not have a socket because the L2CAP open callback shouldn't have been called, but
  // the LTK should be stored since the link key got received.
  ASSERT_FALSE(connected_socket);

  test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);

  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kAVDTP, 0x40, 0x41,
                                            kChannelParams);

  RETURN_IF_FATAL(RunLoopUntilIdle());

  // The socket should be returned.
  ASSERT_TRUE(connected_socket);

  connected_socket.reset();

  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kAVDTP, 0x40, 0x41,
                                            kChannelParams);

  // A second connection request should not require another authentication.
  connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kChannelParams, socket_cb);

  RunLoopUntilIdle();

  ASSERT_TRUE(connected_socket);

  QueueDisconnection(kConnectionHandle);
}

// Test: when the peer is already bonded, the link key gets stored when it is provided to the
// connection.
TEST_F(GAP_BrEdrConnectionManagerTest, OpenL2capEncryptsForBondedPeerThenRetries) {
  ASSERT_TRUE(
      peer_cache()->AddBondedPeer(BondingData{PeerId(999), kTestDevAddr, {}, {}, kLinkKey}));
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_FALSE(peer->connected());
  ASSERT_TRUE(peer->bonded());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  ASSERT_TRUE(peer->bredr()->connected());

  std::optional<zx::socket> connected_socket;

  auto socket_cb = [&](auto chan_sock) { connected_socket = std::move(chan_sock.socket); };

  // Initial connection request

  // Note: this skips some parts of the pairing flow, because the link key being
  // received is the important part of this. The key is not received when the
  // authentication fails.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kAuthenticationRequested, {&kAuthenticationRequestedStatus}));

  connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kChannelParams, socket_cb);

  RunLoopUntilIdle();

  // L2CAP connect shouldn't have been called, and callback shouldn't be called.
  // We should not have a socket.
  ASSERT_FALSE(connected_socket);

  // The authentication flow will request the existing link key, which should be
  // returned and stored, and then the authentication is complete.
  test_device()->QueueCommandTransaction(kLinkKeyRequestReply,
                                         {&kLinkKeyRequestReplyRsp, &kAuthenticationComplete});

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  test_device()->QueueCommandTransaction(CommandTransaction(
      kSetConnectionEncryption, {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent}));
  test_device()->QueueCommandTransaction(CommandTransaction(kReadEncryptionKeySize, {}));

  RunLoopUntilIdle();

  // No socket until the encryption verification completes.
  ASSERT_FALSE(connected_socket);

  test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);

  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kAVDTP, 0x40, 0x41,
                                            kChannelParams);

  RunLoopUntilIdle();

  // The socket should be connected.
  ASSERT_TRUE(connected_socket);

  QueueDisconnection(kConnectionHandle);
}

TEST_F(GAP_BrEdrConnectionManagerTest,
       OpenL2capAuthenticationFailureReturnsInvalidSocketAndDisconnects) {
  QueueSuccessfulIncomingConn();

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());

  std::optional<zx::socket> connected_socket;

  auto socket_cb = [&](auto chan_sock) { connected_socket = std::move(chan_sock.socket); };

  // Initial connection request

  // Note: this skips some parts of the pairing flow, because the link key being
  // received is the important part of this. The key is not received when the
  // authentication fails.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kAuthenticationRequested, {&kAuthenticationRequestedStatus}));

  connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kChannelParams, socket_cb);

  RunLoopUntilIdle();

  // The L2CAP shouldn't have been called
  // We should not have a socket, and the callback shouldn't have been called.
  ASSERT_FALSE(connected_socket);

  test_device()->SendCommandChannelPacket(kAuthenticationCompleteFailed);

  int count = transaction_count();

  // We disconnect the peer when authentication fails.
  QueueDisconnection(kConnectionHandle);

  RunLoopUntilIdle();

  // An invalid socket should have been sent because the connection failed.
  ASSERT_TRUE(connected_socket);
  ASSERT_EQ(ZX_HANDLE_INVALID, *connected_socket);

  ASSERT_EQ(count + kDisconnectionTransactions, transaction_count());
}

// Test: when pairing is in progress, opening an L2CAP channel waits for the pairing to complete
// before retrying.
TEST_F(GAP_BrEdrConnectionManagerTest, OpenL2capDuringPairingWaitsForPairingToComplete) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());

  std::optional<zx::socket> connected_socket;

  auto socket_cb = [&](auto chan_sock) { connected_socket = std::move(chan_sock.socket); };

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Approve pairing requests
  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        ASSERT_TRUE(confirm_cb);
        confirm_cb(true);
      });

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  // Initiate pairing from the peer
  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kDisplayYesNo, AuthRequirements::kMITMGeneralBonding));

  RETURN_IF_FATAL(RunLoopUntilIdle());

  // Initial connection request

  // Pair and bond as the responder. Note that Authentication Requested is not sent even though we
  // are opening the L2CAP channel because the peer started pairing first.
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  test_device()->QueueCommandTransaction(
      CommandTransaction(MakeIoCapabilityRequestReply(IOCapability::kDisplayYesNo,
                                                      AuthRequirements::kMITMGeneralBonding),
                         {&kIoCapabilityRequestReplyRsp, &kUserConfirmationRequest}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kUserConfirmationRequestReply,
      {&kUserConfirmationRequestReplyRsp, &kSimplePairingCompleteSuccess, &kLinkKeyNotification}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kSetConnectionEncryption, {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent}));
  test_device()->QueueCommandTransaction(CommandTransaction(kReadEncryptionKeySize, {}));

  connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kChannelParams, socket_cb);

  RETURN_IF_FATAL(RunLoopUntilIdle());

  // We should not have a socket because the L2CAP open callback shouldn't have been called, but
  // the LTK should be stored since the link key got received.
  ASSERT_FALSE(connected_socket);

  test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);

  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kAVDTP, 0x40, 0x41,
                                            kChannelParams);

  RETURN_IF_FATAL(RunLoopUntilIdle());

  // The socket should be returned.
  ASSERT_TRUE(connected_socket);

  QueueDisconnection(kConnectionHandle);
}

// Test: when pairing is in progress, opening an L2CAP channel waits for the pairing to complete
// before retrying.
TEST_F(GAP_BrEdrConnectionManagerTest, InterrogationInProgressAllowsBondingButNotL2cap) {
  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Trigger inbound connection and respond to some (but not all) of interrogation.
  test_device()->QueueCommandTransaction(CommandTransaction(
      kAcceptConnectionRequest, {&kAcceptConnectionRequestRsp, &kConnectionComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kRemoteNameRequest, {&kRemoteNameRequestRsp, &kRemoteNameRequestComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteVersionInfo, {&kReadRemoteVersionInfoRsp, &kRemoteVersionInfoComplete}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadRemoteSupportedFeatures, {&kReadRemoteSupportedFeaturesRsp}));

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  // Ensure that the interrogation has begun but the peer hasn't yet bonded
  EXPECT_EQ(4, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_FALSE(peer->bredr()->connected());
  ASSERT_FALSE(peer->bredr()->bonded());

  // Approve pairing requests
  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        ASSERT_TRUE(confirm_cb);
        confirm_cb(true);
      });

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  // Initiate pairing from the peer before interrogation completes
  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IOCapability::kDisplayYesNo, AuthRequirements::kMITMGeneralBonding));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  test_device()->QueueCommandTransaction(
      CommandTransaction(MakeIoCapabilityRequestReply(IOCapability::kDisplayYesNo,
                                                      AuthRequirements::kMITMGeneralBonding),
                         {&kIoCapabilityRequestReplyRsp, &kUserConfirmationRequest}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kUserConfirmationRequestReply,
      {&kUserConfirmationRequestReplyRsp, &kSimplePairingCompleteSuccess, &kLinkKeyNotification}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kSetConnectionEncryption, {&kSetConnectionEncryptionRsp, &kEncryptionChangeEvent}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadEncryptionKeySize, {&kReadEncryptionKeySizeRsp}));

  RETURN_IF_FATAL(RunLoopUntilIdle());

  // At this point the peer is bonded and the link is encrypted but interrogation has not completed
  // so host-side L2CAP should still be inactive on this link (though it may be buffering packets).
  EXPECT_FALSE(data_domain()->IsLinkConnected(kConnectionHandle));

  bool socket_cb_called = false;
  auto socket_fails_cb = [&socket_cb_called](auto chan_sock) {
    EXPECT_FALSE(chan_sock);
    socket_cb_called = true;
  };
  connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kChannelParams, socket_fails_cb);

  RETURN_IF_FATAL(RunLoopUntilIdle());
  EXPECT_TRUE(socket_cb_called);

  // Complete interrogation successfully.
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteExtended1, {&kReadRemoteExtendedFeaturesRsp, &kReadRemoteExtended1Complete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteExtended2, {&kReadRemoteExtendedFeaturesRsp, &kReadRemoteExtended1Complete}));
  test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesComplete);

  RETURN_IF_FATAL(RunLoopUntilIdle());

  EXPECT_TRUE(data_domain()->IsLinkConnected(kConnectionHandle));

  QueueDisconnection(kConnectionHandle);
}

TEST_F(GAP_BrEdrConnectionManagerTest, ConnectUnknownPeer) {
  EXPECT_FALSE(connmgr()->Connect(PeerId(456), {}));
}

TEST_F(GAP_BrEdrConnectionManagerTest, ConnectLowEnergyPeer) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddrLe, true);
  EXPECT_FALSE(connmgr()->Connect(peer->identifier(), {}));
}

TEST_F(GAP_BrEdrConnectionManagerTest, DisconnectUnknownPeerDoesNothing) {
  EXPECT_TRUE(connmgr()->Disconnect(PeerId(999)));

  RunLoopUntilIdle();

  EXPECT_EQ(0, transaction_count());
}

// Test: user-initiated disconnection
TEST_F(GAP_BrEdrConnectionManagerTest, DisconnectClosesHciConnection) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());

  QueueDisconnection(kConnectionHandle);

  EXPECT_TRUE(connmgr()->Disconnect(peer->identifier()));
  EXPECT_FALSE(peer->bredr()->connected());

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
  EXPECT_FALSE(peer->bredr()->connected());
}

TEST_F(GAP_BrEdrConnectionManagerTest, DisconnectSamePeerIsIdempotent) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());

  QueueDisconnection(kConnectionHandle);

  EXPECT_TRUE(connmgr()->Disconnect(peer->identifier()));
  EXPECT_FALSE(peer->bredr()->connected());

  // Try to disconnect again while the first disconnect is in progress (HCI
  // Disconnection Complete not yet received).
  EXPECT_TRUE(connmgr()->Disconnect(peer->identifier()));

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
  EXPECT_FALSE(peer->bredr()->connected());

  // Try to disconnect once more, now that the link is gone.
  EXPECT_TRUE(connmgr()->Disconnect(peer->identifier()));
}

TEST_F(GAP_BrEdrConnectionManagerTest, RemovePeerFromPeerCacheDuringDisconnection) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());

  QueueDisconnection(kConnectionHandle);

  const PeerId id = peer->identifier();
  EXPECT_TRUE(connmgr()->Disconnect(id));
  ASSERT_FALSE(peer->bredr()->connected());

  // Remove the peer from PeerCache before receiving HCI Disconnection Complete.
  EXPECT_TRUE(peer_cache()->RemoveDisconnectedPeer(id));

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
  EXPECT_FALSE(peer_cache()->FindById(id));
  EXPECT_FALSE(peer_cache()->FindByAddress(kTestDevAddr));
}

TEST_F(GAP_BrEdrConnectionManagerTest, AddServiceSearchAll) {
  size_t search_cb_count = 0;
  auto search_cb = [&](auto id, const auto&) {
    auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
    ASSERT_TRUE(peer);
    ASSERT_EQ(id, peer->identifier());
    search_cb_count++;
  };

  connmgr()->AddServiceSearch(sdp::profile::kAudioSink, {}, search_cb);

  fbl::RefPtr<l2cap::testing::FakeChannel> sdp_chan;
  std::optional<uint32_t> sdp_request_tid;

  data_domain()->set_channel_callback([&sdp_chan, &sdp_request_tid](auto new_chan) {
    new_chan->SetSendCallback(
        [&sdp_request_tid](auto packet) {
          const auto kSearchExpectedParams = CreateStaticByteBuffer(
              // ServiceSearchPattern
              0x35, 0x03,        // Sequence uint8 3 bytes
              0x19, 0x11, 0x0B,  // UUID (kAudioSink)
              0xFF, 0xFF,        // MaxAttributeByteCount (none)
              // Attribute ID list
              0x35, 0x05,                    // Sequence uint8 5 bytes
              0x0A, 0x00, 0x00, 0xFF, 0xFF,  // uint32_t (all attributes)
              0x00                           // No continuation state
          );
          // First byte should be type.
          ASSERT_LE(3u, packet->size());
          ASSERT_EQ(sdp::kServiceSearchAttributeRequest, (*packet)[0]);
          ASSERT_EQ(kSearchExpectedParams, packet->view(5));
          sdp_request_tid = (*packet)[1] << 8 || (*packet)[2];
        },
        async_get_default_dispatcher());
    sdp_chan = std::move(new_chan);
  });

  QueueSuccessfulIncomingConn();
  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, 0x40, 0x41,
                                            kChannelParams);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  ASSERT_TRUE(sdp_chan);
  ASSERT_TRUE(sdp_request_tid);
  ASSERT_EQ(0u, search_cb_count);

  sdp::ServiceSearchAttributeResponse rsp;
  rsp.SetAttribute(0, sdp::kServiceId, sdp::DataElement(UUID()));
  auto rsp_ptr =
      rsp.GetPDU(0xFFFF /* max attribute bytes */, *sdp_request_tid, PDU_MAX, BufferView());

  sdp_chan->Receive(*rsp_ptr);

  RunLoopUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

  QueueDisconnection(kConnectionHandle);
}

std::string FormatConnectionState(Peer::ConnectionState s) {
  switch (s) {
    case Peer::ConnectionState::kConnected:
      return "kConnected";
    case Peer::ConnectionState::kInitializing:
      return "kInitializing";
    case Peer::ConnectionState::kNotConnected:
      return "kNotConnected";
  }
  return "<Invalid state>";
}

::testing::AssertionResult IsInitializing(Peer* peer) {
  if (Peer::ConnectionState::kInitializing != peer->bredr()->connection_state()) {
    return ::testing::AssertionFailure()
           << "Expected peer connection_state: kInitializing, found "
           << FormatConnectionState(peer->bredr()->connection_state());
  }
  return ::testing::AssertionSuccess();
}
::testing::AssertionResult IsConnected(Peer* peer) {
  if (Peer::ConnectionState::kConnected != peer->bredr()->connection_state()) {
    return ::testing::AssertionFailure()
           << "Expected peer connection_state: kConnected, found "
           << FormatConnectionState(peer->bredr()->connection_state());
  }
  if (peer->temporary()) {
    return ::testing::AssertionFailure()
           << "Expected peer to be non-temporary, but found temporary";
  }
  return ::testing::AssertionSuccess();
}
::testing::AssertionResult NotConnected(Peer* peer) {
  if (Peer::ConnectionState::kNotConnected != peer->bredr()->connection_state()) {
    return ::testing::AssertionFailure()
           << "Expected peer connection_state: kNotConnected, found "
           << FormatConnectionState(peer->bredr()->connection_state());
  }
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult HasConnectionTo(Peer* peer, BrEdrConnection* conn) {
  if (!conn) {
    return ::testing::AssertionFailure() << "Expected BrEdrConnection, but found nullptr";
  }
  if (peer->identifier() != conn->peer_id()) {
    return ::testing::AssertionFailure()
           << "Expected connection peer_id " << bt_str(peer->identifier()) << " but found "
           << bt_str(conn->peer_id());
  }
  return ::testing::AssertionSuccess();
}

#define CALLBACK_EXPECT_FAILURE(status_param)       \
  ([&status_param](auto cb_status, auto conn_ref) { \
    EXPECT_FALSE(conn_ref);                         \
    status_param = cb_status;                       \
  })

// An error is received via the HCI Command cb_status event
TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSinglePeerErrorStatus) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);

  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRspError}));

  ASSERT_TRUE(peer->bredr());
  EXPECT_TRUE(NotConnected(peer));

  hci::Status status;
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), CALLBACK_EXPECT_FAILURE(status)));
  EXPECT_TRUE(IsInitializing(peer));
  RunLoopUntilIdle();

  EXPECT_TRUE(status.is_protocol_error());
  EXPECT_EQ(hci::StatusCode::kConnectionFailedToBeEstablished, status.protocol_error());
  EXPECT_TRUE(NotConnected(peer));
}

::testing::AssertionResult StatusEqual(hci::StatusCode expected, hci::StatusCode actual) {
  if (expected == actual)
    return ::testing::AssertionSuccess();
  else
    return ::testing::AssertionFailure()
           << expected << " is '" << StatusCodeToString(expected) << "', " << actual << " is '"
           << StatusCodeToString(actual) << "'";
}

// Connection Complete event reports error
TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSinglePeerFailure) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);

  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp, &kConnectionCompleteError}));

  hci::Status status(HostError::kFailed);
  bool callback_run = false;

  auto callback = [&status, &callback_run](auto cb_status, auto conn_ref) {
    EXPECT_FALSE(conn_ref);
    status = cb_status;
    callback_run = true;
  };
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  EXPECT_TRUE(IsInitializing(peer));

  RunLoopUntilIdle();

  EXPECT_TRUE(callback_run);

  EXPECT_TRUE(status.is_protocol_error());
  EXPECT_TRUE(
      StatusEqual(hci::StatusCode::kConnectionFailedToBeEstablished, status.protocol_error()));
  EXPECT_TRUE(NotConnected(peer));
}

TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSinglePeerTimeout) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);

  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kCreateConnectionCancel, {&kCreateConnectionCancelRsp, &kConnectionCompleteCanceled}));

  hci::Status status;
  auto callback = [&status](auto cb_status, auto conn_ref) {
    EXPECT_FALSE(conn_ref);
    status = cb_status;
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  EXPECT_TRUE(IsInitializing(peer));
  RunLoopFor(kBrEdrCreateConnectionTimeout);
  RunLoopFor(kBrEdrCreateConnectionTimeout);
  EXPECT_FALSE(status);
  EXPECT_EQ(HostError::kTimedOut, status.error()) << status.ToString();
  EXPECT_TRUE(NotConnected(peer));
}

// Successful connection to single peer
TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSinglePeer) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);
  EXPECT_TRUE(peer->temporary());

  // Queue up the connection
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp, &kConnectionComplete}));
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle);

  // Initialize as error to verify that |callback| assigns success.
  hci::Status status(HostError::kFailed);
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&status, &conn_ref](auto cb_status, auto cb_conn_ref) {
    EXPECT_TRUE(cb_conn_ref);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  EXPECT_TRUE(IsInitializing(peer));
  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(status.ToString(), hci::Status().ToString());
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_TRUE(IsConnected(peer));
}

TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSinglePeerFailedInterrogation) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);
  EXPECT_TRUE(peer->temporary());

  // Queue up outbound connection.
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp, &kConnectionComplete}));

  // Queue up most of interrogation.
  test_device()->QueueCommandTransaction(CommandTransaction(
      kRemoteNameRequest, {&kRemoteNameRequestRsp, &kRemoteNameRequestComplete}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kReadRemoteVersionInfo, {&kReadRemoteVersionInfoRsp, &kRemoteVersionInfoComplete}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(kReadRemoteSupportedFeatures, {&kReadRemoteSupportedFeaturesRsp}));

  hci::Status status;
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&status, &conn_ref](auto cb_status, auto cb_conn_ref) {
    EXPECT_FALSE(cb_conn_ref);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  RETURN_IF_FATAL(RunLoopUntilIdle());

  test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesCompleteFailed);
  QueueDisconnection(kConnectionHandle);
  RETURN_IF_FATAL(RunLoopUntilIdle());

  EXPECT_FALSE(status);
  EXPECT_EQ(HostError::kNotSupported, status.error()) << status.ToString();
  EXPECT_TRUE(NotConnected(peer));
}

// Connecting to an already connected peer should complete instantly
TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSinglePeerAlreadyConnected) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);
  EXPECT_TRUE(peer->temporary());

  // Queue up the connection
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp, &kConnectionComplete}));
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle);

  // Initialize as error to verify that |callback| assigns success.
  hci::Status status(HostError::kFailed);
  int num_callbacks = 0;
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&status, &conn_ref, &num_callbacks](auto cb_status, auto cb_conn_ref) {
    EXPECT_TRUE(cb_conn_ref);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
    ++num_callbacks;
  };

  // Connect to the peer for the first time
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  EXPECT_TRUE(IsInitializing(peer));
  RunLoopUntilIdle();
  EXPECT_TRUE(status);
  EXPECT_EQ(status.ToString(), hci::Status().ToString());
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_TRUE(IsConnected(peer));
  EXPECT_EQ(num_callbacks, 1);

  // Attempt to connect again to the already connected peer
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  RunLoopUntilIdle();
  EXPECT_EQ(num_callbacks, 2);
  EXPECT_TRUE(status);
  EXPECT_EQ(status.ToString(), hci::Status().ToString());
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_TRUE(IsConnected(peer));
}

// Initiating Two Connections to the same (currently unconnected) peer should
// successfully establish both
TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSinglePeerTwoInFlight) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);
  EXPECT_TRUE(peer->temporary());

  // Queue up the connection
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp, &kConnectionComplete}));
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle);

  // Initialize as error to verify that |callback| assigns success.
  hci::Status status(HostError::kFailed);
  int num_callbacks = 0;
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&status, &conn_ref, &num_callbacks](auto cb_status, auto cb_conn_ref) {
    EXPECT_TRUE(cb_conn_ref);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
    ++num_callbacks;
  };

  // Launch one request, but don't run the loop
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  EXPECT_TRUE(IsInitializing(peer));

  // Launch second inflight request
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));

  // Run the loop which should complete both requests
  RunLoopUntilIdle();

  EXPECT_TRUE(status);
  EXPECT_EQ(status.ToString(), hci::Status().ToString());
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_TRUE(IsConnected(peer));
  EXPECT_EQ(num_callbacks, 2);
}

TEST_F(GAP_BrEdrConnectionManagerTest, ConnectSecondPeerFirstTimesOut) {
  auto* peer_a = peer_cache()->NewPeer(kTestDevAddr, true);
  auto* peer_b = peer_cache()->NewPeer(kTestDevAddr2, true);

  // Enqueue first connection request (which will timeout and be cancelled)
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kCreateConnectionCancel, {&kCreateConnectionCancelRsp, &kConnectionCompleteCanceled}));

  // Enqueue second connection (which will succeed once previous has ended)
  QueueSuccessfulCreateConnection(peer_b, kConnectionHandle2);
  QueueSuccessfulInterrogation(peer_b->address(), kConnectionHandle2);
  QueueDisconnection(kConnectionHandle2);

  // Initialize as success to verify that |callback_a| assigns failure.
  hci::Status status_a;
  auto callback_a = [&status_a](auto cb_status, auto cb_conn_ref) {
    status_a = cb_status;
    EXPECT_FALSE(cb_conn_ref);
  };

  // Initialize as error to verify that |callback_b| assigns success.
  hci::Status status_b(HostError::kFailed);
  BrEdrConnection* connection = nullptr;
  auto callback_b = [&status_b, &connection](auto cb_status, auto cb_conn_ref) {
    EXPECT_TRUE(cb_conn_ref);
    status_b = cb_status;
    connection = std::move(cb_conn_ref);
  };

  // Launch one request (this will timeout)
  EXPECT_TRUE(connmgr()->Connect(peer_a->identifier(), callback_a));
  ASSERT_TRUE(peer_a->bredr());
  EXPECT_TRUE(IsInitializing(peer_a));

  RunLoopUntilIdle();

  // Launch second inflight request (this will wait for the first)
  EXPECT_TRUE(connmgr()->Connect(peer_b->identifier(), callback_b));
  ASSERT_TRUE(peer_b->bredr());

  // Run the loop which should complete both requests
  RunLoopFor(kBrEdrCreateConnectionTimeout);
  RunLoopFor(kBrEdrCreateConnectionTimeout);

  EXPECT_FALSE(status_a);
  EXPECT_TRUE(status_b);
  EXPECT_EQ(status_b.ToString(), hci::Status().ToString());
  EXPECT_TRUE(HasConnectionTo(peer_b, connection));
  EXPECT_TRUE(NotConnected(peer_a));
  EXPECT_TRUE(IsConnected(peer_b));
}

TEST_F(GAP_BrEdrConnectionManagerTest, DisconnectPendingConnections) {
  auto* peer_a = peer_cache()->NewPeer(kTestDevAddr, true);
  auto* peer_b = peer_cache()->NewPeer(kTestDevAddr2, true);

  // Enqueue first connection request (which will await Connection Complete)
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp}));
  test_device()->QueueCommandTransaction(CommandTransaction(
      kCreateConnectionCancel, {&kCreateConnectionCancelRsp, &kConnectionCompleteCanceled}));

  // No-op connection callbacks
  auto callback_a = [](auto, auto) {};
  auto callback_b = [](auto, auto) {};

  // Launch both requests (second one is queued. Neither completes.)
  EXPECT_TRUE(connmgr()->Connect(peer_a->identifier(), callback_a));
  EXPECT_TRUE(connmgr()->Connect(peer_b->identifier(), callback_b));

  // Put the first connection into flight.
  RETURN_IF_FATAL(RunLoopUntilIdle());

  ASSERT_TRUE(IsInitializing(peer_a));
  ASSERT_TRUE(IsInitializing(peer_b));

  EXPECT_FALSE(connmgr()->Disconnect(peer_a->identifier()));
  EXPECT_FALSE(connmgr()->Disconnect(peer_b->identifier()));
}

// If SDP channel creation fails, null channel should be caught and
// not be dereferenced. Search should fail to return results.
TEST_F(GAP_BrEdrConnectionManagerTest, SDPChannelCreationFailsGracefully) {
  constexpr l2cap::ChannelId kLocalCId = 0x40;
  constexpr l2cap::ChannelId kRemoteCId = 0x41;

  // Channel creation should fail.
  data_domain()->set_channel_callback([](auto new_chan) { ASSERT_FALSE(new_chan); });

  // Since SDP channel creation fails, search_cb should not be called by SDP.
  auto search_cb = [&](auto id, const auto& attributes) { FAIL(); };
  connmgr()->AddServiceSearch(sdp::profile::kAudioSink, {sdp::kServiceId}, search_cb);

  QueueSuccessfulIncomingConn();
  data_domain()->set_simulate_open_channel_failure(true);
  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, kLocalCId, kRemoteCId,
                                            kChannelParams);

  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunLoopUntilIdle();

  // Peer should still connect successfully.
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));
  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  EXPECT_TRUE(IsConnected(peer));

  test_device()->SendCommandChannelPacket(kDisconnectionComplete);
  RunLoopUntilIdle();

  EXPECT_FALSE(IsConnected(peer));
}

TEST_F(GAP_BrEdrConnectionManagerTest,
       PendingPacketsNotClearedOnDisconnectAndClearedOnDisconnectionCompleteEvent) {
  constexpr size_t kMaxNumPackets = 1;

  ASSERT_EQ(kMaxNumPackets, kBrEdrBufferInfo.max_num_packets());

  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle2));

  QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));

  QueueSuccessfulIncomingConn(kTestDevAddr2, kConnectionHandle2);
  test_device()->SendCommandChannelPacket(testing::ConnectionRequestPacket(kTestDevAddr2));

  RunLoopUntilIdle();

  auto* peer2 = peer_cache()->FindByAddress(kTestDevAddr2);
  ASSERT_TRUE(peer2);
  EXPECT_EQ(peer2->identifier(), connmgr()->GetPeerId(kConnectionHandle2));

  EXPECT_EQ(2 * kIncomingConnTransactions, transaction_count());

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

  ASSERT_TRUE(acl_data_channel()->SendPacket(
      hci::ACLDataPacket::New(kConnectionHandle, hci::ACLPacketBoundaryFlag::kFirstNonFlushable,
                              hci::ACLBroadcastFlag::kPointToPoint, 1),
      l2cap::kInvalidChannelId));

  ASSERT_TRUE(acl_data_channel()->SendPacket(
      hci::ACLDataPacket::New(kConnectionHandle2, hci::ACLPacketBoundaryFlag::kFirstNonFlushable,
                              hci::ACLBroadcastFlag::kPointToPoint, 1),
      l2cap::kInvalidChannelId));

  RunLoopUntilIdle();

  EXPECT_EQ(1u, packet_count);

  test_device()->QueueCommandTransaction(CommandTransaction(kDisconnect, {&kDisconnectRsp}));

  EXPECT_TRUE(connmgr()->Disconnect(peer->identifier()));
  RunLoopUntilIdle();

  // Packet for |kConnectionHandle2| should not have been sent before Disconnection Complete event.
  EXPECT_EQ(1u, packet_count);

  test_device()->SendCommandChannelPacket(kDisconnectionComplete);

  RunLoopUntilIdle();

  EXPECT_FALSE(IsConnected(peer));

  // Packet for |kConnectionHandle2| should have been sent.
  EXPECT_EQ(2u, packet_count);

  // Link |kConnectionHandle| should have been unregistered.
  ASSERT_FALSE(acl_data_channel()->SendPacket(
      hci::ACLDataPacket::New(kConnectionHandle, hci::ACLPacketBoundaryFlag::kFirstNonFlushable,
                              hci::ACLBroadcastFlag::kPointToPoint, 1),
      l2cap::kInvalidChannelId));

  QueueDisconnection(kConnectionHandle2);
}

TEST_F(GAP_BrEdrConnectionManagerTest, PairUnconnectedPeer) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);
  EXPECT_TRUE(peer->temporary());
  ASSERT_EQ(peer_cache()->count(), 1u);
  uint count_cb_called = 0;
  auto cb = [&count_cb_called](hci::Status status) {
    ASSERT_EQ(status.error(), bt::HostError::kNotFound);
    count_cb_called++;
  };
  connmgr()->Pair(peer->identifier(), cb);
  ASSERT_EQ(count_cb_called, 1u);
}

TEST_F(GAP_BrEdrConnectionManagerTest, Pair) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());
  ASSERT_FALSE(peer->bonded());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Approve pairing requests.
  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        ASSERT_TRUE(confirm_cb);
        confirm_cb(true);
      });

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  QueueSuccessfulPairing();

  // Make the pairing error a "bad" error to confirm the callback is called at the end of the
  // pairing process.
  auto pairing_error = HostError::kPacketMalformed;
  auto pairing_complete_cb = [&pairing_error](hci::Status status) {
    ASSERT_TRUE(status);
    pairing_error = status.error();
  };

  connmgr()->Pair(peer->identifier(), pairing_complete_cb);
  ASSERT_FALSE(peer->bonded());
  RunLoopUntilIdle();

  ASSERT_EQ(pairing_error, HostError::kNoError);
  ASSERT_TRUE(peer->bonded());

  QueueDisconnection(kConnectionHandle);
}

TEST_F(GAP_BrEdrConnectionManagerTest, PairTwice) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr()->connected());
  ASSERT_FALSE(peer->bonded());

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());

  // Approve pairing requests.
  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        ASSERT_TRUE(confirm_cb);
        confirm_cb(true);
      });

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  QueueSuccessfulPairing();

  // Make the pairing error a "bad" error to confirm the callback is called at the end of the
  // pairing process.
  auto pairing_error = HostError::kPacketMalformed;
  auto pairing_complete_cb = [&pairing_error](hci::Status status) {
    ASSERT_TRUE(status);
    pairing_error = status.error();
  };

  connmgr()->Pair(peer->identifier(), pairing_complete_cb);
  RunLoopUntilIdle();

  ASSERT_EQ(pairing_error, HostError::kNoError);
  ASSERT_TRUE(peer->bonded());

  pairing_error = HostError::kPacketMalformed;
  connmgr()->Pair(peer->identifier(), pairing_complete_cb);

  // Note that we do not call QueueSuccessfulPairing twice, even though we pair twice - this is to
  // test that pairing on an already-paired link succeeds without sending any messages to the peer.
  RunLoopUntilIdle();
  ASSERT_EQ(pairing_error, HostError::kNoError);
  ASSERT_TRUE(peer->bonded());

  QueueDisconnection(kConnectionHandle);
}

TEST_F(GAP_BrEdrConnectionManagerTest, OpenL2capChannelCreatesChannelWithChannelParameters) {
  constexpr l2cap::PSM kPSM = l2cap::kAVDTP;
  constexpr l2cap::ChannelId kLocalId = l2cap::kFirstDynamicChannelId;
  l2cap::ChannelParameters params;
  params.mode = l2cap::ChannelMode::kEnhancedRetransmission;
  params.max_rx_sdu_size = l2cap::kMinACLMTU;

  QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunLoopUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));

  FakePairingDelegate pairing_delegate(sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate.GetWeakPtr());
  // Approve pairing requests.
  pairing_delegate.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) { confirm_cb(true); });
  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Status status) { EXPECT_TRUE(status.is_success()); });

  QueueSuccessfulPairing();
  RunLoopUntilIdle();

  data_domain()->ExpectOutboundL2capChannel(kConnectionHandle, kPSM, kLocalId, 0x41, params);

  std::optional<l2cap::ChannelInfo> chan_info;
  size_t sock_cb_count = 0;
  auto sock_cb = [&](auto chan_sock) {
    sock_cb_count++;
    EXPECT_TRUE(chan_sock);
    chan_info = chan_sock.params;
  };
  connmgr()->OpenL2capChannel(peer->identifier(), kPSM, params, sock_cb);

  RunLoopUntilIdle();
  EXPECT_EQ(1u, sock_cb_count);
  ASSERT_TRUE(chan_info);
  EXPECT_EQ(*params.mode, chan_info->mode);
  EXPECT_EQ(*params.max_rx_sdu_size, chan_info->max_rx_sdu_size);

  QueueDisconnection(kConnectionHandle);
}

// Tests that the connection manager cleans up its connection map correctly following a
// disconnection due to encryption failure.
TEST_F(GAP_BrEdrConnectionManagerTest, ConnectionCleanUpFollowingEncryptionFailure) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);
  EXPECT_TRUE(peer->temporary());

  // Queue up the connection
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp, &kConnectionComplete}));
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle, hci::StatusCode::kAuthenticationFailure);

  // Initialize as error to verify that |callback| assigns success.
  hci::Status status(HostError::kFailed);
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&status, &conn_ref](auto cb_status, auto cb_conn_ref) {
    EXPECT_TRUE(cb_conn_ref);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  RunLoopUntilIdle();
  ASSERT_TRUE(status);

  test_device()->SendCommandChannelPacket(
      testing::EncryptionChangeEventPacket(hci::StatusCode::kConnectionTerminatedMICFailure,
                                           kConnectionHandle, hci::EncryptionStatus::kOff));
  test_device()->SendCommandChannelPacket(testing::DisconnectionCompletePacket(
      kConnectionHandle, hci::StatusCode::kConnectionTerminatedMICFailure));
  RunLoopUntilIdle();

  EXPECT_TRUE(NotConnected(peer));
}

// Tests for assertions that enforce invariants.
class GAP_BrEdrConnectionManagerDeathTest : public BrEdrConnectionManagerTest {};

// Tests that a disconnection event that occurs after a peer gets removed is handled gracefully.
TEST_F(GAP_BrEdrConnectionManagerDeathTest, DisconnectAfterPeerRemovalAsserts) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);
  EXPECT_TRUE(peer->temporary());

  // Queue up the connection
  test_device()->QueueCommandTransaction(
      CommandTransaction(kCreateConnection, {&kCreateConnectionRsp, &kConnectionComplete}));
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle);

  // Initialize as error to verify that |callback| assigns success.
  hci::Status status(HostError::kFailed);
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&status, &conn_ref](auto cb_status, auto cb_conn_ref) {
    EXPECT_TRUE(cb_conn_ref);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  RunLoopUntilIdle();
  ASSERT_TRUE(status);

  EXPECT_DEATH_IF_SUPPORTED(
      {
        // Remove the peer without removing it from the cache. Normally this is not recommended as
        // implied by the name of the function but it is possible for this invariant to be broken
        // due to programmer error. The connection manager should assert this invariant.
        peer->MutBrEdr().SetConnectionState(Peer::ConnectionState::kNotConnected);
        __UNUSED auto _ = peer_cache()->RemoveDisconnectedPeer(peer->identifier());

        test_device()->SendCommandChannelPacket(kDisconnectionComplete);
        RunLoopUntilIdle();
      },
      ".*");
}

// TODO(BT-819) Connecting a peer that's being interrogated

#undef COMMAND_COMPLETE_RSP
#undef COMMAND_STATUS_RSP

}  // namespace
}  // namespace gap
}  // namespace bt
