blob: 2bd8bb3b044fe533e6387a7c01413cbe4f2444ba [file] [log] [blame]
// Copyright 2019 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 "test_packets.h"
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/bredr_connection_request.h"
namespace bt {
namespace testing {
// clang-format off
#define COMMAND_STATUS_RSP(opcode, statuscode) \
CreateStaticByteBuffer(hci::kCommandStatusEventCode, 0x04, \
(statuscode), 0xF0, \
LowerBits((opcode)), UpperBits((opcode)))
// clang-format on
DynamicByteBuffer AcceptConnectionRequestPacket(DeviceAddress address) {
const auto addr = address.value().bytes();
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kAcceptConnectionRequest), UpperBits(hci::kAcceptConnectionRequest),
0x07, // parameter_total_size (7 bytes)
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], // peer address
0x00 // role (become master)
));
}
DynamicByteBuffer AuthenticationRequestedPacket(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kAuthenticationRequested), UpperBits(hci::kAuthenticationRequested),
0x02, // parameter_total_size (2 bytes)
LowerBits(conn), UpperBits(conn) // Connection_Handle
));
}
DynamicByteBuffer ConnectionRequestPacket(DeviceAddress address) {
const auto addr = address.value().bytes();
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kConnectionRequestEventCode,
0x0A, // parameter_total_size (10 byte payload)
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], // peer address
0x00, 0x1F, 0x00, // class_of_device (unspecified)
0x01 // link_type (ACL)
));
}
DynamicByteBuffer CreateConnectionPacket(DeviceAddress address) {
auto addr = address.value().bytes();
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kCreateConnection), UpperBits(hci::kCreateConnection),
0x0d, // parameter_total_size (13 bytes)
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], // 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)
));
}
DynamicByteBuffer ConnectionCompletePacket(DeviceAddress address, hci::ConnectionHandle conn) {
auto addr = address.value().bytes();
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kConnectionCompleteEventCode,
0x0B, // parameter_total_size (11 byte payload)
hci::StatusCode::kSuccess, // status
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], // peer address
0x01, // link_type (ACL)
0x00 // encryption not enabled
));
}
DynamicByteBuffer DisconnectPacket(hci::ConnectionHandle conn, hci::StatusCode reason) {
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kDisconnect), UpperBits(hci::kDisconnect),
0x03, // parameter_total_size (3 bytes)
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
reason // Reason
));
}
DynamicByteBuffer DisconnectStatusResponsePacket() {
return DynamicByteBuffer(COMMAND_STATUS_RSP(hci::kDisconnect, hci::StatusCode::kSuccess));
}
DynamicByteBuffer DisconnectionCompletePacket(hci::ConnectionHandle conn, hci::StatusCode reason) {
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kDisconnectionCompleteEventCode,
0x04, // parameter_total_size (4 bytes)
hci::StatusCode::kSuccess, // status
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
reason // Reason
));
}
DynamicByteBuffer EncryptionChangeEventPacket(hci::StatusCode status_code,
hci::ConnectionHandle conn,
hci::EncryptionStatus encryption_enabled) {
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kEncryptionChangeEventCode,
0x04, // parameter_total_size (4 bytes)
status_code, // status
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_Handle
static_cast<uint8_t>(encryption_enabled) // Encryption_Enabled
));
}
DynamicByteBuffer NumberOfCompletedPacketsPacket(hci::ConnectionHandle conn, uint16_t num_packets) {
return DynamicByteBuffer(CreateStaticByteBuffer(
0x13, 0x05, // Number Of Completed Packet HCI event header, parameters length
0x01, // Number of handles
LowerBits(conn), UpperBits(conn), LowerBits(num_packets), UpperBits(num_packets)));
}
DynamicByteBuffer CommandStatusPacket(hci::OpCode op_code, hci::StatusCode status_code) {
return DynamicByteBuffer(StaticByteBuffer(
hci::kCommandStatusEventCode,
0x04, // parameter size (4 bytes)
status_code,
0xF0, // number of HCI command packets allowed to be sent to controller (240)
LowerBits(op_code), UpperBits(op_code)));
}
DynamicByteBuffer RemoteNameRequestPacket(DeviceAddress address) {
auto addr = address.value().bytes();
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kRemoteNameRequest), UpperBits(hci::kRemoteNameRequest),
0x0a, // parameter_total_size (10 bytes)
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], // peer address
0x00, // page_scan_repetition_mode (R0)
0x00, // reserved
0x00, 0x00 // clock_offset
));
}
DynamicByteBuffer RemoteNameRequestCompletePacket(DeviceAddress address) {
auto addr = address.value().bytes();
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kRemoteNameRequestCompleteEventCode,
0x20, // parameter_total_size (32)
hci::StatusCode::kSuccess, // status
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], // peer address
'F', 'u', 'c', 'h', 's', 'i', 'a', 0xF0, 0x9F, 0x92, 0x96, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
// remote name (Fuchsia 💖)
// Everything after the 0x00 should be ignored.
));
}
DynamicByteBuffer ReadRemoteVersionInfoPacket(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kReadRemoteVersionInfo), UpperBits(hci::kReadRemoteVersionInfo),
0x02, // Parameter_total_size (2 bytes)
LowerBits(conn), UpperBits(conn) // Little-Endian Connection_handle
));
}
DynamicByteBuffer ReadRemoteVersionInfoCompletePacket(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kReadRemoteVersionInfoCompleteEventCode,
0x08, // parameter_total_size (8 bytes)
hci::StatusCode::kSuccess, // status
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
hci::HCIVersion::k4_2, // lmp_version
0xE0, 0x00, // manufacturer_name (Google)
0xAD, 0xDE // lmp_subversion (anything)
));
}
DynamicByteBuffer ReadRemoteSupportedFeaturesPacket(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kReadRemoteSupportedFeatures), UpperBits(hci::kReadRemoteSupportedFeatures),
0x02, // parameter_total_size (2 bytes)
LowerBits(conn), // Little-Endian Connection_handle
UpperBits(conn)));
}
DynamicByteBuffer ReadRemoteSupportedFeaturesCompletePacket(hci::ConnectionHandle conn,
bool extended_features) {
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kReadRemoteSupportedFeaturesCompleteEventCode,
0x0B, // parameter_total_size (11 bytes)
hci::StatusCode::kSuccess, // status
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
0xFF, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, (extended_features ? 0x80 : 0x00)
// lmp_features
// Set: 3 slot packets, 5 slot packets, Encryption, Timing Accuracy,
// Role Switch, Hold Mode, Sniff Mode, LE Supported
// Extended Features if enabled
));
}
DynamicByteBuffer LEReadRemoteFeaturesPacket(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kLEReadRemoteFeatures), UpperBits(hci::kLEReadRemoteFeatures),
0x02, // parameter_total_size (2 bytes)
LowerBits(conn), // Little-Endian Connection_handle
UpperBits(conn)));
}
DynamicByteBuffer LEReadRemoteFeaturesCompletePacket(hci::ConnectionHandle conn,
hci::LESupportedFeatures le_features) {
const BufferView features(&le_features, sizeof(le_features));
return DynamicByteBuffer(StaticByteBuffer(hci::kLEMetaEventCode,
0x0c, // parameter total size (12 bytes)
hci::kLEReadRemoteFeaturesCompleteSubeventCode,
hci::StatusCode::kSuccess, // status
// Little-Endian connection handle
LowerBits(conn), UpperBits(conn),
// bit mask of LE features
features[0], features[1], features[2], features[3],
features[4], features[5], features[6], features[7]));
}
DynamicByteBuffer ReadRemoteExtended1Packet(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kReadRemoteExtendedFeatures), UpperBits(hci::kReadRemoteExtendedFeatures),
0x03, // parameter_total_size (3 bytes)
LowerBits(conn), // Little-Endian Connection_handle
UpperBits(conn),
0x01 // page_number (1)
));
}
DynamicByteBuffer ReadRemoteExtended1CompletePacket(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kReadRemoteExtendedFeaturesCompleteEventCode,
0x0D, // parameter_total_size (13 bytes)
hci::StatusCode::kSuccess, // status
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
0x01, // page_number
0x03, // max_page_number (3 pages)
0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
// lmp_features (page 1)
// Set: Secure Simple Pairing (Host Support), LE Supported (Host),
// SimultaneousLEAndBREDR, Secure Connections (Host Support)
));
}
DynamicByteBuffer ReadRemoteExtended2Packet(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
LowerBits(hci::kReadRemoteExtendedFeatures), UpperBits(hci::kReadRemoteExtendedFeatures),
0x03, // parameter_total_size (3 bytes)
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
0x02 // page_number (2)
));
}
DynamicByteBuffer ReadRemoteExtended2CompletePacket(hci::ConnectionHandle conn) {
return DynamicByteBuffer(CreateStaticByteBuffer(
hci::kReadRemoteExtendedFeaturesCompleteEventCode,
0x0D, // parameter_total_size (13 bytes)
hci::StatusCode::kSuccess, // status
LowerBits(conn), UpperBits(conn), // Little-Endian Connection_handle
0x02, // page_number
0x03, // max_page_number (3 pages)
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xFF, 0x00
// lmp_features - All the bits should be ignored.
));
}
} // namespace testing
} // namespace bt