// 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/public/pw_bluetooth_sapphire/internal/host/gap/bredr_connection_manager.h"

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/error.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/gap/fake_pairing_delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/gap/peer_cache.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci-spec/util.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/l2cap/fake_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/l2cap/fake_l2cap.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/sdp/sdp.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/fake_peer.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/inspect.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/mock_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_packets.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/transport/error.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/transport/fake_acl_connection.h"
#include "src/connectivity/bluetooth/lib/cpp-string/string_printf.h"

namespace bt::gap {
namespace {

using namespace inspect::testing;

using bt::testing::CommandTransaction;
using pw::bluetooth::emboss::AuthenticationRequirements;
using pw::bluetooth::emboss::IoCapability;

using TestingBase =
    bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;

constexpr hci_spec::ConnectionHandle kConnectionHandle = 0x0BAA;
constexpr hci_spec::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_spec::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_spec::LinkKeyType::kAuthenticatedCombination192),
    kRawKey);

constexpr BrEdrSecurityRequirements kNoSecurityRequirements{
    .authentication = false, .secure_connections = false};
constexpr BrEdrSecurityRequirements kAuthSecurityRequirements{
    .authentication = true, .secure_connections = false};

// 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

const StaticByteBuffer kReadScanEnable(LowerBits(hci_spec::kReadScanEnable),
                                       UpperBits(hci_spec::kReadScanEnable),
                                       0x00  // No parameters
);

#define READ_SCAN_ENABLE_RSP(scan_enable)                      \
  StaticByteBuffer(hci_spec::kCommandCompleteEventCode,        \
                   0x05,                                       \
                   0xF0,                                       \
                   LowerBits(hci_spec::kReadScanEnable),       \
                   UpperBits(hci_spec::kReadScanEnable),       \
                   pw::bluetooth::emboss::StatusCode::SUCCESS, \
                   (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)                \
  StaticByteBuffer(LowerBits(hci_spec::kWriteScanEnable), \
                   UpperBits(hci_spec::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)                    \
  StaticByteBuffer(hci_spec::kCommandCompleteEventCode, \
                   0x04,                                \
                   0xF0,                                \
                   LowerBits((opcode)),                 \
                   UpperBits((opcode)),                 \
                   pw::bluetooth::emboss::StatusCode::SUCCESS)

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

const StaticByteBuffer kWritePageScanActivity(
    LowerBits(hci_spec::kWritePageScanActivity),
    UpperBits(hci_spec::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_spec::kWritePageScanActivity);

const StaticByteBuffer kWritePageScanType(
    LowerBits(hci_spec::kWritePageScanType),
    UpperBits(hci_spec::kWritePageScanType),
    0x01,  // parameter_total_size (1 byte)
    0x01   // Interlaced scan
);

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

#define COMMAND_STATUS_RSP(opcode, statuscode)        \
  StaticByteBuffer(hci_spec::kCommandStatusEventCode, \
                   0x04,                              \
                   (statuscode),                      \
                   0xF0,                              \
                   LowerBits((opcode)),               \
                   UpperBits((opcode)))

const auto kWritePageTimeoutRsp =
    COMMAND_COMPLETE_RSP(hci_spec::kWritePageTimeout);

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

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

const auto kAcceptConnectionRequestRsp =
    COMMAND_STATUS_RSP(hci_spec::kAcceptConnectionRequest,
                       pw::bluetooth::emboss::StatusCode::SUCCESS);

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

const auto kConnectionCompletePageTimeout = testing::ConnectionCompletePacket(
    kTestDevAddr,
    kConnectionHandle,
    pw::bluetooth::emboss::StatusCode::PAGE_TIMEOUT);

const StaticByteBuffer kConnectionCompleteError(
    hci_spec::kConnectionCompleteEventCode,
    0x0B,  // parameter_total_size (11 byte payload)
    pw::bluetooth::emboss::StatusCode::
        CONNECTION_FAILED_TO_BE_ESTABLISHED,  // status
    0x00,
    0x00,                    // connection_handle
    TEST_DEV_ADDR_BYTES_LE,  // peer address
    0x01,                    // link_type (ACL)
    0x00                     // encryption not enabled
);

const StaticByteBuffer kConnectionCompleteCanceled(
    hci_spec::kConnectionCompleteEventCode,
    0x0B,  // parameter_total_size (11 byte payload)
    pw::bluetooth::emboss::StatusCode::UNKNOWN_CONNECTION_ID,  // status
    0x00,
    0x00,                    // connection_handle
    TEST_DEV_ADDR_BYTES_LE,  // peer address
    0x01,                    // link_type (ACL)
    0x00                     // encryption not enabled
);

const StaticByteBuffer kCreateConnection(
    LowerBits(hci_spec::kCreateConnection),
    UpperBits(hci_spec::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_spec::kCreateConnection, pw::bluetooth::emboss::StatusCode::SUCCESS);

const auto kCreateConnectionRspError = COMMAND_STATUS_RSP(
    hci_spec::kCreateConnection,
    pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);

const StaticByteBuffer kCreateConnectionCancel(
    LowerBits(hci_spec::kCreateConnectionCancel),
    UpperBits(hci_spec::kCreateConnectionCancel),
    0x06,                   // parameter_total_size (6 bytes)
    TEST_DEV_ADDR_BYTES_LE  // peer address
);

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

const StaticByteBuffer kRemoteNameRequest(
    LowerBits(hci_spec::kRemoteNameRequest),
    UpperBits(hci_spec::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_spec::kRemoteNameRequest, pw::bluetooth::emboss::StatusCode::SUCCESS);

const auto kRemoteNameRequestComplete =
    testing::RemoteNameRequestCompletePacket(
        kTestDevAddr,
        {'F',    'u',    'c',    'h',    's',    'i',    'a',    '\xF0', '\x9F',
         '\x92', '\x96', '\x00', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19',
         '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', '\x20'}
        // remote name (Fuchsia💖)
        // Everything after the 0x00 should be ignored.
    );
const StaticByteBuffer kReadRemoteVersionInfo(
    LowerBits(hci_spec::kReadRemoteVersionInfo),
    UpperBits(hci_spec::kReadRemoteVersionInfo),
    0x02,  // Parameter_total_size (2 bytes)
    0xAA,
    0x0B  // connection_handle
);

const auto kReadRemoteVersionInfoRsp =
    COMMAND_STATUS_RSP(hci_spec::kReadRemoteVersionInfo,
                       pw::bluetooth::emboss::StatusCode::SUCCESS);

const auto kRemoteVersionInfoComplete = StaticByteBuffer(
    hci_spec::kReadRemoteVersionInfoCompleteEventCode,
    0x08,  // parameter_total_size (8 bytes)
    pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
    0xAA,
    0x0B,                                                   // connection_handle
    pw::bluetooth::emboss::CoreSpecificationVersion::V4_2,  // version
    0xE0,
    0x00,  // company_identifier (Google)
    0xAD,
    0xDE  // subversion (anything)
);

const auto kReadRemoteSupportedFeaturesRsp =
    COMMAND_STATUS_RSP(hci_spec::kReadRemoteSupportedFeatures,
                       pw::bluetooth::emboss::StatusCode::SUCCESS);

const auto kReadRemoteSupportedFeaturesComplete =
    StaticByteBuffer(hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode,
                     0x0B,  // parameter_total_size (11 bytes)
                     pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
                     0xAA,
                     0x0B,  // connection_handle,
                     0xFF,
                     0x00,
                     0x00,
                     0x00,
                     0x40,
                     0x00,
                     0x00,
                     0x80
                     // lmp_features_page0: 3 slot packets, 5 slot packets,
                     // Encryption, Slot Offset, Timing Accuracy, Role Switch,
                     // Hold Mode, Sniff Mode, LE Supported, Extended Features
    );

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

const auto kReadRemoteExtendedFeaturesRsp =
    COMMAND_STATUS_RSP(hci_spec::kReadRemoteExtendedFeatures,
                       pw::bluetooth::emboss::StatusCode::SUCCESS);

const auto kReadRemoteExtended1Complete = StaticByteBuffer(
    hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode,
    0x0D,  // parameter_total_size (13 bytes)
    pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
    0xAA,
    0x0B,  // connection_handle,
    0x01,  // page_number
    0x02,  // max_page_number
    0x0F,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00
    // lmp_features_page1: Secure Simple Pairing (Host Support), LE Supported
    // (Host), Previously Used, Secure Connections (Host Support)
);

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

const auto kReadRemoteExtended2Complete =
    StaticByteBuffer(hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode,
                     0x0D,  // parameter_total_size (13 bytes)
                     pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
                     0xAA,
                     0x0B,  // connection_handle,
                     0x02,  // page_number
                     0x02,  // max_page_number
                     0x00,
                     0x00,
                     0x00,
                     0x00,
                     0x02,
                     0x00,
                     0xFF,
                     0x00
                     // lmp_features_page2  - All the bits should be ignored.
    );

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

const auto kDisconnectRsp = COMMAND_STATUS_RSP(
    hci_spec::kDisconnect, pw::bluetooth::emboss::StatusCode::SUCCESS);

const auto kDisconnectionComplete = testing::DisconnectionCompletePacket(
    kConnectionHandle,
    pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);

const auto kAuthenticationRequested =
    testing::AuthenticationRequestedPacket(kConnectionHandle);

const auto kAuthenticationRequestedStatus =
    COMMAND_STATUS_RSP(hci_spec::kAuthenticationRequested,
                       pw::bluetooth::emboss::StatusCode::SUCCESS);

const auto kAuthenticationComplete =
    StaticByteBuffer(hci_spec::kAuthenticationCompleteEventCode,
                     0x03,  // parameter_total_size (3 bytes)
                     pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
                     0xAA,
                     0x0B  // connection_handle
    );

const auto kAuthenticationCompleteFailed = StaticByteBuffer(
    hci_spec::kAuthenticationCompleteEventCode,
    0x03,  // parameter_total_size (3 bytes)
    pw::bluetooth::emboss::StatusCode::PAIRING_NOT_ALLOWED,  // status
    0xAA,
    0x0B  // connection_handle
);

const StaticByteBuffer kLinkKeyRequest(hci_spec::kLinkKeyRequestEventCode,
                                       0x06,  // parameter_total_size (6 bytes)
                                       TEST_DEV_ADDR_BYTES_LE  // peer address
);

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

const auto kLinkKeyRequestNegativeReplyRsp =
    StaticByteBuffer(hci_spec::kCommandCompleteEventCode,
                     0x0A,
                     0xF0,
                     LowerBits(hci_spec::kLinkKeyRequestNegativeReply),
                     UpperBits(hci_spec::kLinkKeyRequestNegativeReply),
                     pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
                     TEST_DEV_ADDR_BYTES_LE  // peer address
    );

auto MakeIoCapabilityResponse(IoCapability io_cap,
                              AuthenticationRequirements auth_req) {
  return StaticByteBuffer(hci_spec::kIOCapabilityResponseEventCode,
                          0x09,  // parameter_total_size (9 bytes)
                          TEST_DEV_ADDR_BYTES_LE,  // address
                          io_cap,
                          0x00,  // OOB authentication data not present
                          auth_req);
}

const StaticByteBuffer kIoCapabilityRequest(
    hci_spec::kIOCapabilityRequestEventCode,
    0x06,                   // parameter_total_size (6 bytes)
    TEST_DEV_ADDR_BYTES_LE  // address
);

auto MakeIoCapabilityRequestReply(IoCapability io_cap,
                                  AuthenticationRequirements auth_req) {
  return StaticByteBuffer(LowerBits(hci_spec::kIOCapabilityRequestReply),
                          UpperBits(hci_spec::kIOCapabilityRequestReply),
                          0x09,  // parameter_total_size (9 bytes)
                          TEST_DEV_ADDR_BYTES_LE,  // peer address
                          io_cap,
                          0x00,  // No OOB data present
                          auth_req);
}

const StaticByteBuffer kIoCapabilityRequestReplyRsp(
    hci_spec::kCommandCompleteEventCode,
    0x0A,
    0xF0,
    LowerBits(hci_spec::kIOCapabilityRequestReply),
    UpperBits(hci_spec::kIOCapabilityRequestReply),
    pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
    TEST_DEV_ADDR_BYTES_LE                       // peer address
);

const auto kIoCapabilityRequestNegativeReply =
    StaticByteBuffer(LowerBits(hci_spec::kIOCapabilityRequestNegativeReply),
                     UpperBits(hci_spec::kIOCapabilityRequestNegativeReply),
                     0x07,                    // parameter_total_size (7 bytes)
                     TEST_DEV_ADDR_BYTES_LE,  // peer address
                     pw::bluetooth::emboss::StatusCode::PAIRING_NOT_ALLOWED);

const auto kIoCapabilityRequestNegativeReplyRsp =
    StaticByteBuffer(hci_spec::kCommandCompleteEventCode,
                     0x0A,
                     0xF0,
                     LowerBits(hci_spec::kIOCapabilityRequestNegativeReply),
                     UpperBits(hci_spec::kIOCapabilityRequestNegativeReply),
                     pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
                     TEST_DEV_ADDR_BYTES_LE);  // peer address

auto MakeUserConfirmationRequest(uint32_t passkey) {
  const auto passkey_bytes = ToBytes(kPasskey);
  return StaticByteBuffer(hci_spec::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 =
    StaticByteBuffer(LowerBits(hci_spec::kUserConfirmationRequestReply),
                     UpperBits(hci_spec::kUserConfirmationRequestReply),
                     0x06,                   // parameter_total_size (6 bytes)
                     TEST_DEV_ADDR_BYTES_LE  // peer address
    );

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

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

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

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

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

DynamicByteBuffer MakeLinkKeyNotification(hci_spec::LinkKeyType key_type) {
  return DynamicByteBuffer(StaticByteBuffer(
      hci_spec::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
      static_cast<uint8_t>(key_type)  // key type
      ));
}

const auto kLinkKeyNotification = MakeLinkKeyNotification(
    hci_spec::LinkKeyType::kAuthenticatedCombination192);

const StaticByteBuffer kLinkKeyRequestReply(
    LowerBits(hci_spec::kLinkKeyRequestReply),
    UpperBits(hci_spec::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 StaticByteBuffer kLinkKeyRequestReplyRsp(
    hci_spec::kCommandCompleteEventCode,
    0x0A,
    0xF0,
    LowerBits(hci_spec::kLinkKeyRequestReply),
    UpperBits(hci_spec::kLinkKeyRequestReply),
    pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
    TEST_DEV_ADDR_BYTES_LE                       // peer address
);

const auto kLinkKeyNotificationChanged =
    StaticByteBuffer(hci_spec::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 StaticByteBuffer kSetConnectionEncryption(
    LowerBits(hci_spec::kSetConnectionEncryption),
    UpperBits(hci_spec::kSetConnectionEncryption),
    0x03,  // parameter total size
    0xAA,
    0x0B,  // connection handle
    0x01   // encryption enable
);

const auto kSetConnectionEncryptionRsp =
    COMMAND_STATUS_RSP(hci_spec::kSetConnectionEncryption,
                       pw::bluetooth::emboss::StatusCode::SUCCESS);

const StaticByteBuffer kEncryptionChangeEvent(
    hci_spec::kEncryptionChangeEventCode,
    4,     // parameter total size
    0x00,  // status
    0xAA,
    0x0B,  // connection handle
    0x01   // encryption enabled: E0 for BR/EDR or AES-CCM for LE
);

const StaticByteBuffer kReadEncryptionKeySize(
    LowerBits(hci_spec::kReadEncryptionKeySize),
    UpperBits(hci_spec::kReadEncryptionKeySize),
    0x02,  // parameter size
    0xAA,
    0x0B  // connection handle
);

const StaticByteBuffer kReadEncryptionKeySizeRsp(
    hci_spec::kCommandCompleteEventCode,
    0x07,  // parameters total size
    0xFF,  // num command packets allowed (255)
    LowerBits(hci_spec::kReadEncryptionKeySize),
    UpperBits(hci_spec::kReadEncryptionKeySize),
    pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
    0xAA,
    0x0B,  // connection handle
    0x10   // encryption key size: 16
);

auto MakeUserPasskeyRequestReply(uint32_t passkey) {
  const auto passkey_bytes = ToBytes(kPasskey);
  return StaticByteBuffer(LowerBits(hci_spec::kUserPasskeyRequestReply),
                          UpperBits(hci_spec::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 StaticByteBuffer kUserPasskeyRequestReplyRsp(
    hci_spec::kCommandCompleteEventCode,
    0x0A,
    0xF0,
    LowerBits(hci_spec::kUserPasskeyRequestReply),
    UpperBits(hci_spec::kUserPasskeyRequestReply),
    pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
    TEST_DEV_ADDR_BYTES_LE                       // peer address
);

auto MakeUserPasskeyNotification(uint32_t passkey) {
  const auto passkey_bytes = ToBytes(kPasskey);
  return StaticByteBuffer(hci_spec::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;

::testing::AssertionResult IsInitializing(Peer* peer) {
  if (Peer::ConnectionState::kInitializing !=
      peer->bredr()->connection_state()) {
    return ::testing::AssertionFailure()
           << "Expected peer connection_state: kInitializing, found "
           << Peer::ConnectionStateToString(peer->bredr()->connection_state());
  }
  return ::testing::AssertionSuccess()
         << "Peer connection state is kInitializing";
}
::testing::AssertionResult IsConnected(Peer* peer) {
  if (Peer::ConnectionState::kConnected != peer->bredr()->connection_state()) {
    return ::testing::AssertionFailure()
           << "Expected peer to be in a connected state: kConnected, found "
           << Peer::ConnectionStateToString(peer->bredr()->connection_state());
  }
  if (peer->temporary()) {
    return ::testing::AssertionFailure()
           << "Expected peer to be non-temporary, but found temporary";
  }
  return ::testing::AssertionSuccess() << "Peer connection state is kConnected";
}
::testing::AssertionResult IsNotConnected(Peer* peer) {
  if (Peer::ConnectionState::kNotConnected !=
      peer->bredr()->connection_state()) {
    return ::testing::AssertionFailure()
           << "Expected peer connection_state: kNotConnected, found "
           << Peer::ConnectionStateToString(peer->bredr()->connection_state());
  }
  return ::testing::AssertionSuccess()
         << "Peer connection state is kNotConnected";
  ;
}

::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 " << peer->identifier()
           << " but found " << conn->peer_id();
  }
  return ::testing::AssertionSuccess() << "Peer " << peer->identifier()
                                       << " connected to the connection given";
}

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

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

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

    peer_cache_ = std::make_unique<PeerCache>(dispatcher());
    l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(dispatcher());

    // Respond to BrEdrConnectionManager controller setup with success.
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::WritePageTimeoutPacket(static_cast<uint16_t>(
                              pw::bluetooth::emboss::PageTimeout::DEFAULT)),
                          &kWritePageTimeoutRsp);

    connection_manager_ = std::make_unique<BrEdrConnectionManager>(
        transport()->GetWeakPtr(),
        peer_cache_.get(),
        kLocalDevAddr,
        l2cap_.get(),
        /*use_interlaced_scan=*/true,
        /*local_secure_connections_supported=*/true,
        dispatcher());

    RunUntilIdle();

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

  void TearDown() override {
    int expected_transaction_count = transaction_count();
    if (connection_manager_ != nullptr) {
      expected_transaction_count += 2;
      // deallocating the connection manager disables connectivity.
      EXPECT_CMD_PACKET_OUT(
          test_device(), kReadScanEnable, &kReadScanEnableRspBoth);
      EXPECT_CMD_PACKET_OUT(
          test_device(), kWriteScanEnableInq, &kWriteScanEnableRsp);
      connection_manager_ = nullptr;
    }
    RunUntilIdle();
    // A disconnection may also occur for a queued disconnection, allow up to 1
    // extra transaction.
    EXPECT_LE(expected_transaction_count, transaction_count());
    EXPECT_GE(expected_transaction_count + 1, transaction_count());
    // Don't trigger the transaction callback for the rest.
    test_device()->ClearTransactionCallback();
    test_device()->Stop();
    l2cap_ = nullptr;
    peer_cache_ = nullptr;
    TestingBase::TearDown();
  }

  inspect::Inspector inspector() { return inspector_; }

 protected:
  static constexpr const int kShortInterrogationTransactions = 3;
  static constexpr const int kInterrogationTransactions =
      kShortInterrogationTransactions + 2;
  static constexpr const int kIncomingConnTransactions =
      1 + kInterrogationTransactions;
  static constexpr const int kDisconnectionTransactions = 1;
  // Currently unused, for reference:
  // static constexpr const int kIncomingConnShortTransactions = 1 +
  // kShortInterrogationTransactions;

  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(); }

  l2cap::testing::FakeL2cap* l2cap() const { return l2cap_.get(); }

  int transaction_count() const { return transaction_count_; }

  // Expect an incoming connection that is accepted.
  void QueueSuccessfulAccept(
      DeviceAddress addr = kTestDevAddr,
      hci_spec::ConnectionHandle handle = kConnectionHandle,
      std::optional<pw::bluetooth::emboss::ConnectionRole> role_change =
          std::nullopt) const {
    const auto connection_complete =
        testing::ConnectionCompletePacket(addr, handle);
    if (role_change) {
      const auto role_change_event =
          testing::RoleChangePacket(addr, role_change.value());
      EXPECT_CMD_PACKET_OUT(test_device(),
                            testing::AcceptConnectionRequestPacket(addr),
                            &kAcceptConnectionRequestRsp,
                            &role_change_event,
                            &connection_complete);
    } else {
      EXPECT_CMD_PACKET_OUT(test_device(),
                            testing::AcceptConnectionRequestPacket(addr),
                            &kAcceptConnectionRequestRsp,
                            &connection_complete);
    }
  }

  // Add expectations and simulated responses for the outbound commands sent
  // after an inbound Connection Request Event is received, for a peer that is
  // already interrogated. Results in kIncomingConnShortTransactions
  // transaction.
  void QueueRepeatIncomingConn(
      DeviceAddress addr = kTestDevAddr,
      hci_spec::ConnectionHandle handle = kConnectionHandle,
      std::optional<pw::bluetooth::emboss::ConnectionRole> role_change =
          std::nullopt) const {
    QueueSuccessfulAccept(addr, handle, role_change);
    QueueShortInterrogation(handle);
  }

  // Add expectations and simulated responses for the outbound commands sent
  // after an inbound Connection Request Event is received, for a peer that is
  // already interrogated.
  //  Results in |kIncomingConnTransactions| transactions.
  void QueueSuccessfulIncomingConn(
      DeviceAddress addr = kTestDevAddr,
      hci_spec::ConnectionHandle handle = kConnectionHandle,
      std::optional<pw::bluetooth::emboss::ConnectionRole> role_change =
          std::nullopt) const {
    QueueSuccessfulAccept(addr, handle, role_change);
    QueueSuccessfulInterrogation(addr, handle);
  }

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

  void QueueShortInterrogation(hci_spec::ConnectionHandle conn) const {
    const DynamicByteBuffer remote_extended1_complete_packet =
        testing::ReadRemoteExtended1CompletePacket(conn);
    const DynamicByteBuffer remote_extended2_complete_packet =
        testing::ReadRemoteExtended2CompletePacket(conn);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteExtended1Packet(conn),
                          &kReadRemoteExtendedFeaturesRsp,
                          &remote_extended1_complete_packet);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteExtended2Packet(conn),
                          &kReadRemoteExtendedFeaturesRsp,
                          &remote_extended2_complete_packet);
  }

  void QueueSuccessfulInterrogation(DeviceAddress addr,
                                    hci_spec::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, /*extended_features=*/true);

    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::RemoteNameRequestPacket(addr),
                          &kRemoteNameRequestRsp,
                          &remote_name_complete_packet);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteVersionInfoPacket(conn),
                          &kReadRemoteVersionInfoRsp,
                          &remote_version_complete_packet);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteSupportedFeaturesPacket(conn),
                          &kReadRemoteSupportedFeaturesRsp,
                          &remote_supported_complete_packet);
    QueueShortInterrogation(conn);
  }

  // Queue all interrogation packets except for the remote extended complete
  // packet 2.
  void QueueIncompleteInterrogation(DeviceAddress addr,
                                    hci_spec::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, /*extended_features=*/true);
    const DynamicByteBuffer remote_extended1_complete_packet =
        testing::ReadRemoteExtended1CompletePacket(conn);

    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::RemoteNameRequestPacket(addr),
                          &kRemoteNameRequestRsp,
                          &remote_name_complete_packet);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteVersionInfoPacket(conn),
                          &kReadRemoteVersionInfoRsp,
                          &remote_version_complete_packet);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteSupportedFeaturesPacket(conn),
                          &kReadRemoteSupportedFeaturesRsp,
                          &remote_supported_complete_packet);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteExtended1Packet(conn),
                          &kReadRemoteExtendedFeaturesRsp,
                          &remote_extended1_complete_packet);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::ReadRemoteExtended2Packet(conn),
                          &kReadRemoteExtendedFeaturesRsp);
  }

  // Completes an interrogation started with QueueIncompleteInterrogation.
  void CompleteInterrogation(hci_spec::ConnectionHandle conn) {
    const DynamicByteBuffer remote_extended2_complete_packet =
        testing::ReadRemoteExtended2CompletePacket(conn);

    test_device()->SendCommandChannelPacket(remote_extended2_complete_packet);
  }

  void QueueSuccessfulPairing(
      hci_spec::LinkKeyType key_type =
          hci_spec::LinkKeyType::kAuthenticatedCombination192) {
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kAuthenticationRequested,
                          &kAuthenticationRequestedStatus,
                          &kLinkKeyRequest);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kLinkKeyRequestNegativeReply,
                          &kLinkKeyRequestNegativeReplyRsp,
                          &kIoCapabilityRequest);
    const auto kIoCapabilityResponse = MakeIoCapabilityResponse(
        IoCapability::DISPLAY_YES_NO,
        AuthenticationRequirements::MITM_GENERAL_BONDING);
    const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          MakeIoCapabilityRequestReply(
                              IoCapability::DISPLAY_YES_NO,
                              AuthenticationRequirements::MITM_GENERAL_BONDING),
                          &kIoCapabilityRequestReplyRsp,
                          &kIoCapabilityResponse,
                          &kUserConfirmationRequest);
    const auto kLinkKeyNotificationWithKeyType =
        MakeLinkKeyNotification(key_type);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kUserConfirmationRequestReply,
                          &kUserConfirmationRequestReplyRsp,
                          &kSimplePairingCompleteSuccess,
                          &kLinkKeyNotificationWithKeyType,
                          &kAuthenticationComplete);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kSetConnectionEncryption,
                          &kSetConnectionEncryptionRsp,
                          &kEncryptionChangeEvent);
    EXPECT_CMD_PACKET_OUT(
        test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);
  }

  // Use when pairing with no IO, where authenticated pairing is not possible.
  void QueueSuccessfulUnauthenticatedPairing(
      hci_spec::LinkKeyType key_type =
          hci_spec::LinkKeyType::kUnauthenticatedCombination192) {
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kAuthenticationRequested,
                          &kAuthenticationRequestedStatus,
                          &kLinkKeyRequest);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kLinkKeyRequestNegativeReply,
                          &kLinkKeyRequestNegativeReplyRsp,
                          &kIoCapabilityRequest);
    const auto kIoCapabilityReply = MakeIoCapabilityRequestReply(
        IoCapability::NO_INPUT_NO_OUTPUT,
        AuthenticationRequirements::GENERAL_BONDING);
    const auto kIoCapabilityResponse =
        MakeIoCapabilityResponse(IoCapability::NO_INPUT_NO_OUTPUT,
                                 AuthenticationRequirements::GENERAL_BONDING);
    const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kIoCapabilityReply,
                          &kIoCapabilityRequestReplyRsp,
                          &kIoCapabilityResponse,
                          &kUserConfirmationRequest);
    const auto kLinkKeyNotificationWithKeyType =
        MakeLinkKeyNotification(key_type);
    // User Confirmation Request Reply will be automatic due to no IO.
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kUserConfirmationRequestReply,
                          &kUserConfirmationRequestReplyRsp,
                          &kSimplePairingCompleteSuccess,
                          &kLinkKeyNotificationWithKeyType,
                          &kAuthenticationComplete);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          kSetConnectionEncryption,
                          &kSetConnectionEncryptionRsp,
                          &kEncryptionChangeEvent);
    EXPECT_CMD_PACKET_OUT(
        test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);
  }

  void QueueDisconnection(
      hci_spec::ConnectionHandle conn,
      pw::bluetooth::emboss::StatusCode reason =
          pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION)
      const {
    const DynamicByteBuffer disconnect_complete =
        testing::DisconnectionCompletePacket(conn, reason);
    EXPECT_CMD_PACKET_OUT(test_device(),
                          testing::DisconnectPacket(conn, reason),
                          &kDisconnectRsp,
                          &disconnect_complete);
  }

 private:
  std::unique_ptr<BrEdrConnectionManager> connection_manager_;
  std::unique_ptr<PeerCache> peer_cache_;
  std::unique_ptr<l2cap::testing::FakeL2cap> l2cap_;
  int transaction_count_ = 0;

  inspect::Inspector inspector_;

  BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BrEdrConnectionManagerTest);
};

using GAP_BrEdrConnectionManagerTest = BrEdrConnectionManagerTest;

TEST_F(BrEdrConnectionManagerTest, DisableConnectivity) {
  size_t cb_count = 0;
  auto cb = [&cb_count](const auto& status) {
    cb_count++;
    EXPECT_EQ(fit::ok(), status);
  };

  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadScanEnable, &kReadScanEnableRspPage);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kWriteScanEnableNone, &kWriteScanEnableRsp);

  connmgr()->SetConnectable(/*connectable=*/false, cb);

  RunUntilIdle();

  EXPECT_EQ(1u, cb_count);

  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadScanEnable, &kReadScanEnableRspBoth);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kWriteScanEnableInq, &kWriteScanEnableRsp);

  connmgr()->SetConnectable(/*connectable=*/false, cb);

  RunUntilIdle();

  EXPECT_EQ(2u, cb_count);
}

TEST_F(BrEdrConnectionManagerTest, EnableConnectivity) {
  size_t cb_count = 0;
  auto cb = [&cb_count](const auto& status) {
    cb_count++;
    EXPECT_EQ(fit::ok(), status);
  };

  EXPECT_CMD_PACKET_OUT(
      test_device(), kWritePageScanActivity, &kWritePageScanActivityRsp);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kWritePageScanType, &kWritePageScanTypeRsp);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadScanEnable, &kReadScanEnableRspNone);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kWriteScanEnablePage, &kWriteScanEnableRsp);

  connmgr()->SetConnectable(/*connectable=*/true, cb);

  RunUntilIdle();

  EXPECT_EQ(1u, cb_count);

  EXPECT_CMD_PACKET_OUT(
      test_device(), kWritePageScanActivity, &kWritePageScanActivityRsp);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kWritePageScanType, &kWritePageScanTypeRsp);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadScanEnable, &kReadScanEnableRspInquiry);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kWriteScanEnableBoth, &kWriteScanEnableRsp);

  connmgr()->SetConnectable(/*connectable=*/true, cb);

  RunUntilIdle();

  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(BrEdrConnectionManagerTest,
       IncomingConnection_BrokenExtendedPageResponse) {
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAcceptConnectionRequest,
                        &kAcceptConnectionRequestRsp,
                        &kConnectionComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kRemoteNameRequest,
                        &kRemoteNameRequestRsp,
                        &kRemoteNameRequestComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteVersionInfo,
                        &kReadRemoteVersionInfoRsp,
                        &kRemoteVersionInfoComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        hci_spec::kReadRemoteSupportedFeatures,
                        &kReadRemoteSupportedFeaturesRsp,
                        &kReadRemoteSupportedFeaturesComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended1,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended2,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(6, transaction_count());

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

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

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));
  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  // Confirm remote name request during interrogation sets proper name source.
  EXPECT_EQ(peer->name_source(), Peer::NameSource::kNameDiscoveryProcedure);

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

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

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  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(BrEdrConnectionManagerTest, RemoteDisconnect) {
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));
  QueueSuccessfulIncomingConn();

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

  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);

  RunUntilIdle();

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

const auto kRemoteNameRequestCompleteFailed =
    StaticByteBuffer(hci_spec::kRemoteNameRequestCompleteEventCode,
                     0x01,  // parameter_total_size (1 bytes)
                     pw::bluetooth::emboss::StatusCode::HARDWARE_FAILURE);

const auto kReadRemoteSupportedFeaturesCompleteFailed =
    StaticByteBuffer(hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode,
                     0x01,  // parameter_total_size (1 bytes)
                     pw::bluetooth::emboss::StatusCode::HARDWARE_FAILURE);

// 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(BrEdrConnectionManagerTest, IncomingConnectionFailedInterrogation) {
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAcceptConnectionRequest,
                        &kAcceptConnectionRequestRsp,
                        &kConnectionComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kRemoteNameRequest,
                        &kRemoteNameRequestRsp,
                        &kRemoteNameRequestCompleteFailed);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteVersionInfo,
                        &kReadRemoteVersionInfoRsp,
                        &kRemoteVersionInfoComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        hci_spec::kReadRemoteSupportedFeatures,
                        &kReadRemoteSupportedFeaturesRsp,
                        &kReadRemoteSupportedFeaturesCompleteFailed);

  EXPECT_CMD_PACKET_OUT(
      test_device(), kDisconnect, &kDisconnectRsp, &kDisconnectionComplete);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(5, transaction_count());
}

// Test: replies negative to IO Capability Requests before PairingDelegate is
// set
TEST_F(BrEdrConnectionManagerTest,
       IoCapabilityRequestNegativeReplyWithNoPairingDelegate) {
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kIoCapabilityRequestNegativeReply,
                        &kIoCapabilityRequestNegativeReplyRsp);

  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  RunUntilIdle();

  EXPECT_EQ(1, transaction_count());
}

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kIoCapabilityRequestNegativeReply,
                        &kIoCapabilityRequestNegativeReplyRsp);

  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  RunUntilIdle();

  EXPECT_EQ(1, transaction_count());
}

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

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  ASSERT_EQ(kIncomingConnTransactions, transaction_count());

  EXPECT_CMD_PACKET_OUT(
      test_device(),
      MakeIoCapabilityRequestReply(IoCapability::NO_INPUT_NO_OUTPUT,
                                   AuthenticationRequirements::GENERAL_BONDING),
      &kIoCapabilityRequestReplyRsp);

  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_ONLY,
      AuthenticationRequirements::MITM_GENERAL_BONDING));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  QueueDisconnection(kConnectionHandle);
}

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp);

  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_ONLY, AuthenticationRequirements::GENERAL_BONDING));
  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);
      });

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestNegativeReply,
                        &kUserConfirmationRequestNegativeReplyRsp);
  test_device()->SendCommandChannelPacket(
      MakeUserConfirmationRequest(kPasskey));

  pairing_delegate.SetCompletePairingCallback([](PeerId, sm::Result<> status) {
    EXPECT_EQ(ToResult(HostError::kFailed), status);
  });

  test_device()->SendCommandChannelPacket(kSimplePairingCompleteError);

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

  RunUntilIdle();
}

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

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

const auto kUserPasskeyRequestNegativeReplyRsp =
    StaticByteBuffer(hci_spec::kCommandCompleteEventCode,
                     0x0A,
                     0xF0,
                     LowerBits(hci_spec::kUserPasskeyRequestNegativeReply),
                     UpperBits(hci_spec::kUserPasskeyRequestNegativeReply),
                     pw::bluetooth::emboss::StatusCode::SUCCESS,  // 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(BrEdrConnectionManagerTest,
       RespondToPasskeyEntryPairingAfterUserProvidesInvalidPasskey) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::KEYBOARD_ONLY,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp);

  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_ONLY, AuthenticationRequirements::GENERAL_BONDING));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserPasskeyRequestNegativeReply,
                        &kUserPasskeyRequestNegativeReplyRsp);
  test_device()->SendCommandChannelPacket(kUserPasskeyRequest);

  pairing_delegate.SetCompletePairingCallback([](PeerId, sm::Result<> status) {
    EXPECT_EQ(ToResult(HostError::kFailed), status);
  });

  test_device()->SendCommandChannelPacket(kSimplePairingCompleteError);

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

  RunUntilIdle();
}

// Test: replies negative to Link Key Requests for unknown and unbonded peers
TEST_F(BrEdrConnectionManagerTest, LinkKeyRequestAndNegativeReply) {
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kLinkKeyRequestNegativeReply,
                        &kLinkKeyRequestNegativeReplyRsp);

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunUntilIdle();

  EXPECT_EQ(1, transaction_count());

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kLinkKeyRequestNegativeReply,
                        &kLinkKeyRequestNegativeReplyRsp);

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 2, transaction_count());

  // Queue disconnection for teardown
  QueueDisconnection(kConnectionHandle);
}

// Test: replies to Link Key Requests for bonded peer
TEST_F(BrEdrConnectionManagerTest, RecallLinkKeyForBondedPeer) {
  ASSERT_TRUE(
      peer_cache()->AddBondedPeer(BondingData{.identifier = PeerId(999),
                                              .address = kTestDevAddr,
                                              .name = std::nullopt,
                                              .le_pairing_data = {},
                                              .bredr_link_key = kLinkKey,
                                              .bredr_services = {}}));
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsNotConnected(peer));
  ASSERT_TRUE(peer->bonded());

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  ASSERT_TRUE(IsInitializing(peer));

  EXPECT_CMD_PACKET_OUT(
      test_device(), kLinkKeyRequestReply, &kLinkKeyRequestReplyRsp);

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunUntilIdle();
  /// Peer is still initializing until the Pairing is complete
  /// (OnPairingComplete)
  ASSERT_TRUE(IsInitializing(peer));

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());

  // Queue disconnection for teardown.
  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(BrEdrConnectionManagerTest,
       EncryptAfterPasskeyEntryPairingAndUserProvidesAcceptedPasskey) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::KEYBOARD_ONLY,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp);

  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_ONLY, AuthenticationRequirements::GENERAL_BONDING));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeUserPasskeyRequestReply(kPasskey),
                        &kUserPasskeyRequestReplyRsp);
  test_device()->SendCommandChannelPacket(kUserPasskeyRequest);

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);

  RETURN_IF_FATAL(RunUntilIdle());
  ASSERT_TRUE(IsConnected(peer));
  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(BrEdrConnectionManagerTest, EncryptAfterPasskeyDisplayPairing) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_ONLY,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp);

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IoCapability::KEYBOARD_ONLY,
                               AuthenticationRequirements::GENERAL_BONDING));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  RETURN_IF_FATAL(RunUntilIdle());
  ASSERT_TRUE(IsInitializing(peer));

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);

  RETURN_IF_FATAL(RunUntilIdle());
  ASSERT_TRUE(IsConnected(peer));
  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(BrEdrConnectionManagerTest,
       EncryptAndBondAfterNumericComparisonPairingAndUserConfirms) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp);

  test_device()->SendCommandChannelPacket(
      MakeIoCapabilityResponse(IoCapability::DISPLAY_YES_NO,
                               AuthenticationRequirements::GENERAL_BONDING));
  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);
      });

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestReply,
                        &kUserConfirmationRequestReplyRsp);
  test_device()->SendCommandChannelPacket(
      MakeUserConfirmationRequest(kPasskey));

  pairing_delegate.SetCompletePairingCallback(
      [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  RETURN_IF_FATAL(RunUntilIdle());
  ASSERT_TRUE(IsInitializing(peer));

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);

  RETURN_IF_FATAL(RunUntilIdle());
  ASSERT_TRUE(IsConnected(peer));
  EXPECT_TRUE(peer->bonded());

  EXPECT_CMD_PACKET_OUT(
      test_device(), kLinkKeyRequestReply, &kLinkKeyRequestReplyRsp);
  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunUntilIdle();

  QueueDisconnection(kConnectionHandle);
}

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

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

  RunUntilIdle();
  ASSERT_FALSE(IsConnected(peer));
  EXPECT_FALSE(peer->bonded());

  EXPECT_CMD_PACKET_OUT(
      test_device(), kLinkKeyRequestNegativeReply, &kLinkKeyRequestReplyRsp);

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunUntilIdle();

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

  QueueDisconnection(kConnectionHandle);
}

const auto kLinkKeyNotificationLegacy =
    StaticByteBuffer(hci_spec::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 or mark successfully connected if the link key resulted from
// legacy pairing
TEST_F(BrEdrConnectionManagerTest, LegacyLinkKeyNotBonded) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

  test_device()->SendCommandChannelPacket(kLinkKeyNotificationLegacy);

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

  EXPECT_CMD_PACKET_OUT(
      test_device(), kLinkKeyRequestNegativeReply, &kLinkKeyRequestReplyRsp);

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  RunUntilIdle();

  ASSERT_FALSE(IsConnected(peer));
  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(BrEdrConnectionManagerTest, DisconnectOnLinkError) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

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

  l2cap()->TriggerLinkError(kConnectionHandle);

  RunUntilIdle();

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

TEST_F(BrEdrConnectionManagerTest, InitializingPeerDoesNotTimeout) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());

  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_FALSE(IsNotConnected(peer));
  EXPECT_FALSE(peer->bonded());

  // We want to make sure the connection doesn't expire just because they didn't
  // pair.
  RunFor(std::chrono::seconds(600));

  auto* peer_still = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer_still);
  ASSERT_EQ(peer->identifier(), peer_still->identifier());

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

  RunUntilIdle();

  // Peer should still be there, but not connected anymore, until they time out.
  peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_TRUE(IsNotConnected(peer));
  EXPECT_FALSE(peer->bonded());
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));
}

inline uint16_t tid_from_sdp_packet(const ByteBufferPtr& packet) {
  return (*packet)[1] << CHAR_BIT | (*packet)[2];
}

TEST_F(BrEdrConnectionManagerTest,
       PeerServicesAddedBySearchAndRetainedIfNotSearchedFor) {
  constexpr UUID kServiceUuid1 = sdp::profile::kAudioSink;
  auto* const peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  peer->MutBrEdr().AddService(kServiceUuid1);

  // Search for different service.
  constexpr UUID kServiceUuid2 = sdp::profile::kAudioSource;
  size_t search_cb_count = 0;
  connmgr()->AddServiceSearch(kServiceUuid2,
                              {sdp::kServiceId},
                              [&](auto, auto&) { search_cb_count++; });

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

  l2cap()->set_channel_callback(
      [this, &sdp_chan, &sdp_request_tid](auto new_chan) {
        new_chan->SetSendCallback(
            [&sdp_request_tid](auto packet) {
              sdp_request_tid = tid_from_sdp_packet(packet);
            },
            dispatcher());
        sdp_chan = std::move(new_chan);
      });

  // No searches in this connection.
  QueueSuccessfulIncomingConn();
  l2cap()->ExpectOutboundL2capChannel(
      kConnectionHandle, l2cap::kSDP, 0x40, 0x41, kChannelParams);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  ASSERT_TRUE(sdp_chan.is_alive());
  ASSERT_EQ(0u, search_cb_count);

  // Positive response to search.
  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);

  RunUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

  // Prior connections' services retained and newly discovered service added.
  EXPECT_EQ(1u, peer->bredr()->services().count(kServiceUuid1));
  EXPECT_EQ(1u, peer->bredr()->services().count(kServiceUuid2));

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest,
       PeerServiceNotErasedByEmptyResultsForSearchOfSameService) {
  constexpr UUID kServiceUuid = sdp::profile::kAudioSink;
  auto* const peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  peer->MutBrEdr().AddService(kServiceUuid);

  size_t search_cb_count = 0;
  connmgr()->AddServiceSearch(
      kServiceUuid, {sdp::kServiceId}, [&](auto, auto&) { search_cb_count++; });

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

  l2cap()->set_channel_callback(
      [this, &sdp_chan, &sdp_request_tid](auto new_chan) {
        new_chan->SetSendCallback(
            [&sdp_request_tid](auto packet) {
              sdp_request_tid = tid_from_sdp_packet(packet);
            },
            dispatcher());
        sdp_chan = std::move(new_chan);
      });

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  ASSERT_TRUE(sdp_chan.is_alive());
  ASSERT_EQ(0u, search_cb_count);

  sdp::ServiceSearchAttributeResponse empty_rsp;
  auto rsp_ptr = empty_rsp.GetPDU(0xFFFF /* max attribute bytes */,
                                  *sdp_request_tid,
                                  PDU_MAX,
                                  BufferView());

  sdp_chan->Receive(*rsp_ptr);

  RunUntilIdle();

  // Search callback isn't called by empty attribute list from peer.
  ASSERT_EQ(0u, search_cb_count);

  EXPECT_EQ(1u, peer->bredr()->services().count(kServiceUuid));

  QueueDisconnection(kConnectionHandle);
}

l2cap::testing::FakeChannel::SendCallback MakeAudioSinkSearchExpected(
    std::optional<uint16_t>* tid) {
  return [tid](auto packet) {
    const StaticByteBuffer kSearchExpectedParams(
        // 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(sizeof(bt::sdp::Header)));
    if (tid != nullptr) {
    }
    *tid = tid_from_sdp_packet(packet);
  };
}

TEST_F(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);

  l2cap::testing::FakeChannel::WeakPtr sdp_chan;
  std::optional<uint16_t> sdp_request_tid;

  l2cap()->set_channel_callback(
      [&sdp_chan, &sdp_request_tid, this](auto new_chan) {
        new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid),
                                  dispatcher());
        sdp_chan = std::move(new_chan);
      });

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  ASSERT_TRUE(sdp_chan.is_alive());
  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);

  RunUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

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

  RunUntilIdle();

  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
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAcceptConnectionRequest,
                        &kAcceptConnectionRequestRsp,
                        &kConnectionComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended1,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended2,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended2Complete);

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

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

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest, SearchAfterConnected) {
  // We have no services registered, so this will not start a SDP search.
  QueueSuccessfulIncomingConn();
  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  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++;
  };

  l2cap::testing::FakeChannel::WeakPtr sdp_chan;
  std::optional<uint16_t> sdp_request_tid;

  l2cap()->set_channel_callback(
      [&sdp_chan, &sdp_request_tid, this](auto new_chan) {
        new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid),
                                  dispatcher());
        sdp_chan = std::move(new_chan);
      });

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

  // When this gets added, the service search will immediately be done on the
  // already-connected peer.
  auto search_id = connmgr()->AddServiceSearch(
      sdp::profile::kAudioSink, {sdp::kServiceId}, search_cb);

  ASSERT_NE(sdp::ServiceDiscoverer::kInvalidSearchId, search_id);

  RunUntilIdle();

  ASSERT_TRUE(sdp_chan.is_alive());
  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);

  RunUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

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

  RunUntilIdle();

  sdp_request_tid.reset();
  sdp_chan.reset();

  // Second connection is shortened because we have already interrogated,
  // we repeat the search for SDP services.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAcceptConnectionRequest,
                        &kAcceptConnectionRequestRsp,
                        &kConnectionComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended1,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended2,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended2Complete);

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

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

  ASSERT_TRUE(sdp_chan.is_alive());
  ASSERT_TRUE(sdp_request_tid);
  ASSERT_EQ(1u, search_cb_count);

  // Reusing the (empty) answer from before
  rsp_ptr = rsp.GetPDU(0xFFFF /* max attribute bytes */,
                       *sdp_request_tid,
                       PDU_MAX,
                       BufferView());

  sdp_chan->Receive(*rsp_ptr);

  // We should have another search callback.
  ASSERT_EQ(2u, search_cb_count);

  QueueDisconnection(kConnectionHandle);
}

TEST_F(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);

  l2cap::testing::FakeChannel::WeakPtr sdp_chan;
  std::optional<uint16_t> sdp_request_tid;

  l2cap()->set_channel_callback(
      [&sdp_chan, &sdp_request_tid, this](auto new_chan) {
        new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid),
                                  dispatcher());
        sdp_chan = std::move(new_chan);
      });

  // This test uses a modified peer and interrogation which doesn't use extended
  // pages.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        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,
          /*extended_features=*/false);

  EXPECT_CMD_PACKET_OUT(test_device(),
                        testing::RemoteNameRequestPacket(kTestDevAddr),
                        &kRemoteNameRequestRsp,
                        &remote_name_complete_packet);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        testing::ReadRemoteVersionInfoPacket(kConnectionHandle),
                        &kReadRemoteVersionInfoRsp,
                        &remote_version_complete_packet);
  EXPECT_CMD_PACKET_OUT(
      test_device(),
      testing::ReadRemoteSupportedFeaturesPacket(kConnectionHandle),
      &kReadRemoteSupportedFeaturesRsp,
      &remote_supported_complete_packet);

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  ASSERT_TRUE(sdp_chan.is_alive());
  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);

  RunUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

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

  RunUntilIdle();

  sdp_request_tid.reset();
  sdp_chan.reset();

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

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

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

  // We should have searched again.
  ASSERT_TRUE(sdp_chan.is_alive());
  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);

  RunUntilIdle();

  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(BrEdrConnectionManagerTest, OpenL2capPairsAndEncryptsThenRetries) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  std::optional<l2cap::Channel::WeakPtr> connected_chan;

  auto chan_cb = [&](auto chan) { connected_chan = std::move(chan); };

  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  // Initial connection request

  // Pairing initiation and flow that results in bonding then encryption, but
  // verifying the strength of the encryption key doesn't complete
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAuthenticationRequested,
                        &kAuthenticationRequestedStatus,
                        &kLinkKeyRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kLinkKeyRequestNegativeReply,
                        &kLinkKeyRequestNegativeReplyRsp,
                        &kIoCapabilityRequest);
  const auto kIoCapabilityResponse = MakeIoCapabilityResponse(
      IoCapability::DISPLAY_YES_NO,
      AuthenticationRequirements::MITM_GENERAL_BONDING);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp,
                        &kIoCapabilityResponse,
                        &kUserConfirmationRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestReply,
                        &kUserConfirmationRequestReplyRsp,
                        &kSimplePairingCompleteSuccess,
                        &kLinkKeyNotification,
                        &kAuthenticationComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, );

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

  RETURN_IF_FATAL(RunUntilIdle());

  // We should not have a channel 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_chan);
  // We should be initializing, since we have not completed pairing.
  ASSERT_TRUE(IsInitializing(peer));

  test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);

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

  RETURN_IF_FATAL(RunUntilIdle());
  // We should signal to PeerCache as connected once we finish pairing.
  ASSERT_TRUE(IsConnected(peer));

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

  connected_chan.reset();

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

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

  RunUntilIdle();

  ASSERT_TRUE(connected_chan);

  QueueDisconnection(kConnectionHandle);
}

// Test: when the peer is already bonded, the link key gets stored when it is
// provided to the connection.
TEST_F(BrEdrConnectionManagerTest, OpenL2capEncryptsForBondedPeerThenRetries) {
  ASSERT_TRUE(
      peer_cache()->AddBondedPeer(BondingData{.identifier = PeerId(999),
                                              .address = kTestDevAddr,
                                              .name = std::nullopt,
                                              .le_pairing_data = {},
                                              .bredr_link_key = kLinkKey,
                                              .bredr_services = {}}));
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsNotConnected(peer));
  ASSERT_TRUE(peer->bonded());

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

  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  ASSERT_FALSE(IsNotConnected(peer));

  std::optional<l2cap::Channel::WeakPtr> connected_chan;

  auto socket_cb = [&](auto chan) { connected_chan = std::move(chan); };

  // 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.
  EXPECT_CMD_PACKET_OUT(
      test_device(), kAuthenticationRequested, &kAuthenticationRequestedStatus);

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

  RunUntilIdle();

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

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

  test_device()->SendCommandChannelPacket(kLinkKeyRequest);

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, );

  RunUntilIdle();

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

  test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);

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

  RunUntilIdle();

  // Once the L2CAP channel has connected, we have connected.
  ASSERT_TRUE(IsConnected(peer));

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

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest,
       OpenL2capAuthenticationFailureReturnsInvalidSocketAndDisconnects) {
  QueueSuccessfulIncomingConn();

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  std::optional<l2cap::Channel::WeakPtr> connected_chan;

  auto socket_cb = [&](auto chan) { connected_chan = std::move(chan); };

  // 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.
  EXPECT_CMD_PACKET_OUT(
      test_device(), kAuthenticationRequested, &kAuthenticationRequestedStatus);

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

  RunUntilIdle();

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

  test_device()->SendCommandChannelPacket(kAuthenticationCompleteFailed);

  int count = transaction_count();

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

  RunUntilIdle();

  // An invalid channel should have been sent because the connection failed.
  ASSERT_TRUE(connected_chan);
  ASSERT_FALSE(connected_chan.value().is_alive());

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

TEST_F(BrEdrConnectionManagerTest, OpenL2capPairingFinishesButDisconnects) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  // Initial connection request

  // Pairing initiation and flow that results in bonding then encryption, but
  // verifying the strength of the encryption key doesn't complete
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAuthenticationRequested,
                        &kAuthenticationRequestedStatus,
                        &kLinkKeyRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kLinkKeyRequestNegativeReply,
                        &kLinkKeyRequestNegativeReplyRsp,
                        &kIoCapabilityRequest);
  const auto kIoCapabilityResponse = MakeIoCapabilityResponse(
      IoCapability::DISPLAY_YES_NO,
      AuthenticationRequirements::MITM_GENERAL_BONDING);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp,
                        &kIoCapabilityResponse,
                        &kUserConfirmationRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestReply,
                        &kUserConfirmationRequestReplyRsp,
                        &kSimplePairingCompleteSuccess,
                        &kLinkKeyNotification,
                        &kAuthenticationComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, );

  std::optional<l2cap::Channel::WeakPtr> connected_chan;

  auto chan_cb = [&](auto chan) { connected_chan = std::move(chan); };
  connmgr()->OpenL2capChannel(peer->identifier(),
                              l2cap::kAVDTP,
                              kNoSecurityRequirements,
                              kChannelParams,
                              chan_cb);

  RETURN_IF_FATAL(RunUntilIdle());

  // We should not have a channel 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_chan);

  // The remote device disconnects now, when the pairing has been started, then
  // pairing completes.
  test_device()->SendCommandChannelPacket(kDisconnectionComplete);
  test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);
  RunUntilIdle();

  // We should get a callback from the OpenL2capChannel
  ASSERT_TRUE(connected_chan);
  EXPECT_FALSE(connected_chan.value().is_alive());

  connected_chan.reset();

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

  // The L2CAP should be called right away without a channel.
  ASSERT_TRUE(connected_chan);
  EXPECT_FALSE(connected_chan.value().is_alive());

  connected_chan.reset();
}

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  std::optional<l2cap::Channel::WeakPtr> connected_chan;

  auto socket_cb = [&](auto chan) { connected_chan = std::move(chan); };

  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  // Initiate pairing from the peer
  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_YES_NO,
      AuthenticationRequirements::MITM_GENERAL_BONDING));

  RETURN_IF_FATAL(RunUntilIdle());

  // 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);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp,
                        &kUserConfirmationRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestReply,
                        &kUserConfirmationRequestReplyRsp,
                        &kSimplePairingCompleteSuccess,
                        &kLinkKeyNotification);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, );

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

  RETURN_IF_FATAL(RunUntilIdle());

  // 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_chan);

  test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);

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

  RETURN_IF_FATAL(RunUntilIdle());

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

  QueueDisconnection(kConnectionHandle);
}

// Test: when pairing is in progress, opening an L2CAP channel waits for the
// pairing to complete before retrying.
TEST_F(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.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAcceptConnectionRequest,
                        &kAcceptConnectionRequestRsp,
                        &kConnectionComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kRemoteNameRequest,
                        &kRemoteNameRequestRsp,
                        &kRemoteNameRequestComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteVersionInfo,
                        &kReadRemoteVersionInfoRsp,
                        &kRemoteVersionInfoComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        hci_spec::kReadRemoteSupportedFeatures,
                        &kReadRemoteSupportedFeaturesRsp);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  // 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_TRUE(IsInitializing(peer));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  // Initiate pairing from the peer before interrogation completes
  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_YES_NO,
      AuthenticationRequirements::MITM_GENERAL_BONDING));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp,
                        &kUserConfirmationRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestReply,
                        &kUserConfirmationRequestReplyRsp,
                        &kSimplePairingCompleteSuccess,
                        &kLinkKeyNotification);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);

  RETURN_IF_FATAL(RunUntilIdle());

  // 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(l2cap()->IsLinkConnected(kConnectionHandle));

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

  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_TRUE(socket_cb_called);

  // Complete interrogation successfully.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended1,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended2,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);
  test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesComplete);

  RETURN_IF_FATAL(RunUntilIdle());

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

  QueueDisconnection(kConnectionHandle);
}

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

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

TEST_F(BrEdrConnectionManagerTest, DisconnectUnknownPeerDoesNothing) {
  EXPECT_TRUE(
      connmgr()->Disconnect(PeerId(999), DisconnectReason::kApiRequest));

  RunUntilIdle();

  EXPECT_EQ(0, transaction_count());
}

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  QueueDisconnection(kConnectionHandle);

  EXPECT_TRUE(
      connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
  EXPECT_TRUE(IsNotConnected(peer));

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
  EXPECT_TRUE(IsNotConnected(peer));
}

TEST_F(BrEdrConnectionManagerTest, DisconnectSamePeerIsIdempotent) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_FALSE(IsNotConnected(peer));

  QueueDisconnection(kConnectionHandle);

  EXPECT_TRUE(
      connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
  ASSERT_TRUE(IsNotConnected(peer));

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

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
  ASSERT_TRUE(IsNotConnected(peer));

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

TEST_F(BrEdrConnectionManagerTest, RemovePeerFromPeerCacheDuringDisconnection) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_FALSE(IsNotConnected(peer));

  QueueDisconnection(kConnectionHandle);

  const PeerId id = peer->identifier();
  EXPECT_TRUE(connmgr()->Disconnect(id, DisconnectReason::kApiRequest));
  ASSERT_TRUE(IsNotConnected(peer));

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

  RunUntilIdle();

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

TEST_F(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);

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

  l2cap()->set_channel_callback(
      [this, &sdp_chan, &sdp_request_tid](auto new_chan) {
        new_chan->SetSendCallback(
            [&sdp_request_tid](auto packet) {
              const StaticByteBuffer kSearchExpectedParams(
                  // 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(sizeof(bt::sdp::Header)));
              sdp_request_tid = tid_from_sdp_packet(packet);
            },
            dispatcher());
        sdp_chan = std::move(new_chan);
      });

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

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  ASSERT_TRUE(sdp_chan.is_alive());
  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);

  RunUntilIdle();

  ASSERT_EQ(1u, search_cb_count);

  QueueDisconnection(kConnectionHandle);
}

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

  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRspError);

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

  hci::Result<> status = fit::ok();
  EXPECT_TRUE(
      connmgr()->Connect(peer->identifier(), CALLBACK_EXPECT_FAILURE(status)));
  EXPECT_TRUE(IsInitializing(peer));
  RunUntilIdle();

  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::
                         CONNECTION_FAILED_TO_BE_ESTABLISHED),
            status);
  EXPECT_TRUE(IsNotConnected(peer));
}

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

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kCreateConnection,
                        &kCreateConnectionRsp,
                        &kConnectionCompleteError);

  hci::Result<> status = ToResult(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));

  RunUntilIdle();

  EXPECT_TRUE(callback_run);

  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::
                         CONNECTION_FAILED_TO_BE_ESTABLISHED),
            status);
  EXPECT_TRUE(IsNotConnected(peer));
}

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

  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kCreateConnectionCancel,
                        &kCreateConnectionCancelRsp,
                        &kConnectionCompleteCanceled);

  hci::Result<> status = fit::ok();
  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));
  RunFor(kBrEdrCreateConnectionTimeout);
  RunFor(kBrEdrCreateConnectionTimeout);
  EXPECT_EQ(ToResult(HostError::kTimedOut), status);
  EXPECT_TRUE(IsNotConnected(peer));
}

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

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

  // Initialize as error to verify that |callback| assigns success.
  hci::Result<> status = ToResult(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));
  RunUntilIdle();
  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_FALSE(IsNotConnected(peer));
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::CENTRAL);
}

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

  // Queue up outbound connection.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kCreateConnection,
                        &kCreateConnectionRsp,
                        &kConnectionComplete);

  // Queue up most of interrogation.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kRemoteNameRequest,
                        &kRemoteNameRequestRsp,
                        &kRemoteNameRequestComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteVersionInfo,
                        &kReadRemoteVersionInfoRsp,
                        &kRemoteVersionInfoComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        hci_spec::kReadRemoteSupportedFeatures,
                        &kReadRemoteSupportedFeaturesRsp);

  hci::Result<> status = fit::ok();
  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(RunUntilIdle());

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

  EXPECT_EQ(ToResult(HostError::kNotSupported), status);
  EXPECT_TRUE(IsNotConnected(peer));
}

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

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

  // Initialize as error to verify that |callback| assigns success.
  hci::Result<> status = ToResult(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));
  RunUntilIdle();
  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_FALSE(IsNotConnected(peer));
  EXPECT_EQ(num_callbacks, 1);

  // Attempt to connect again to the already connected peer. callback should be
  // called synchronously.
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  EXPECT_EQ(num_callbacks, 2);
  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_FALSE(IsNotConnected(peer));
}

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

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

  // Initialize as error to verify that |callback| assigns success.
  hci::Result<> status = ToResult(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
  RunUntilIdle();

  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_FALSE(IsNotConnected(peer));
  EXPECT_EQ(num_callbacks, 2);
}

TEST_F(BrEdrConnectionManagerTest,
       ConnectInterrogatingPeerOnlyCompletesAfterInterrogation) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  EXPECT_CMD_PACKET_OUT(test_device(),
                        kCreateConnection,
                        &kCreateConnectionRsp,
                        &kConnectionComplete);
  // Prevent interrogation from completing so that we can queue a second request
  // during interrogation.
  QueueIncompleteInterrogation(kTestDevAddr, kConnectionHandle);
  QueueDisconnection(kConnectionHandle);

  // Initialize as error to verify that |callback| assigns success.
  hci::Result<> status = ToResult(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;
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  EXPECT_TRUE(IsInitializing(peer));
  RunUntilIdle();

  // Launch second request, which should not complete immediately.
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  EXPECT_EQ(num_callbacks, 0);

  // Finishing interrogation should complete both requests.
  CompleteInterrogation(kConnectionHandle);
  RunUntilIdle();

  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_FALSE(IsNotConnected(peer));
  EXPECT_EQ(num_callbacks, 2);
}

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

  // Enqueue first connection request (which will timeout and be cancelled)
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        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::Result<> status_a = fit::ok();
  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::Result<> status_b = ToResult(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));

  RunUntilIdle();

  // 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
  RunFor(kBrEdrCreateConnectionTimeout);
  RunFor(kBrEdrCreateConnectionTimeout);

  EXPECT_TRUE(status_a.is_error());
  EXPECT_EQ(fit::ok(), status_b);
  EXPECT_TRUE(HasConnectionTo(peer_b, connection));
  EXPECT_TRUE(IsNotConnected(peer_a));
  EXPECT_FALSE(IsNotConnected(peer_b));
}

class FirstLowEnergyOnlyPeer : public BrEdrConnectionManagerTest,
                               public ::testing::WithParamInterface<bool> {};

TEST_P(FirstLowEnergyOnlyPeer, ConnectToDualModePeerThatWasFirstLowEnergyOnly) {
  const DeviceAddress kTestDevAddrLeAlias(DeviceAddress::Type::kLEPublic,
                                          kTestDevAddr.value());
  auto* peer =
      peer_cache()->NewPeer(kTestDevAddrLeAlias, /*connectable=*/GetParam());
  EXPECT_TRUE(peer->temporary());
  EXPECT_EQ(TechnologyType::kLowEnergy, peer->technology());

  // Make peer dual mode
  peer->MutBrEdr();
  EXPECT_EQ(TechnologyType::kDualMode, peer->technology());

  // Queue up the connection
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);

  // Initialize as error to verify that |callback| assigns success.
  hci::Result<> status = ToResult(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));
  RunUntilIdle();

  test_device()->SendCommandChannelPacket(kConnectionComplete);
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle);
  RunUntilIdle();

  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_FALSE(IsNotConnected(peer));
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::CENTRAL);
}

INSTANTIATE_TEST_SUITE_P(BrEdrConnectionManagerTest,
                         FirstLowEnergyOnlyPeer,
                         ::testing::Values(true, false));

// Tests the successful retry case. "don't retry for other error codes" is
// implicitly tested in ConnectSinglePeerFailure - MockController would error if
// we unexpectedly retried.
TEST_F(BrEdrConnectionManagerTest, SuccessfulHciRetriesAfterPageTimeout) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  // We send a first HCI Create Connection which will hang for 14s, and then
  // respond on the test device with a ConnectionCompletePageTimeout event,
  // which will cause a retry. The retry will also hang for 14s, then will
  // receive another PageTimeout response, which will cause another retry, which
  // will finally be permitted to succeed
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kCreateConnection,
                        &kCreateConnectionRsp,
                        &kConnectionComplete);
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle);

  // Initialize as error to verify that |callback| assigns success.
  hci::Result<> status = ToResult(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());
  // Cause the initial Create Connection to wait for 14s for Connection Complete
  RunFor(std::chrono::seconds(14));
  ASSERT_TRUE(
      test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));
  // Verify higher layers have not been notified of failure.
  EXPECT_EQ(ToResult(HostError::kFailed), status);
  // Cause the first retry Create Connection to wait for 14s for Connection
  // Complete - now 28s since the first Create Connection, bumping up on the
  // retry window limit of 30s.
  RunFor(std::chrono::seconds(14));
  // Cause a second retry.
  ASSERT_TRUE(
      test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));
  // Verify higher layers have not been notified of failure until the Connection
  // Complete propagates
  EXPECT_EQ(ToResult(HostError::kFailed), status);

  RunUntilIdle();
  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::CENTRAL);
}

TEST_F(BrEdrConnectionManagerTest, DontRetryAfterWindowClosed) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  // We send a first HCI Create Connection which will hang for 15s, and then
  // respond on the test device with a ConnectionCompletePageTimeout event,
  // which will cause a retry. The retry will hang for 16s, then will receive
  // another PageTimeout response. Because this will be 31s after the initial
  // HCI Create Connection, the retry window will be closed and the Connect()
  // will fail.
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);

  // Initialize as success to verify that |callback| assigns error.
  hci::Result<> status = fit::ok();
  auto callback = [&status](auto cb_status, auto cb_conn_ref) {
    EXPECT_FALSE(cb_conn_ref);
    status = cb_status;
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(peer->bredr());
  RunFor(std::chrono::seconds(15));
  // Higher layers should not be notified yet.
  EXPECT_EQ(fit::ok(), status);
  ASSERT_TRUE(
      test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));

  // Create Connection will retry, and it hangs for 16s before
  // ConnectionCompletePageTimeout
  RunFor(std::chrono::seconds(16));
  ASSERT_TRUE(
      test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));
  RunUntilIdle();
  // Create Connection will *not* be tried again as we are outside of the retry
  // window.
  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PAGE_TIMEOUT), status);
}

TEST_F(BrEdrConnectionManagerTest,
       ConnectSecondPeerFirstFailsWithPageTimeoutAndDoesNotRetry) {
  auto* peer_a = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  auto* peer_b = peer_cache()->NewPeer(kTestDevAddr2, /*connectable=*/true);

  // First peer's Create Connection Request will complete with a page timeout
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kCreateConnection,
                        &kCreateConnectionRsp,
                        &kConnectionCompletePageTimeout);

  // Immediately enqueue successful connection request to peer_b, without any
  // retry in between for the Connect() call to peer_a.
  QueueSuccessfulCreateConnection(peer_b, kConnectionHandle2);
  QueueSuccessfulInterrogation(peer_b->address(), kConnectionHandle2);
  QueueDisconnection(kConnectionHandle2);

  // Initialize as success to verify that |callback_a| assigns failure.
  hci::Result<> status_a = fit::ok();
  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::Result<> status_b = ToResult(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, which will cause a Connection Complete: page timeout
  // controller event.
  EXPECT_TRUE(connmgr()->Connect(peer_a->identifier(), callback_a));
  EXPECT_TRUE(IsInitializing(peer_a));

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

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

  // The Connect() request to peer_a should fail with the Page Timeout status
  // code without retrying
  EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PAGE_TIMEOUT),
            status_a);
  EXPECT_EQ(fit::ok(), status_b);
  EXPECT_TRUE(HasConnectionTo(peer_b, connection));
  EXPECT_TRUE(IsNotConnected(peer_a));
  EXPECT_FALSE(IsNotConnected(peer_b));
}

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

  // Enqueue first connection request (which will await Connection Complete)
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        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(RunUntilIdle());

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

  EXPECT_FALSE(connmgr()->Disconnect(peer_a->identifier(),
                                     DisconnectReason::kApiRequest));
  EXPECT_FALSE(connmgr()->Disconnect(peer_b->identifier(),
                                     DisconnectReason::kApiRequest));
}

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

  // Peer successfully connects to us.
  QueueSuccessfulIncomingConn(kTestDevAddr);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_FALSE(IsNotConnected(peer));

  // Disconnect locally from an API Request.
  QueueDisconnection(kConnectionHandle);
  EXPECT_TRUE(
      connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));

  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_TRUE(IsNotConnected(peer));

  // Peer tries to connect to us. We should reject the connection.
  auto status_event =
      testing::CommandStatusPacket(hci_spec::kRejectConnectionRequest,
                                   pw::bluetooth::emboss::StatusCode::SUCCESS);
  auto reject_packet = testing::RejectConnectionRequestPacket(
      kTestDevAddr,
      pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR);

  EXPECT_CMD_PACKET_OUT(test_device(), reject_packet, &status_event);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_TRUE(IsNotConnected(peer));

  // After the cooldown time, a successful incoming connection can happen.
  RunFor(BrEdrConnectionManager::kLocalDisconnectCooldownDuration);

  QueueRepeatIncomingConn(kTestDevAddr);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_FALSE(IsNotConnected(peer));

  // Can still connect out if we disconnect locally.
  QueueDisconnection(kConnectionHandle);
  EXPECT_TRUE(
      connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
  RETURN_IF_FATAL(RunUntilIdle());

  EXPECT_TRUE(IsNotConnected(peer));

  QueueSuccessfulCreateConnection(peer, kConnectionHandle);
  // Interrogation is short because the peer is already known
  QueueShortInterrogation(kConnectionHandle);

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

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

  // Complete connection.
  RETURN_IF_FATAL(RunUntilIdle());

  EXPECT_EQ(fit::ok(), status);
  EXPECT_TRUE(HasConnectionTo(peer, connection));
  EXPECT_FALSE(IsNotConnected(peer));

  // Remote disconnections can reconnect immediately
  test_device()->SendCommandChannelPacket(kDisconnectionComplete);
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_TRUE(IsNotConnected(peer));

  QueueRepeatIncomingConn(kTestDevAddr);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_FALSE(IsNotConnected(peer));

  // If the reason is not kApiRequest, then the remote peer can reconnect
  // immediately.
  QueueDisconnection(kConnectionHandle);
  EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(),
                                    DisconnectReason::kPairingFailed));
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_TRUE(IsNotConnected(peer));

  QueueRepeatIncomingConn(kTestDevAddr);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_FALSE(IsNotConnected(peer));

  // Queue disconnection for teardown.
  QueueDisconnection(kConnectionHandle);
}

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

  // Peer successfully connects to us.
  QueueSuccessfulIncomingConn(kTestDevAddr);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_FALSE(IsNotConnected(peer));

  // Disconnect locally from an API Request.
  QueueDisconnection(kConnectionHandle);
  EXPECT_TRUE(
      connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));

  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_TRUE(IsNotConnected(peer));

  // Peer tries to connect to us. We should reject the connection.
  auto status_event =
      testing::CommandStatusPacket(hci_spec::kRejectConnectionRequest,
                                   pw::bluetooth::emboss::StatusCode::SUCCESS);
  auto reject_packet = testing::RejectConnectionRequestPacket(
      kTestDevAddr,
      pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR);

  EXPECT_CMD_PACKET_OUT(test_device(), reject_packet, &status_event);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_TRUE(IsNotConnected(peer));

  // If we initiate a connection out, then an incoming connection can succeed,
  // even if we fail to make the connection out.
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRspError);

  // Initialize as ok to verify that |callback| assigns failure
  hci::Result<> status = fit::ok();
  EXPECT_TRUE(
      connmgr()->Connect(peer->identifier(), CALLBACK_EXPECT_FAILURE(status)));
  EXPECT_TRUE(IsInitializing(peer));
  RunUntilIdle();

  // The outgoing connection failed to succeed
  EXPECT_TRUE(IsNotConnected(peer));

  // but an incoming connection can now succeed, since our intent is to connect
  // now
  QueueRepeatIncomingConn(kTestDevAddr);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RETURN_IF_FATAL(RunUntilIdle());
  EXPECT_FALSE(IsNotConnected(peer));

  // Queue disconnection for teardown.
  QueueDisconnection(kConnectionHandle);
}

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

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

  // 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();
  l2cap()->set_simulate_open_channel_failure(true);
  l2cap()->ExpectOutboundL2capChannel(
      kConnectionHandle, l2cap::kSDP, kLocalCId, kRemoteCId, kChannelParams);

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

  // 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_FALSE(IsNotConnected(peer));

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

  EXPECT_TRUE(IsNotConnected(peer));
}

TEST_F(
    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);

  RunUntilIdle();

  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));

  RunUntilIdle();

  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++; });

  // Should register connection with ACL Data Channel.
  hci::FakeAclConnection connection_0(
      acl_data_channel(), kConnectionHandle, LinkType::kACL);
  hci::FakeAclConnection connection_1(
      acl_data_channel(), kConnectionHandle2, LinkType::kACL);

  acl_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
  acl_data_channel()->RegisterConnection(connection_1.GetWeakPtr());

  EXPECT_ACL_PACKET_OUT(test_device(),
                        StaticByteBuffer(
                            // ACL data header (handle: 0, length 1)
                            LowerBits(kConnectionHandle),
                            UpperBits(kConnectionHandle),
                            // payload length
                            0x01,
                            0x00,
                            // payload
                            1));
  // Create packet to send on |acl_connection_0|
  hci::ACLDataPacketPtr packet_0 = hci::ACLDataPacket::New(
      kConnectionHandle,
      hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
      hci_spec::ACLBroadcastFlag::kPointToPoint,
      /*payload_size=*/1);
  packet_0->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
  connection_0.QueuePacket(std::move(packet_0));
  RunUntilIdle();

  EXPECT_ACL_PACKET_OUT(test_device(),
                        StaticByteBuffer(
                            // ACL data header (handle: 0, length 1)
                            LowerBits(kConnectionHandle2),
                            UpperBits(kConnectionHandle2),
                            // payload length
                            0x01,
                            0x00,
                            // payload
                            1));
  hci::ACLDataPacketPtr packet_1 = hci::ACLDataPacket::New(
      kConnectionHandle2,
      hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
      hci_spec::ACLBroadcastFlag::kPointToPoint,
      /*payload_size=*/1);
  packet_1->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
  connection_1.QueuePacket(std::move(packet_1));
  RunUntilIdle();

  EXPECT_EQ(connection_0.queued_packets().size(), 0u);
  EXPECT_EQ(connection_1.queued_packets().size(), 1u);
  EXPECT_FALSE(test_device()->AllExpectedDataPacketsSent());

  EXPECT_CMD_PACKET_OUT(test_device(), kDisconnect, &kDisconnectRsp);

  EXPECT_TRUE(
      connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
  RunUntilIdle();

  // Packet for |kConnectionHandle2| should not have been sent before
  // Disconnection Complete event.
  EXPECT_EQ(connection_0.queued_packets().size(), 0u);
  EXPECT_EQ(connection_1.queued_packets().size(), 1u);
  EXPECT_FALSE(test_device()->AllExpectedDataPacketsSent());

  acl_data_channel()->UnregisterConnection(kConnectionHandle);

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

  EXPECT_TRUE(IsNotConnected(peer));

  // Disconnection Complete handler should clear controller packet counts, so
  // packet for |kConnectionHandle2| should be sent
  EXPECT_EQ(connection_0.queued_packets().size(), 0u);
  EXPECT_EQ(connection_1.queued_packets().size(), 0u);
  EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());

  // Connection handle |kConnectionHandle| should have been unregistered with
  // ACL Data Channel.
  QueueDisconnection(kConnectionHandle2);
}

TEST_F(BrEdrConnectionManagerTest, PairUnconnectedPeer) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());
  ASSERT_EQ(peer_cache()->count(), 1u);
  uint count_cb_called = 0;
  auto cb = [&count_cb_called](hci::Result<> status) {
    ASSERT_EQ(ToResult(bt::HostError::kNotFound), status);
    count_cb_called++;
  };
  connmgr()->Pair(peer->identifier(), kNoSecurityRequirements, cb);
  ASSERT_EQ(count_cb_called, 1u);
}

TEST_F(BrEdrConnectionManagerTest, Pair) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsInitializing(peer));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  QueueSuccessfulPairing();

  // Make the pairing error a "bad" error to confirm the callback is called at
  // the end of the pairing process.
  hci::Result<> pairing_status = ToResult(HostError::kPacketMalformed);
  auto pairing_complete_cb = [&pairing_status](hci::Result<> status) {
    ASSERT_EQ(fit::ok(), status);
    pairing_status = status;
  };

  connmgr()->Pair(
      peer->identifier(), kNoSecurityRequirements, pairing_complete_cb);
  ASSERT_TRUE(IsInitializing(peer));
  ASSERT_FALSE(peer->bonded());
  RunUntilIdle();

  ASSERT_EQ(fit::ok(), pairing_status);
  ASSERT_TRUE(IsConnected(peer));
  ASSERT_TRUE(peer->bonded());

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest, PairTwice) {
  QueueSuccessfulIncomingConn();

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsInitializing(peer));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  QueueSuccessfulPairing();

  // Make the pairing error a "bad" error to confirm the callback is called at
  // the end of the pairing process.
  hci::Result<> pairing_status = ToResult(HostError::kPacketMalformed);
  auto pairing_complete_cb = [&pairing_status](hci::Result<> status) {
    ASSERT_EQ(fit::ok(), status);
    pairing_status = status;
  };

  connmgr()->Pair(
      peer->identifier(), kNoSecurityRequirements, pairing_complete_cb);
  RunUntilIdle();

  ASSERT_EQ(fit::ok(), pairing_status);
  ASSERT_TRUE(IsConnected(peer));
  ASSERT_TRUE(peer->bonded());

  pairing_status = ToResult(HostError::kPacketMalformed);
  connmgr()->Pair(
      peer->identifier(), kNoSecurityRequirements, 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.
  RunUntilIdle();
  ASSERT_EQ(fit::ok(), pairing_status);
  ASSERT_TRUE(peer->bonded());

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest,
       OpenL2capChannelCreatesChannelWithChannelParameters) {
  constexpr l2cap::Psm kPsm = l2cap::kAVDTP;
  constexpr l2cap::ChannelId kLocalId = l2cap::kFirstDynamicChannelId;
  l2cap::ChannelParameters params;
  params.mode =
      l2cap::RetransmissionAndFlowControlMode::kEnhancedRetransmission;
  params.max_rx_sdu_size = l2cap::kMinACLMTU;

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

  RunUntilIdle();

  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  QueueSuccessfulPairing();
  RunUntilIdle();

  l2cap()->ExpectOutboundL2capChannel(
      kConnectionHandle, kPsm, kLocalId, 0x41, params);

  std::optional<l2cap::ChannelInfo> chan_info;
  size_t sock_cb_count = 0;
  auto sock_cb = [&](auto chan) {
    sock_cb_count++;
    ASSERT_TRUE(chan.is_alive());
    chan_info = chan->info();
  };
  connmgr()->OpenL2capChannel(
      peer->identifier(), kPsm, kNoSecurityRequirements, params, sock_cb);

  RunUntilIdle();
  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(BrEdrConnectionManagerTest,
       ConnectionCleanUpFollowingEncryptionFailure) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  EXPECT_TRUE(peer->temporary());

  // Queue up the connection
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kCreateConnection,
                        &kCreateConnectionRsp,
                        &kConnectionComplete);
  QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
  QueueDisconnection(kConnectionHandle,
                     pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE);

  // Initialize as error to verify that |callback| assigns success.
  hci::Result<> status = ToResult(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());
  RunUntilIdle();
  ASSERT_EQ(fit::ok(), status);

  test_device()->SendCommandChannelPacket(testing::EncryptionChangeEventPacket(
      pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE,
      kConnectionHandle,
      hci_spec::EncryptionStatus::kOff));
  test_device()->SendCommandChannelPacket(testing::DisconnectionCompletePacket(
      kConnectionHandle,
      pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE));
  RunUntilIdle();

  EXPECT_TRUE(IsNotConnected(peer));
}

TEST_F(BrEdrConnectionManagerTest, OpenL2capChannelUpgradesLinkKey) {
  QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  FakePairingDelegate pairing_delegate_no_io(
      sm::IOCapability::kNoInputNoOutput);
  connmgr()->SetPairingDelegate(pairing_delegate_no_io.GetWeakPtr());
  pairing_delegate_no_io.SetConfirmPairingCallback(
      [&peer](PeerId peer_id, auto cb) {
        EXPECT_EQ(peer->identifier(), peer_id);
        ASSERT_TRUE(cb);
        cb(true);
      });
  pairing_delegate_no_io.SetCompletePairingCallback(
      [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  size_t sock_cb_count = 0;
  auto sock_cb = [&](auto chan_sock) {
    sock_cb_count++;
    EXPECT_TRUE(chan_sock.is_alive());
  };

  // Pairing caused by missing link key.
  QueueSuccessfulUnauthenticatedPairing();

  constexpr auto kPsm0 = l2cap::kHIDControl;
  constexpr l2cap::ChannelId kLocalId0 = l2cap::kFirstDynamicChannelId;
  constexpr l2cap::ChannelId kRemoteId0 = 0x41;
  l2cap()->ExpectOutboundL2capChannel(kConnectionHandle,
                                      kPsm0,
                                      kLocalId0,
                                      kRemoteId0,
                                      l2cap::ChannelParameters());
  connmgr()->OpenL2capChannel(peer->identifier(),
                              kPsm0,
                              kNoSecurityRequirements,
                              l2cap::ChannelParameters(),
                              sock_cb);

  RunUntilIdle();
  EXPECT_EQ(1u, sock_cb_count);

  // New pairing delegate with display can support authenticated pairing.
  FakePairingDelegate pairing_delegate_with_display(
      sm::IOCapability::kDisplayYesNo);
  connmgr()->SetPairingDelegate(pairing_delegate_with_display.GetWeakPtr());
  pairing_delegate_with_display.SetDisplayPasskeyCallback(
      [](PeerId, uint32_t passkey, auto method, auto confirm_cb) {
        confirm_cb(true);
      });
  pairing_delegate_with_display.SetCompletePairingCallback(
      [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  // Pairing caused by insufficient link key.
  QueueSuccessfulPairing();

  constexpr auto kPsm1 = l2cap::kHIDInteerup;
  constexpr l2cap::ChannelId kLocalId1 = kLocalId0 + 1;
  constexpr l2cap::ChannelId kRemoteId1 = kRemoteId0 + 1;
  l2cap()->ExpectOutboundL2capChannel(kConnectionHandle,
                                      kPsm1,
                                      kLocalId1,
                                      kRemoteId1,
                                      l2cap::ChannelParameters());
  connmgr()->OpenL2capChannel(peer->identifier(),
                              kPsm1,
                              kAuthSecurityRequirements,
                              l2cap::ChannelParameters(),
                              sock_cb);

  RunUntilIdle();
  EXPECT_EQ(2u, sock_cb_count);

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest, OpenL2capChannelUpgradeLinkKeyFails) {
  QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

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

  FakePairingDelegate pairing_delegate_no_io(
      sm::IOCapability::kNoInputNoOutput);
  connmgr()->SetPairingDelegate(pairing_delegate_no_io.GetWeakPtr());
  pairing_delegate_no_io.SetConfirmPairingCallback(
      [&peer](PeerId peer_id, auto cb) {
        EXPECT_EQ(peer->identifier(), peer_id);
        ASSERT_TRUE(cb);
        cb(true);
      });
  pairing_delegate_no_io.SetCompletePairingCallback(
      [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  size_t sock_cb_count = 0;
  auto sock_cb = [&](auto chan_sock) {
    if (sock_cb_count == 0) {
      EXPECT_TRUE(chan_sock.is_alive());
    } else {
      // Second OpenL2capChannel fails due to insufficient security.
      EXPECT_FALSE(chan_sock.is_alive());
    }
    sock_cb_count++;
  };

  // Initial pairing.
  QueueSuccessfulUnauthenticatedPairing();

  constexpr auto kPsm0 = l2cap::kHIDControl;
  constexpr l2cap::ChannelId kLocalId = l2cap::kFirstDynamicChannelId;
  constexpr l2cap::ChannelId kRemoteId = 0x41;
  l2cap()->ExpectOutboundL2capChannel(kConnectionHandle,
                                      kPsm0,
                                      kLocalId,
                                      kRemoteId,
                                      l2cap::ChannelParameters());
  connmgr()->OpenL2capChannel(peer->identifier(),
                              kPsm0,
                              kNoSecurityRequirements,
                              l2cap::ChannelParameters(),
                              sock_cb);

  RunUntilIdle();
  EXPECT_EQ(1u, sock_cb_count);

  // Pairing caused by insufficient link key.
  QueueSuccessfulUnauthenticatedPairing();

  constexpr auto kPsm1 = l2cap::kHIDInteerup;

  connmgr()->OpenL2capChannel(peer->identifier(),
                              kPsm1,
                              kAuthSecurityRequirements,
                              l2cap::ChannelParameters(),
                              sock_cb);

  RunUntilIdle();
  EXPECT_EQ(2u, sock_cb_count);

  // Pairing should not be attempted a third time.

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest,
       OpenScoConnectionWithoutExistingBrEdrConnectionFails) {
  std::optional<sco::ScoConnectionManager::OpenConnectionResult> conn_result;
  auto conn_cb = [&conn_result](auto result) {
    conn_result = std::move(result);
  };
  auto handle = connmgr()->OpenScoConnection(
      PeerId(1),
      {bt::StaticPacket<
          pw::bluetooth::emboss::SynchronousConnectionParametersWriter>{}},
      std::move(conn_cb));
  EXPECT_FALSE(handle.has_value());
  ASSERT_TRUE(conn_result.has_value());
  ASSERT_TRUE(conn_result->is_error());
  EXPECT_EQ(conn_result->error_value(), HostError::kNotFound);
}

TEST_F(BrEdrConnectionManagerTest, OpenScoConnectionInitiator) {
  QueueSuccessfulIncomingConn();
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);

  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      kScoConnection;
  kScoConnection.SetToZeros();
  constexpr hci_spec::ConnectionHandle kScoConnectionHandle = 0x41;
  auto setup_status_packet = testing::CommandStatusPacket(
      hci_spec::kEnhancedSetupSynchronousConnection,
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
      kScoConnectionHandle,
      peer->address(),
      hci_spec::LinkType::kExtendedSCO,
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  EXPECT_CMD_PACKET_OUT(
      test_device(),
      testing::EnhancedSetupSynchronousConnectionPacket(kConnectionHandle, {}),
      &setup_status_packet,
      &conn_complete_packet);

  std::optional<sco::ScoConnectionManager::OpenConnectionResult> conn_result;
  auto conn_cb = [&conn_result](auto result) {
    conn_result = std::move(result);
  };

  auto req_handle = connmgr()->OpenScoConnection(
      peer->identifier(), {kScoConnection}, std::move(conn_cb));

  RunUntilIdle();
  ASSERT_TRUE(conn_result.has_value());
  ASSERT_TRUE(conn_result->is_ok());
  EXPECT_EQ(conn_result->value()->handle(), kScoConnectionHandle);

  // Disconnecting from a peer should first disconnect SCO connections, then
  // disconnect the ACL connection.
  QueueDisconnection(kScoConnectionHandle);
  QueueDisconnection(kConnectionHandle);
  connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest);
  RunUntilIdle();
}

class ScoLinkTypesTest
    : public BrEdrConnectionManagerTest,
      public ::testing::WithParamInterface<hci_spec::LinkType> {};

TEST_P(ScoLinkTypesTest, OpenScoConnectionResponder) {
  QueueSuccessfulIncomingConn();
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);

  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      sco_conn_params;
  if (GetParam() == hci_spec::LinkType::kSCO) {
    sco_conn_params.view().packet_types().hv3().Write(true);
  } else {
    sco_conn_params.view().packet_types().ev3().Write(true);
  }
  std::optional<sco::ScoConnectionManager::AcceptConnectionResult> conn_result;
  auto conn_cb =
      [&conn_result](sco::ScoConnectionManager::AcceptConnectionResult result) {
        EXPECT_TRUE(result.is_ok());
        conn_result = std::move(result);
      };
  auto req_handle = connmgr()->AcceptScoConnection(
      peer->identifier(), {sco_conn_params}, std::move(conn_cb));

  auto conn_req_packet = testing::ConnectionRequestPacket(
      peer->address(), /*link_type=*/GetParam());
  test_device()->SendCommandChannelPacket(conn_req_packet);

  auto accept_status_packet = testing::CommandStatusPacket(
      hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  EXPECT_CMD_PACKET_OUT(
      test_device(),
      testing::EnhancedAcceptSynchronousConnectionRequestPacket(
          peer->address(), sco_conn_params),
      &accept_status_packet);
  RunUntilIdle();
  EXPECT_FALSE(conn_result.has_value());

  constexpr hci_spec::ConnectionHandle kScoConnectionHandle = 0x41;
  test_device()->SendCommandChannelPacket(
      testing::SynchronousConnectionCompletePacket(
          kScoConnectionHandle,
          peer->address(),
          /*link_type=*/GetParam(),
          pw::bluetooth::emboss::StatusCode::SUCCESS));

  RunUntilIdle();
  ASSERT_TRUE(conn_result.has_value());
  ASSERT_TRUE(conn_result->is_ok());
  EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);

  // Disconnecting from a peer should first disconnect SCO connections, then
  // disconnect the ACL connection.
  QueueDisconnection(kScoConnectionHandle);
  QueueDisconnection(kConnectionHandle);
  connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest);
  RunUntilIdle();
}

INSTANTIATE_TEST_SUITE_P(BrEdrConnectionManagerTest,
                         ScoLinkTypesTest,
                         ::testing::Values(hci_spec::LinkType::kSCO,
                                           hci_spec::LinkType::kExtendedSCO));

class UnconnectedLinkTypesTest
    : public BrEdrConnectionManagerTest,
      public ::testing::WithParamInterface<hci_spec::LinkType> {};

// Test that an unexpected SCO connection request is rejected for
// kUnacceptableConnectionParameters
TEST_P(UnconnectedLinkTypesTest, RejectUnsupportedSCOConnectionRequests) {
  auto status_event = testing::CommandStatusPacket(
      hci_spec::kRejectSynchronousConnectionRequest,
      pw::bluetooth::emboss::StatusCode::SUCCESS);
  auto complete_event = testing::ConnectionCompletePacket(
      kTestDevAddr,
      kConnectionHandle,
      pw::bluetooth::emboss::StatusCode::UNACCEPTABLE_CONNECTION_PARAMETERS);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        testing::RejectSynchronousConnectionRequest(
                            kTestDevAddr,
                            pw::bluetooth::emboss::StatusCode::
                                UNACCEPTABLE_CONNECTION_PARAMETERS),
                        &status_event,
                        &complete_event);
  test_device()->SendCommandChannelPacket(
      testing::ConnectionRequestPacket(kTestDevAddr, /*link_type=*/GetParam()));
  RunUntilIdle();
}

INSTANTIATE_TEST_SUITE_P(BrEdrConnectionManagerTest,
                         UnconnectedLinkTypesTest,
                         ::testing::Values(hci_spec::LinkType::kSCO,
                                           hci_spec::LinkType::kExtendedSCO));

// Test that an unexpected link type connection request is rejected for
// kUnsupportedFeatureOrParameter
TEST_F(BrEdrConnectionManagerTest, RejectUnsupportedConnectionRequest) {
  auto linktype = static_cast<hci_spec::LinkType>(0x09);
  auto status_event =
      testing::CommandStatusPacket(hci_spec::kRejectConnectionRequest,
                                   pw::bluetooth::emboss::StatusCode::SUCCESS);
  auto complete_event = testing::ConnectionCompletePacket(
      kTestDevAddr,
      kConnectionHandle,
      pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
  EXPECT_CMD_PACKET_OUT(
      test_device(),
      testing::RejectConnectionRequestPacket(
          kTestDevAddr,
          pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER),
      &status_event,
      &complete_event);
  test_device()->SendCommandChannelPacket(
      testing::ConnectionRequestPacket(kTestDevAddr, linktype));
  RunUntilIdle();
}

TEST_F(BrEdrConnectionManagerTest, IncomingConnectionRacesOutgoing) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  ASSERT_TRUE(peer->bredr() && IsNotConnected(peer));

  hci::Result<> status = ToResult(HostError::kFailed);
  BrEdrConnection* conn_ref = nullptr;
  auto should_succeed = [&status, &conn_ref](auto cb_status, auto cb_conn_ref) {
    // We expect this callback to be executed, with a succesful connection
    EXPECT_TRUE(cb_conn_ref);
    EXPECT_EQ(fit::ok(), cb_status);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
  };

  // A client calls Connect() for the Peer, beginning an outgoing connection. We
  // expect a CreateConnection, and ack with a status response but don't
  // complete yet
  EXPECT_CMD_PACKET_OUT(
      test_device(), kCreateConnection, &kCreateConnectionRsp);
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), should_succeed));

  // Meanwhile, an incoming connection is requested from the Peer
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  // We expect it to be accepted, and then return a command status response, but
  // not a ConnectionComplete event yet
  EXPECT_CMD_PACKET_OUT(
      test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
  RunUntilIdle();

  // The controller now establishes the link, but will respond to the outgoing
  // connection with the hci error: `ConnectionAlreadyExists` First, the
  // controller notifies us of the failed outgoing connection - as from its
  // perspective, we've already connected
  const auto complete_already = testing::ConnectionCompletePacket(
      kTestDevAddr,
      kConnectionHandle,
      pw::bluetooth::emboss::StatusCode::CONNECTION_ALREADY_EXISTS);
  test_device()->SendCommandChannelPacket(complete_already);
  // Then the controller notifies us of the successful incoming connection
  test_device()->SendCommandChannelPacket(kConnectionComplete);
  // We expect to connect and begin interrogation, and for our connect()
  // callback to have been run
  QueueSuccessfulInterrogation(kTestDevAddr, kConnectionHandle);
  RunUntilIdle();
  EXPECT_EQ(fit::ok(), status);

  // Peers are marked as initializing until a pairing procedure finishes.
  EXPECT_TRUE(IsInitializing(peer));
  // Prepare for disconnection upon teardown.
  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest, OutgoingConnectionRacesIncoming) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  ASSERT_TRUE(peer->bredr() && IsNotConnected(peer));
  hci::Result<> status = ToResult(HostError::kFailed);
  BrEdrConnection* conn_ref = nullptr;
  auto should_succeed = [&status, &conn_ref](auto cb_status, auto cb_conn_ref) {
    EXPECT_TRUE(cb_conn_ref);
    EXPECT_EQ(fit::ok(), cb_status);
    status = cb_status;
    conn_ref = std::move(cb_conn_ref);
  };

  // An incoming connection is requested from the Peer
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  // We expect it to be accepted, and then return a command status response, but
  // not a ConnectionComplete event yet
  EXPECT_CMD_PACKET_OUT(
      test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
  RunUntilIdle();
  // Meanwhile, a client calls Connect() for the peer. We don't expect any
  // packets out as the connection manager will defer requests that have an
  // active incoming request. Instead, this request will be completed when the
  // incoming procedure completes.
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), should_succeed));
  // We should still expect to connect
  RunUntilIdle();

  // The controller now notifies us of the complete incoming connection
  test_device()->SendCommandChannelPacket(kConnectionComplete);
  // We expect to connect and begin interrogation, and for the callback passed
  // to Connect() to have been executed when the incoming connection succeeded.
  QueueSuccessfulInterrogation(kTestDevAddr, kConnectionHandle);
  RunUntilIdle();
  EXPECT_EQ(fit::ok(), status);

  // Peers are marked as initializing until a pairing procedure finishes.
  EXPECT_TRUE(IsInitializing(peer));
  // Prepare for disconnection upon teardown.
  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest,
       DuplicateIncomingConnectionsFromSamePeerRejected) {
  auto* peer = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
  ASSERT_TRUE(peer->bredr() && IsNotConnected(peer));

  // Our first request should be accepted - we send back a success status, not
  // the connection complete yet
  EXPECT_CMD_PACKET_OUT(
      test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();

  auto status_event =
      testing::CommandStatusPacket(hci_spec::kRejectConnectionRequest,
                                   pw::bluetooth::emboss::StatusCode::SUCCESS);
  auto complete_error = testing::ConnectionCompletePacket(
      kTestDevAddr,
      kConnectionHandle,
      pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
  auto reject_packet = testing::RejectConnectionRequestPacket(
      kTestDevAddr,
      pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR);

  // Our second request should be rejected - we already have an incoming request
  EXPECT_CMD_PACKET_OUT(test_device(), reject_packet, &status_event);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();

  QueueSuccessfulInterrogation(kTestDevAddr, kConnectionHandle);
  test_device()->SendCommandChannelPacket(kConnectionComplete);
  RunUntilIdle();
  test_device()->SendCommandChannelPacket(complete_error);

  RunUntilIdle();

  EXPECT_FALSE(IsNotConnected(peer));

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

TEST_F(BrEdrConnectionManagerTest, IncomingRequestInitializesPeer) {
  // Initially, we should not have a peer for the given address
  auto peer = peer_cache()->FindByAddress(kTestDevAddr);
  EXPECT_FALSE(peer);
  // Send a request, and once accepted send back a success status but not the
  // connection complete yet
  EXPECT_CMD_PACKET_OUT(
      test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();

  // We should now have a peer in the cache to track our incoming request
  // address The peer is marked as 'Initializing` immediately.
  peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(peer->bredr());
  ASSERT_EQ(peer->bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);
}

#ifndef NINSPECT
TEST_F(BrEdrConnectionManagerTest, Inspect) {
  connmgr()->AttachInspect(inspector().GetRoot(), "bredr_connection_manager");

  // Don't receive connection complete yet in order to keep request pending.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        testing::AcceptConnectionRequestPacket(kTestDevAddr),
                        &kAcceptConnectionRequestRsp);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();

  auto requests_one_request_matcher = AllOf(
      NodeMatches(NameMatches("connection_requests")),
      ChildrenMatch(ElementsAre(NodeMatches(NameMatches("request_0x0")))));

  auto conn_mgr_with_request_matcher = AllOf(
      NodeMatches(NameMatches("bredr_connection_manager")),
      ChildrenMatch(::testing::IsSupersetOf({requests_one_request_matcher})));

  EXPECT_THAT(inspect::ReadFromVmo(inspector().DuplicateVmo()).value(),
              ChildrenMatch(ElementsAre(conn_mgr_with_request_matcher)));

  QueueSuccessfulInterrogation(kTestDevAddr, kConnectionHandle);
  const auto connection_complete =
      testing::ConnectionCompletePacket(kTestDevAddr, kConnectionHandle);
  test_device()->SendCommandChannelPacket(connection_complete);
  RunUntilIdle();
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_EQ(peer->bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);

  auto empty_requests_matcher =
      AllOf(NodeMatches(NameMatches("connection_requests")),
            ChildrenMatch(::testing::IsEmpty()));

  auto connection_matcher =
      NodeMatches(AllOf(NameMatches("connection_0x1"),
                        PropertyList(ElementsAre(StringIs(
                            "peer_id", peer->identifier().ToString())))));

  auto connections_matcher =
      AllOf(NodeMatches(NameMatches("connections")),
            ChildrenMatch(ElementsAre(connection_matcher)));

  auto recent_conn_list_matcher =
      AllOf(NodeMatches(NameMatches("last_disconnected")),
            ChildrenMatch(::testing::IsEmpty()));

  auto incoming_matcher =
      AllOf(NodeMatches(AllOf(NameMatches("incoming"),
                              PropertyList(UnorderedElementsAre(
                                  UintIs("connection_attempts", 1),
                                  UintIs("failed_connections", 0),
                                  UintIs("successful_connections", 0))))));

  auto outgoing_matcher =
      AllOf(NodeMatches(AllOf(NameMatches("outgoing"),
                              PropertyList(UnorderedElementsAre(
                                  UintIs("connection_attempts", 0),
                                  UintIs("failed_connections", 0),
                                  UintIs("successful_connections", 0))))));

  auto conn_mgr_matcher = AllOf(
      NodeMatches(AllOf(NameMatches("bredr_connection_manager"),
                        PropertyList(UnorderedElementsAre(
                            UintIs("disconnect_acl_link_error_count", 0),
                            UintIs("disconnect_interrogation_failed_count", 0),
                            UintIs("disconnect_local_api_request_count", 0),
                            UintIs("disconnect_pairing_failed_count", 0),
                            UintIs("disconnect_peer_disconnection_count", 0),
                            UintIs("interrogation_complete_count", 1),
                            StringIs("security_mode", "Mode 4"))))),
      ChildrenMatch(UnorderedElementsAre(empty_requests_matcher,
                                         connections_matcher,
                                         recent_conn_list_matcher,
                                         incoming_matcher,
                                         outgoing_matcher)));

  auto hierarchy = inspect::ReadFromVmo(inspector().DuplicateVmo());
  EXPECT_THAT(hierarchy.value(), ChildrenMatch(ElementsAre(conn_mgr_matcher)));

  // Delay disconnect so connection has non-zero duration.
  RunFor(std::chrono::seconds(1));
  QueueDisconnection(kConnectionHandle);
  EXPECT_TRUE(
      connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
  RunUntilIdle();

  auto incoming_matcher_after_disconnect =
      AllOf(NodeMatches(AllOf(NameMatches("incoming"),
                              PropertyList(UnorderedElementsAre(
                                  UintIs("connection_attempts", 1),
                                  UintIs("failed_connections", 0),
                                  UintIs("successful_connections", 0))))));

  auto requests_matcher = AllOf(NodeMatches(NameMatches("connection_requests")),
                                ChildrenMatch(::testing::IsEmpty()));
  auto connections_after_disconnect_matcher =
      AllOf(NodeMatches(NameMatches("connections")),
            ChildrenMatch(::testing::IsEmpty()));
  auto recent_conn_list_after_disconnect_matcher =
      AllOf(NodeMatches(NameMatches("last_disconnected")),
            ChildrenMatch(ElementsAre(NodeMatches(
                AllOf(NameMatches("0"),
                      PropertyList(UnorderedElementsAre(
                          StringIs("peer_id", peer->identifier().ToString()),
                          UintIs("duration_s", 1u),
                          IntIs("@time", 1'000'000'000))))))));

  auto conn_mgr_after_disconnect_matcher = AllOf(
      NodeMatches(AllOf(NameMatches("bredr_connection_manager"),
                        PropertyList(UnorderedElementsAre(
                            UintIs("disconnect_acl_link_error_count", 0),
                            UintIs("disconnect_interrogation_failed_count", 0),
                            UintIs("disconnect_local_api_request_count", 1),
                            UintIs("disconnect_pairing_failed_count", 0),
                            UintIs("disconnect_peer_disconnection_count", 0),
                            UintIs("interrogation_complete_count", 1),
                            StringIs("security_mode", "Mode 4"))))),
      ChildrenMatch(
          UnorderedElementsAre(empty_requests_matcher,
                               connections_after_disconnect_matcher,
                               outgoing_matcher,
                               incoming_matcher_after_disconnect,
                               recent_conn_list_after_disconnect_matcher)));

  hierarchy = inspect::ReadFromVmo(inspector().DuplicateVmo());
  EXPECT_THAT(hierarchy.value(),
              ChildrenMatch(ElementsAre(conn_mgr_after_disconnect_matcher)));
}
#endif  // NINSPECT

TEST_F(BrEdrConnectionManagerTest, RoleChangeAfterInboundConnection) {
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));

  QueueSuccessfulIncomingConn();
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);

  // Request an outbound connection in order to get a pointer to the existing
  // connection. No packets should be sent.
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&conn_ref](auto /*status*/, auto cb_conn_ref) {
    conn_ref = cb_conn_ref;
  };

  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(conn_ref);
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);

  test_device()->SendCommandChannelPacket(testing::RoleChangePacket(
      kTestDevAddr, pw::bluetooth::emboss::ConnectionRole::CENTRAL));
  RunUntilIdle();
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::CENTRAL);

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest,
       RoleChangeWithFailureStatusAfterInboundConnection) {
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));

  QueueSuccessfulIncomingConn();
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);

  // Request an outbound connection in order to get a pointer to the existing
  // connection. No packets should be sent.
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&conn_ref](auto /*status*/, auto cb_conn_ref) {
    conn_ref = cb_conn_ref;
  };
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(conn_ref);
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);

  test_device()->SendCommandChannelPacket(testing::RoleChangePacket(
      kTestDevAddr,
      pw::bluetooth::emboss::ConnectionRole::CENTRAL,
      pw::bluetooth::emboss::StatusCode::UNSPECIFIED_ERROR));
  RunUntilIdle();
  // The role should not change.
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);

  QueueDisconnection(kConnectionHandle);
}

TEST_F(BrEdrConnectionManagerTest, RoleChangeDuringInboundConnectionProcedure) {
  EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));

  QueueSuccessfulIncomingConn(
      kTestDevAddr,
      kConnectionHandle,
      /*role_change=*/pw::bluetooth::emboss::ConnectionRole::CENTRAL);
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();
  auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  EXPECT_EQ(peer->bredr()->connection_state(),
            Peer::ConnectionState::kInitializing);

  // Request an outbound connection in order to get a pointer to the existing
  // connection. No packets should be sent.
  BrEdrConnection* conn_ref = nullptr;
  auto callback = [&conn_ref](auto /*status*/, auto cb_conn_ref) {
    conn_ref = cb_conn_ref;
  };
  EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
  ASSERT_TRUE(conn_ref);
  EXPECT_EQ(conn_ref->link().role(),
            pw::bluetooth::emboss::ConnectionRole::CENTRAL);

  QueueDisconnection(kConnectionHandle);
}

// Peer and local Secure Connections (SC) are supported and key is of SC type
TEST_F(BrEdrConnectionManagerTest,
       SecureConnectionsSupportedCorrectLinkKeyTypeSucceeds) {
  const auto kReadRemoteExtended2Complete = StaticByteBuffer(
      hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode,
      0x0D,  // parameter_total_size (13 bytes)
      pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
      0xAA,
      0x0B,  // connection_handle,
      0x02,  // page_number
      0x02,  // max_page_number
      0x00,
      0x01,
      0x00,
      0x00,
      0x00,
      0x00,
      0x00,
      0x00
      // lmp_features_page2: Secure Connections (Controller Support)
  );
  const auto kLinkKeyNotification = MakeLinkKeyNotification(
      hci_spec::LinkKeyType::kAuthenticatedCombination256);
  const StaticByteBuffer kEncryptionChangeEvent(
      hci_spec::kEncryptionChangeEventCode,
      4,     // parameter total size
      0x00,  // status
      0xAA,
      0x0B,  // connection handle
      0x02   // encryption enabled: AES-CCM for BR/EDR
  );

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

  // Trigger inbound connection and respond to interrogation. LMP features are
  // set to support peer host and controller Secure Connections.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAcceptConnectionRequest,
                        &kAcceptConnectionRequestRsp,
                        &kConnectionComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kRemoteNameRequest,
                        &kRemoteNameRequestRsp,
                        &kRemoteNameRequestComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteVersionInfo,
                        &kReadRemoteVersionInfoRsp,
                        &kRemoteVersionInfoComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        hci_spec::kReadRemoteSupportedFeatures,
                        &kReadRemoteSupportedFeaturesRsp,
                        &kReadRemoteSupportedFeaturesComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended1,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended2,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended2Complete);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  // Ensure that the interrogation has begun but the peer hasn't yet bonded
  EXPECT_EQ(6, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsInitializing(peer));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  // Initiate pairing from the peer before interrogation completes
  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_YES_NO,
      AuthenticationRequirements::MITM_GENERAL_BONDING));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp,
                        &kUserConfirmationRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestReply,
                        &kUserConfirmationRequestReplyRsp,
                        &kSimplePairingCompleteSuccess,
                        &kLinkKeyNotification);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kSetConnectionEncryption,
                        &kSetConnectionEncryptionRsp,
                        &kEncryptionChangeEvent);
  EXPECT_CMD_PACKET_OUT(
      test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);

  RETURN_IF_FATAL(RunUntilIdle());

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

  QueueDisconnection(kConnectionHandle);
}

// Peer and local Secure Connections (SC) are supported, but key is not of SC
// type
TEST_F(BrEdrConnectionManagerTest,
       SecureConnectionsSupportedIncorrectLinkKeyTypeFails) {
  const auto kReadRemoteExtended2Complete = StaticByteBuffer(
      hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode,
      0x0D,  // parameter_total_size (13 bytes)
      pw::bluetooth::emboss::StatusCode::SUCCESS,  // status
      0xAA,
      0x0B,  // connection_handle,
      0x02,  // page_number
      0x02,  // max_page_number
      0x00,
      0x01,
      0x00,
      0x00,
      0x00,
      0x00,
      0x00,
      0x00
      // lmp_features_page2: Secure Connections (Controller Support)
  );

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

  // Trigger inbound connection and respond to interrogation. LMP features are
  // set to support peer host and controller Secure Connections.
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kAcceptConnectionRequest,
                        &kAcceptConnectionRequestRsp,
                        &kConnectionComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kRemoteNameRequest,
                        &kRemoteNameRequestRsp,
                        &kRemoteNameRequestComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteVersionInfo,
                        &kReadRemoteVersionInfoRsp,
                        &kRemoteVersionInfoComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        hci_spec::kReadRemoteSupportedFeatures,
                        &kReadRemoteSupportedFeaturesRsp,
                        &kReadRemoteSupportedFeaturesComplete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended1,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended1Complete);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kReadRemoteExtended2,
                        &kReadRemoteExtendedFeaturesRsp,
                        &kReadRemoteExtended2Complete);

  test_device()->SendCommandChannelPacket(kConnectionRequest);

  RunUntilIdle();

  // Ensure that the interrogation has begun but the peer hasn't yet bonded
  EXPECT_EQ(6, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsInitializing(peer));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  // Initiate pairing from the peer
  test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
      IoCapability::DISPLAY_YES_NO,
      AuthenticationRequirements::MITM_GENERAL_BONDING));
  test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
  const auto kUserConfirmationRequest = MakeUserConfirmationRequest(kPasskey);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        MakeIoCapabilityRequestReply(
                            IoCapability::DISPLAY_YES_NO,
                            AuthenticationRequirements::MITM_GENERAL_BONDING),
                        &kIoCapabilityRequestReplyRsp,
                        &kUserConfirmationRequest);
  EXPECT_CMD_PACKET_OUT(test_device(),
                        kUserConfirmationRequestReply,
                        &kUserConfirmationRequestReplyRsp,
                        &kSimplePairingCompleteSuccess,
                        &kLinkKeyNotification);

  // Connection terminates because kLinkKeyNotification's key type is
  // kAuthenticatedCombination192. When SC is supported, key type must be of SC
  // type (kUnauthenticatedCombination256 or kAuthenticatedCombination256).
  QueueDisconnection(kConnectionHandle);
  RETURN_IF_FATAL(RunUntilIdle());
}

// Active connections that do not meeting the requirements for Secure
// Connections Only mode are disconnected when the security mode is changed to
// SC Only.
TEST_F(BrEdrConnectionManagerTest,
       SecureConnectionsOnlyDisconnectsInsufficientSecurity) {
  QueueSuccessfulIncomingConn();
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();
  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsInitializing(peer));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  QueueSuccessfulPairing();  // kAuthenticatedCombination192 default is not of
                             // SC type

  // Initialize as error to verify that |pairing_complete_cb| assigns success.
  hci::Result<> pairing_status = ToResult(HostError::kInsufficientSecurity);
  auto pairing_complete_cb = [&pairing_status](hci::Result<> status) {
    ASSERT_EQ(fit::ok(), status);
    pairing_status = status;
  };

  connmgr()->Pair(
      peer->identifier(), kNoSecurityRequirements, pairing_complete_cb);
  ASSERT_TRUE(IsInitializing(peer));
  ASSERT_FALSE(peer->bonded());
  RunUntilIdle();

  ASSERT_EQ(fit::ok(), pairing_status);
  ASSERT_TRUE(IsConnected(peer));
  ASSERT_TRUE(peer->bonded());

  // Setting Secure Connections Only mode causes connections not allowed under
  // this mode to be disconnected. In this case, |peer| is encrypted,
  // authenticated, but not SC-generated.
  EXPECT_CMD_PACKET_OUT(test_device(), kDisconnect);
  connmgr()->SetSecurityMode(BrEdrSecurityMode::SecureConnectionsOnly);
  RunUntilIdle();
  EXPECT_EQ(BrEdrSecurityMode::SecureConnectionsOnly,
            connmgr()->security_mode());
  ASSERT_TRUE(IsNotConnected(peer));
}

// Active connections that meet the requirements for Secure Connections Only
// mode are not disconnected when the security mode is changed to SC Only.
TEST_F(BrEdrConnectionManagerTest,
       SecureConnectionsOnlySufficientSecuritySucceeds) {
  QueueSuccessfulIncomingConn();
  test_device()->SendCommandChannelPacket(kConnectionRequest);
  RunUntilIdle();
  EXPECT_EQ(kIncomingConnTransactions, transaction_count());
  auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
  ASSERT_TRUE(peer);
  ASSERT_TRUE(IsInitializing(peer));
  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::Result<> status) { EXPECT_EQ(fit::ok(), status); });

  QueueSuccessfulPairing(hci_spec::LinkKeyType::kAuthenticatedCombination256);

  // Initialize as error to verify that |pairing_complete_cb| assigns success.
  hci::Result<> pairing_status = ToResult(HostError::kInsufficientSecurity);
  auto pairing_complete_cb = [&pairing_status](hci::Result<> status) {
    ASSERT_EQ(fit::ok(), status);
    pairing_status = status;
  };

  connmgr()->Pair(
      peer->identifier(), kNoSecurityRequirements, pairing_complete_cb);
  ASSERT_TRUE(IsInitializing(peer));
  ASSERT_FALSE(peer->bonded());
  RunUntilIdle();

  ASSERT_EQ(fit::ok(), pairing_status);
  ASSERT_TRUE(IsConnected(peer));
  ASSERT_TRUE(peer->bonded());

  // Setting Secure Connections Only mode causes connections not allowed under
  // this mode to be disconnected. In this case, |peer| is encrypted,
  // authenticated, and SC-generated.
  connmgr()->SetSecurityMode(BrEdrSecurityMode::SecureConnectionsOnly);
  RunUntilIdle();
  EXPECT_EQ(BrEdrSecurityMode::SecureConnectionsOnly,
            connmgr()->security_mode());
  ASSERT_TRUE(IsConnected(peer));

  QueueDisconnection(kConnectionHandle);
}

#undef COMMAND_COMPLETE_RSP
#undef COMMAND_STATUS_RSP

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