blob: 95bb2029e1b68bd7c3ded962252b508fed6e3f06 [file] [log] [blame]
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dual_mode_controller.h"
#include <memory>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/values.h>
#include "os/log.h"
#include "packet/raw_builder.h"
using bluetooth::hci::ErrorCode;
using bluetooth::hci::LoopbackMode;
using bluetooth::hci::OpCode;
using std::vector;
namespace {
size_t LastNonZero(bluetooth::packet::PacketView<true> view) {
for (size_t i = view.size() - 1; i > 0; i--) {
if (view[i] != 0) {
return i;
}
}
return 0;
}
} // namespace
namespace test_vendor_lib {
constexpr char DualModeController::kControllerPropertiesFile[];
constexpr uint16_t DualModeController::kSecurityManagerNumKeys;
constexpr uint16_t kNumCommandPackets = 0x01;
// Device methods.
void DualModeController::Initialize(const std::vector<std::string>& args) {
if (args.size() < 2) return;
Address addr;
if (Address::FromString(args[1], addr)) {
properties_.SetAddress(addr);
} else {
LOG_ALWAYS_FATAL("Invalid address: %s", args[1].c_str());
}
};
std::string DualModeController::GetTypeString() const {
return "Simulated Bluetooth Controller";
}
void DualModeController::IncomingPacket(
model::packets::LinkLayerPacketView incoming) {
link_layer_controller_.IncomingPacket(incoming);
}
void DualModeController::TimerTick() {
link_layer_controller_.TimerTick();
}
void DualModeController::SendCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode) const {
std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
std::make_unique<bluetooth::packet::RawBuilder>();
raw_builder_ptr->AddOctets1(kNumCommandPackets);
raw_builder_ptr->AddOctets2(command_opcode);
raw_builder_ptr->AddOctets1(
static_cast<uint8_t>(ErrorCode::UNKNOWN_HCI_COMMAND));
auto packet = bluetooth::hci::EventPacketBuilder::Create(
bluetooth::hci::EventCode::COMMAND_COMPLETE, std::move(raw_builder_ptr));
send_event_(std::move(packet));
}
DualModeController::DualModeController(const std::string& properties_filename, uint16_t num_keys)
: Device(properties_filename), security_manager_(num_keys) {
loopback_mode_ = LoopbackMode::NO_LOOPBACK;
Address public_address;
ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address));
properties_.SetAddress(public_address);
link_layer_controller_.RegisterRemoteChannel(
[this](std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet,
Phy::Type phy_type) {
DualModeController::SendLinkLayerPacket(packet, phy_type);
});
#define SET_HANDLER(opcode, method) \
active_hci_commands_[static_cast<uint16_t>(opcode)] = \
[this](PacketView<true> param) { method(param); };
SET_HANDLER(OpCode::RESET, HciReset);
SET_HANDLER(OpCode::READ_BUFFER_SIZE, HciReadBufferSize);
SET_HANDLER(OpCode::HOST_BUFFER_SIZE, HciHostBufferSize);
SET_HANDLER(OpCode::SNIFF_SUBRATING, HciSniffSubrating);
SET_HANDLER(OpCode::READ_ENCRYPTION_KEY_SIZE, HciReadEncryptionKeySize);
SET_HANDLER(OpCode::READ_LOCAL_VERSION_INFORMATION, HciReadLocalVersionInformation);
SET_HANDLER(OpCode::READ_BD_ADDR, HciReadBdAddr);
SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_COMMANDS, HciReadLocalSupportedCommands);
SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_FEATURES, HciReadLocalSupportedFeatures);
SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_CODECS, HciReadLocalSupportedCodecs);
SET_HANDLER(OpCode::READ_LOCAL_EXTENDED_FEATURES, HciReadLocalExtendedFeatures);
SET_HANDLER(OpCode::READ_REMOTE_EXTENDED_FEATURES, HciReadRemoteExtendedFeatures);
SET_HANDLER(OpCode::SWITCH_ROLE, HciSwitchRole);
SET_HANDLER(OpCode::READ_REMOTE_SUPPORTED_FEATURES, HciReadRemoteSupportedFeatures);
SET_HANDLER(OpCode::READ_CLOCK_OFFSET, HciReadClockOffset);
SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_REPLY, HciIoCapabilityRequestReply);
SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_REPLY, HciUserConfirmationRequestReply);
SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, HciUserConfirmationRequestNegativeReply);
SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, HciIoCapabilityRequestNegativeReply);
SET_HANDLER(OpCode::WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
SET_HANDLER(OpCode::WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
SET_HANDLER(OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
HciWriteSecureConnectionsHostSupport);
SET_HANDLER(OpCode::SET_EVENT_MASK, HciSetEventMask);
SET_HANDLER(OpCode::WRITE_INQUIRY_MODE, HciWriteInquiryMode);
SET_HANDLER(OpCode::WRITE_PAGE_SCAN_TYPE, HciWritePageScanType);
SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_TYPE, HciWriteInquiryScanType);
SET_HANDLER(OpCode::AUTHENTICATION_REQUESTED, HciAuthenticationRequested);
SET_HANDLER(OpCode::SET_CONNECTION_ENCRYPTION, HciSetConnectionEncryption);
SET_HANDLER(OpCode::CHANGE_CONNECTION_LINK_KEY, HciChangeConnectionLinkKey);
SET_HANDLER(OpCode::MASTER_LINK_KEY, HciMasterLinkKey);
SET_HANDLER(OpCode::WRITE_AUTHENTICATION_ENABLE, HciWriteAuthenticationEnable);
SET_HANDLER(OpCode::READ_AUTHENTICATION_ENABLE, HciReadAuthenticationEnable);
SET_HANDLER(OpCode::WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice);
SET_HANDLER(OpCode::WRITE_PAGE_TIMEOUT, HciWritePageTimeout);
SET_HANDLER(OpCode::WRITE_LINK_SUPERVISION_TIMEOUT, HciWriteLinkSupervisionTimeout);
SET_HANDLER(OpCode::HOLD_MODE, HciHoldMode);
SET_HANDLER(OpCode::SNIFF_MODE, HciSniffMode);
SET_HANDLER(OpCode::EXIT_SNIFF_MODE, HciExitSniffMode);
SET_HANDLER(OpCode::QOS_SETUP, HciQosSetup);
SET_HANDLER(OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings);
SET_HANDLER(OpCode::FLOW_SPECIFICATION, HciFlowSpecification);
SET_HANDLER(OpCode::WRITE_LINK_POLICY_SETTINGS, HciWriteLinkPolicySettings);
SET_HANDLER(OpCode::CHANGE_CONNECTION_PACKET_TYPE, HciChangeConnectionPacketType);
SET_HANDLER(OpCode::WRITE_LOCAL_NAME, HciWriteLocalName);
SET_HANDLER(OpCode::READ_LOCAL_NAME, HciReadLocalName);
SET_HANDLER(OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE, HciWriteExtendedInquiryResponse);
SET_HANDLER(OpCode::REFRESH_ENCRYPTION_KEY, HciRefreshEncryptionKey);
SET_HANDLER(OpCode::WRITE_VOICE_SETTING, HciWriteVoiceSetting);
SET_HANDLER(OpCode::WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap);
SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_ACTIVITY, HciWriteInquiryScanActivity);
SET_HANDLER(OpCode::WRITE_SCAN_ENABLE, HciWriteScanEnable);
SET_HANDLER(OpCode::SET_EVENT_FILTER, HciSetEventFilter);
SET_HANDLER(OpCode::INQUIRY, HciInquiry);
SET_HANDLER(OpCode::INQUIRY_CANCEL, HciInquiryCancel);
SET_HANDLER(OpCode::ACCEPT_CONNECTION_REQUEST, HciAcceptConnectionRequest);
SET_HANDLER(OpCode::REJECT_CONNECTION_REQUEST, HciRejectConnectionRequest);
SET_HANDLER(OpCode::LINK_KEY_REQUEST_REPLY, HciLinkKeyRequestReply);
SET_HANDLER(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, HciLinkKeyRequestNegativeReply);
SET_HANDLER(OpCode::DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey);
SET_HANDLER(OpCode::REMOTE_NAME_REQUEST, HciRemoteNameRequest);
SET_HANDLER(OpCode::LE_SET_EVENT_MASK, HciLeSetEventMask);
SET_HANDLER(OpCode::LE_READ_BUFFER_SIZE, HciLeReadBufferSize);
SET_HANDLER(OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES, HciLeReadLocalSupportedFeatures);
SET_HANDLER(OpCode::LE_SET_RANDOM_ADDRESS, HciLeSetRandomAddress);
SET_HANDLER(OpCode::LE_SET_ADVERTISING_PARAMETERS, HciLeSetAdvertisingParameters);
SET_HANDLER(OpCode::LE_SET_ADVERTISING_DATA, HciLeSetAdvertisingData);
SET_HANDLER(OpCode::LE_SET_SCAN_RESPONSE_DATA, HciLeSetScanResponseData);
SET_HANDLER(OpCode::LE_SET_ADVERTISING_ENABLE, HciLeSetAdvertisingEnable);
SET_HANDLER(OpCode::LE_SET_SCAN_PARAMETERS, HciLeSetScanParameters);
SET_HANDLER(OpCode::LE_SET_SCAN_ENABLE, HciLeSetScanEnable);
SET_HANDLER(OpCode::LE_CREATE_CONNECTION, HciLeCreateConnection);
SET_HANDLER(OpCode::CREATE_CONNECTION, HciCreateConnection);
SET_HANDLER(OpCode::DISCONNECT, HciDisconnect);
SET_HANDLER(OpCode::LE_CREATE_CONNECTION_CANCEL, HciLeConnectionCancel);
SET_HANDLER(OpCode::LE_READ_WHITE_LIST_SIZE, HciLeReadWhiteListSize);
SET_HANDLER(OpCode::LE_CLEAR_WHITE_LIST, HciLeClearWhiteList);
SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_WHITE_LIST, HciLeAddDeviceToWhiteList);
SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_WHITE_LIST, HciLeRemoveDeviceFromWhiteList);
SET_HANDLER(OpCode::LE_RAND, HciLeRand);
SET_HANDLER(OpCode::LE_READ_SUPPORTED_STATES, HciLeReadSupportedStates);
SET_HANDLER(OpCode::LE_GET_VENDOR_CAPABILITIES, HciLeVendorCap);
SET_HANDLER(OpCode::LE_MULTI_ADVT, HciLeVendorMultiAdv);
SET_HANDLER(OpCode::LE_ADV_FILTER, HciLeAdvertisingFilter);
SET_HANDLER(OpCode::LE_ENERGY_INFO, HciLeEnergyInfo);
SET_HANDLER(OpCode::LE_EXTENDED_SCAN_PARAMS, HciLeExtendedScanParams);
SET_HANDLER(OpCode::LE_READ_REMOTE_FEATURES, HciLeReadRemoteFeatures);
SET_HANDLER(OpCode::READ_REMOTE_VERSION_INFORMATION, HciReadRemoteVersionInformation);
SET_HANDLER(OpCode::LE_CONNECTION_UPDATE, HciLeConnectionUpdate);
SET_HANDLER(OpCode::LE_START_ENCRYPTION, HciLeStartEncryption);
SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
HciLeAddDeviceToResolvingList);
SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST,
HciLeRemoveDeviceFromResolvingList);
SET_HANDLER(OpCode::LE_CLEAR_RESOLVING_LIST, HciLeClearResolvingList);
SET_HANDLER(OpCode::LE_SET_PRIVACY_MODE, HciLeSetPrivacyMode);
// Testing Commands
SET_HANDLER(OpCode::READ_LOOPBACK_MODE, HciReadLoopbackMode);
SET_HANDLER(OpCode::WRITE_LOOPBACK_MODE, HciWriteLoopbackMode);
#undef SET_HANDLER
}
void DualModeController::HciSniffSubrating(PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto packet = bluetooth::hci::SniffSubratingCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, handle);
send_event_(std::move(packet));
}
void DualModeController::RegisterTaskScheduler(
std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> oneshot_scheduler) {
link_layer_controller_.RegisterTaskScheduler(oneshot_scheduler);
}
void DualModeController::RegisterPeriodicTaskScheduler(
std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
periodic_scheduler) {
link_layer_controller_.RegisterPeriodicTaskScheduler(periodic_scheduler);
}
void DualModeController::RegisterTaskCancel(std::function<void(AsyncTaskId)> task_cancel) {
link_layer_controller_.RegisterTaskCancel(task_cancel);
}
void DualModeController::HandleAcl(std::shared_ptr<std::vector<uint8_t>> packet) {
bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
auto acl_packet = bluetooth::hci::AclPacketView::Create(raw_packet);
ASSERT(acl_packet.IsValid());
if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
uint16_t handle = acl_packet.GetHandle();
std::vector<bluetooth::hci::CompletedPackets> completed_packets;
bluetooth::hci::CompletedPackets cp;
cp.connection_handle_ = handle;
cp.host_num_of_completed_packets_ = kNumCommandPackets;
completed_packets.push_back(cp);
auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
completed_packets);
send_event_(std::move(packet));
return;
}
link_layer_controller_.SendAclToRemote(acl_packet);
}
void DualModeController::HandleSco(std::shared_ptr<std::vector<uint8_t>> packet) {
bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
auto sco_packet = bluetooth::hci::ScoPacketView::Create(raw_packet);
if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
uint16_t handle = sco_packet.GetHandle();
send_sco_(packet);
std::vector<bluetooth::hci::CompletedPackets> completed_packets;
bluetooth::hci::CompletedPackets cp;
cp.connection_handle_ = handle;
cp.host_num_of_completed_packets_ = kNumCommandPackets;
completed_packets.push_back(cp);
auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
completed_packets);
send_event_(std::move(packet));
return;
}
}
void DualModeController::HandleIso(
std::shared_ptr<std::vector<uint8_t>> /* packet */) {
// TODO: implement handling similar to HandleSco
}
void DualModeController::HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet) {
bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
auto command_packet = bluetooth::hci::CommandPacketView::Create(raw_packet);
ASSERT(command_packet.IsValid());
auto op = command_packet.GetOpCode();
uint16_t opcode = static_cast<uint16_t>(op);
if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL &&
// Loopback exceptions.
op != OpCode::RESET &&
op != OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL &&
op != OpCode::HOST_BUFFER_SIZE &&
op != OpCode::HOST_NUM_COMPLETED_PACKETS &&
op != OpCode::READ_BUFFER_SIZE && op != OpCode::READ_LOOPBACK_MODE &&
op != OpCode::WRITE_LOOPBACK_MODE) {
std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
std::make_unique<bluetooth::packet::RawBuilder>();
raw_builder_ptr->AddOctets(*packet);
auto packet = bluetooth::hci::LoopbackCommandBuilder::Create(
std::move(raw_builder_ptr));
send_event_(std::move(packet));
} else if (active_hci_commands_.count(opcode) > 0) {
active_hci_commands_[opcode](command_packet.GetPayload());
} else {
SendCommandCompleteUnknownOpCodeEvent(opcode);
LOG_INFO("Unknown command, opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X",
opcode, (opcode & 0xFC00) >> 10, opcode & 0x03FF);
}
}
void DualModeController::RegisterEventChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
send_event_ =
[callback](std::shared_ptr<bluetooth::hci::EventPacketBuilder> event) {
auto bytes = std::make_shared<std::vector<uint8_t>>();
bluetooth::packet::BitInserter bit_inserter(*bytes);
bytes->reserve(event->size());
event->Serialize(bit_inserter);
callback(std::move(bytes));
};
link_layer_controller_.RegisterEventChannel(send_event_);
}
void DualModeController::RegisterAclChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
send_acl_ =
[callback](std::shared_ptr<bluetooth::hci::AclPacketBuilder> acl_data) {
auto bytes = std::make_shared<std::vector<uint8_t>>();
bluetooth::packet::BitInserter bit_inserter(*bytes);
bytes->reserve(acl_data->size());
acl_data->Serialize(bit_inserter);
callback(std::move(bytes));
};
link_layer_controller_.RegisterAclChannel(send_acl_);
}
void DualModeController::RegisterScoChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
link_layer_controller_.RegisterScoChannel(callback);
send_sco_ = callback;
}
void DualModeController::RegisterIsoChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
callback) {
link_layer_controller_.RegisterIsoChannel(callback);
send_iso_ = callback;
}
void DualModeController::HciReset(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.Reset();
if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
loopback_mode_ = LoopbackMode::NO_LOOPBACK;
}
send_event_(bluetooth::hci::ResetCompleteBuilder::Create(kNumCommandPackets,
ErrorCode::SUCCESS));
}
void DualModeController::HciReadBufferSize(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadBufferSizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetAclDataPacketSize(),
properties_.GetSynchronousDataPacketSize(),
properties_.GetTotalNumAclDataPackets(),
properties_.GetTotalNumSynchronousDataPackets());
send_event_(std::move(packet));
}
void DualModeController::HciReadEncryptionKeySize(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto packet = bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, handle,
properties_.GetEncryptionKeySize());
send_event_(std::move(packet));
}
void DualModeController::HciHostBufferSize(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::HostBufferSizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciReadLocalVersionInformation(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
bluetooth::hci::LocalVersionInformation local_version_information;
local_version_information.hci_version_ =
static_cast<bluetooth::hci::HciVersion>(properties_.GetVersion());
local_version_information.hci_revision_ = properties_.GetRevision();
local_version_information.lmp_version_ =
static_cast<bluetooth::hci::LmpVersion>(properties_.GetLmpPalVersion());
local_version_information.manufacturer_name_ =
properties_.GetManufacturerName();
local_version_information.lmp_subversion_ = properties_.GetLmpPalSubversion();
auto packet =
bluetooth::hci::ReadLocalVersionInformationCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, local_version_information);
send_event_(std::move(packet));
}
void DualModeController::HciReadRemoteVersionInformation(
PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_REMOTE_VERSION_INFORMATION, args, handle);
auto packet =
bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciReadBdAddr(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetAddress());
send_event_(std::move(packet));
}
void DualModeController::HciReadLocalSupportedCommands(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
std::array<uint8_t, 64> supported_commands;
supported_commands.fill(0x00);
size_t len = properties_.GetSupportedCommands().size();
if (len > 64) {
len = 64;
}
std::copy_n(properties_.GetSupportedCommands().begin(), len,
supported_commands.begin());
auto packet =
bluetooth::hci::ReadLocalSupportedCommandsCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, supported_commands);
send_event_(std::move(packet));
}
void DualModeController::HciReadLocalSupportedFeatures(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet =
bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetSupportedFeatures());
send_event_(std::move(packet));
}
void DualModeController::HciReadLocalSupportedCodecs(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadLocalSupportedCodecsCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetSupportedCodecs(),
properties_.GetVendorSpecificCodecs());
send_event_(std::move(packet));
}
void DualModeController::HciReadLocalExtendedFeatures(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
uint8_t page_number = args.begin().extract<uint8_t>();
auto pakcet =
bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, page_number,
properties_.GetExtendedFeaturesMaximumPageNumber(),
properties_.GetExtendedFeatures(page_number));
send_event_(std::move(pakcet));
}
void DualModeController::HciReadRemoteExtendedFeatures(PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_REMOTE_EXTENDED_FEATURES, args, handle);
auto packet = bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciSwitchRole(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Address address = args.begin().extract<Address>();
uint8_t role = args.begin().extract<uint8_t>();
auto status = link_layer_controller_.SwitchRole(address, role);
auto packet = bluetooth::hci::SwitchRoleStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciReadRemoteSupportedFeatures(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_REMOTE_SUPPORTED_FEATURES, args, handle);
auto packet =
bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciReadClockOffset(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_CLOCK_OFFSET, args, handle);
auto packet = bluetooth::hci::ReadClockOffsetStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciIoCapabilityRequestReply(PacketView<true> args) {
ASSERT_LOG(args.size() == 9, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address peer = args_itr.extract<Address>();
uint8_t io_capability = args_itr.extract<uint8_t>();
uint8_t oob_data_present_flag = args_itr.extract<uint8_t>();
uint8_t authentication_requirements = args_itr.extract<uint8_t>();
auto status = link_layer_controller_.IoCapabilityRequestReply(
peer, io_capability, oob_data_present_flag, authentication_requirements);
auto packet = bluetooth::hci::IoCapabilityRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciUserConfirmationRequestReply(
PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
auto status = link_layer_controller_.UserConfirmationRequestReply(peer);
auto packet =
bluetooth::hci::UserConfirmationRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciUserConfirmationRequestNegativeReply(
PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
auto status =
link_layer_controller_.UserConfirmationRequestNegativeReply(peer);
auto packet =
bluetooth::hci::UserConfirmationRequestNegativeReplyCompleteBuilder::
Create(kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciUserPasskeyRequestReply(PacketView<true> args) {
ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address peer = args_itr.extract<Address>();
uint32_t numeric_value = args_itr.extract<uint32_t>();
auto status =
link_layer_controller_.UserPasskeyRequestReply(peer, numeric_value);
auto packet = bluetooth::hci::UserPasskeyRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciUserPasskeyRequestNegativeReply(
PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
auto status = link_layer_controller_.UserPasskeyRequestNegativeReply(peer);
auto packet =
bluetooth::hci::UserPasskeyRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciRemoteOobDataRequestReply(PacketView<true> args) {
ASSERT_LOG(args.size() == 38, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address peer = args_itr.extract<Address>();
std::vector<uint8_t> c;
std::vector<uint8_t> r;
for (size_t i = 0; i < 16; i++) {
c.push_back(args_itr.extract<uint8_t>());
}
for (size_t i = 0; i < 16; i++) {
r.push_back(args_itr.extract<uint8_t>());
}
auto status = link_layer_controller_.RemoteOobDataRequestReply(peer, c, r);
auto packet =
bluetooth::hci::RemoteOobDataRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciRemoteOobDataRequestNegativeReply(
PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
auto status = link_layer_controller_.RemoteOobDataRequestNegativeReply(peer);
auto packet =
bluetooth::hci::RemoteOobDataRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciIoCapabilityRequestNegativeReply(
PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address peer = args_itr.extract<Address>();
ErrorCode reason = args_itr.extract<ErrorCode>();
auto status =
link_layer_controller_.IoCapabilityRequestNegativeReply(peer, reason);
auto packet =
bluetooth::hci::IoCapabilityRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::HciWriteSimplePairingMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
ASSERT(args[0] == 1 || args[0] == 0);
link_layer_controller_.WriteSimplePairingMode(args[0] == 1);
auto packet = bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciChangeConnectionPacketType(PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
uint16_t packet_type = args_itr.extract<uint16_t>();
auto status =
link_layer_controller_.ChangeConnectionPacketType(handle, packet_type);
auto packet = bluetooth::hci::ChangeConnectionPacketTypeStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciWriteLeHostSupport(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWriteSecureConnectionsHostSupport(
PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
properties_.SetExtendedFeatures(properties_.GetExtendedFeatures(1) | 0x8, 1);
auto packet =
bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciSetEventMask(PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::SetEventMaskCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWriteInquiryMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetInquiryMode(args[0]);
auto packet = bluetooth::hci::WriteInquiryModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWritePageScanType(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::WritePageScanTypeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWriteInquiryScanType(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciAuthenticationRequested(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto status = link_layer_controller_.AuthenticationRequested(handle);
auto packet = bluetooth::hci::AuthenticationRequestedStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciSetConnectionEncryption(PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
uint8_t encryption_enable = args_itr.extract<uint8_t>();
auto status =
link_layer_controller_.SetConnectionEncryption(handle, encryption_enable);
auto packet = bluetooth::hci::SetConnectionEncryptionStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciChangeConnectionLinkKey(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
auto status = link_layer_controller_.ChangeConnectionLinkKey(handle);
auto packet = bluetooth::hci::ChangeConnectionLinkKeyStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciMasterLinkKey(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint8_t key_flag = args_itr.extract<uint8_t>();
auto status = link_layer_controller_.MasterLinkKey(key_flag);
auto packet = bluetooth::hci::MasterLinkKeyStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciWriteAuthenticationEnable(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
properties_.SetAuthenticationEnable(args[0]);
auto packet =
bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciReadAuthenticationEnable(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
static_cast<bluetooth::hci::AuthenticationEnable>(
properties_.GetAuthenticationEnable()));
send_event_(std::move(packet));
}
void DualModeController::HciWriteClassOfDevice(PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
properties_.SetClassOfDevice(args[0], args[1], args[2]);
auto packet = bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWritePageTimeout(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::WritePageTimeoutCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciHoldMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
uint16_t hold_mode_max_interval = args_itr.extract<uint16_t>();
uint16_t hold_mode_min_interval = args_itr.extract<uint16_t>();
auto status = link_layer_controller_.HoldMode(handle, hold_mode_max_interval,
hold_mode_min_interval);
auto packet =
bluetooth::hci::HoldModeStatusBuilder::Create(status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciSniffMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
uint16_t sniff_max_interval = args_itr.extract<uint16_t>();
uint16_t sniff_min_interval = args_itr.extract<uint16_t>();
uint16_t sniff_attempt = args_itr.extract<uint16_t>();
uint16_t sniff_timeout = args_itr.extract<uint16_t>();
auto status = link_layer_controller_.SniffMode(handle, sniff_max_interval,
sniff_min_interval,
sniff_attempt, sniff_timeout);
auto packet = bluetooth::hci::SniffModeStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciExitSniffMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
auto status = link_layer_controller_.ExitSniffMode(handle);
auto packet = bluetooth::hci::ExitSniffModeStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciQosSetup(PacketView<true> args) {
ASSERT_LOG(args.size() == 20, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
args_itr.extract<uint8_t>(); // unused
uint8_t service_type = args_itr.extract<uint8_t>();
uint32_t token_rate = args_itr.extract<uint32_t>();
uint32_t peak_bandwidth = args_itr.extract<uint32_t>();
uint32_t latency = args_itr.extract<uint32_t>();
uint32_t delay_variation = args_itr.extract<uint32_t>();
auto status =
link_layer_controller_.QosSetup(handle, service_type, token_rate,
peak_bandwidth, latency, delay_variation);
auto packet =
bluetooth::hci::QosSetupStatusBuilder::Create(status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciWriteDefaultLinkPolicySettings(
PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto packet =
bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciFlowSpecification(PacketView<true> args) {
ASSERT_LOG(args.size() == 21, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
args_itr.extract<uint8_t>(); // unused
uint8_t flow_direction = args_itr.extract<uint8_t>();
uint8_t service_type = args_itr.extract<uint8_t>();
uint32_t token_rate = args_itr.extract<uint32_t>();
uint32_t token_bucket_size = args_itr.extract<uint32_t>();
uint32_t peak_bandwidth = args_itr.extract<uint32_t>();
uint32_t access_latency = args_itr.extract<uint32_t>();
auto status = link_layer_controller_.FlowSpecification(
handle, flow_direction, service_type, token_rate, token_bucket_size,
peak_bandwidth, access_latency);
auto packet = bluetooth::hci::FlowSpecificationStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciWriteLinkPolicySettings(PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
uint16_t settings = args_itr.extract<uint16_t>();
auto status =
link_layer_controller_.WriteLinkPolicySettings(handle, settings);
auto packet = bluetooth::hci::WriteLinkPolicySettingsCompleteBuilder::Create(
kNumCommandPackets, status, handle);
send_event_(std::move(packet));
}
void DualModeController::HciWriteLinkSupervisionTimeout(PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
uint16_t timeout = args_itr.extract<uint16_t>();
auto status =
link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout);
auto packet =
bluetooth::hci::WriteLinkSupervisionTimeoutCompleteBuilder::Create(
kNumCommandPackets, status, handle);
send_event_(std::move(packet));
}
void DualModeController::HciReadLocalName(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
std::array<uint8_t, 248> local_name;
local_name.fill(0x00);
size_t len = properties_.GetName().size();
if (len > 247) {
len = 247; // one byte for NULL octet (0x00)
}
std::copy_n(properties_.GetName().begin(), len, local_name.begin());
auto packet = bluetooth::hci::ReadLocalNameCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, local_name);
send_event_(std::move(packet));
}
void DualModeController::HciWriteLocalName(PacketView<true> args) {
ASSERT_LOG(args.size() == 248, "%s size=%zu", __func__, args.size());
std::vector<uint8_t> clipped(args.begin(), args.begin() + LastNonZero(args) + 1);
properties_.SetName(clipped);
auto packet = bluetooth::hci::WriteLocalNameCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWriteExtendedInquiryResponse(
PacketView<true> args) {
ASSERT_LOG(args.size() == 241, "%s size=%zu", __func__, args.size());
// Strip FEC byte and trailing zeros
std::vector<uint8_t> clipped(args.begin() + 1, args.begin() + LastNonZero(args) + 1);
properties_.SetExtendedInquiryData(clipped);
auto packet =
bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciRefreshEncryptionKey(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
auto status_packet =
bluetooth::hci::RefreshEncryptionKeyStatusBuilder::Create(
ErrorCode::SUCCESS, kNumCommandPackets);
send_event_(std::move(status_packet));
// TODO: Support this in the link layer
auto complete_packet =
bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
ErrorCode::SUCCESS, handle);
send_event_(std::move(complete_packet));
}
void DualModeController::HciWriteVoiceSetting(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWriteCurrentIacLap(PacketView<true> args) {
ASSERT(args.size() > 0);
ASSERT(args.size() == 1 + (3 * args[0])); // count + 3-byte IACs
auto packet = bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWriteInquiryScanActivity(PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciWriteScanEnable(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetInquiryScanEnable(args[0] & 0x1);
link_layer_controller_.SetPageScanEnable(args[0] & 0x2);
auto packet = bluetooth::hci::WriteScanEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciSetEventFilter(PacketView<true> args) {
ASSERT(args.size() > 0);
auto packet = bluetooth::hci::SetEventFilterCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciInquiry(PacketView<true> args) {
ASSERT_LOG(args.size() == 5, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetInquiryLAP(args[0] | (args[1], 8) | (args[2], 16));
link_layer_controller_.SetInquiryMaxResponses(args[4]);
link_layer_controller_.StartInquiry(std::chrono::milliseconds(args[3] * 1280));
auto packet = bluetooth::hci::InquiryStatusBuilder::Create(
ErrorCode::SUCCESS, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciInquiryCancel(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.InquiryCancel();
auto packet = bluetooth::hci::InquiryCancelCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciAcceptConnectionRequest(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Address addr = args.begin().extract<Address>();
bool try_role_switch = args[6] == 0;
auto status =
link_layer_controller_.AcceptConnectionRequest(addr, try_role_switch);
auto packet = bluetooth::hci::AcceptConnectionRequestStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciRejectConnectionRequest(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address addr = args_itr.extract<Address>();
uint8_t reason = args_itr.extract<uint8_t>();
auto status = link_layer_controller_.RejectConnectionRequest(addr, reason);
auto packet = bluetooth::hci::RejectConnectionRequestStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciLinkKeyRequestReply(PacketView<true> args) {
ASSERT_LOG(args.size() == 22, "%s size=%zu", __func__, args.size());
auto args_it = args.begin();
Address addr = args_it.extract<Address>();
auto key = args.begin().extract<std::array<uint8_t, 16>>();
auto status = link_layer_controller_.LinkKeyRequestReply(addr, key);
auto packet = bluetooth::hci::LinkKeyRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status);
send_event_(std::move(packet));
}
void DualModeController::HciLinkKeyRequestNegativeReply(PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address addr = args.begin().extract<Address>();
auto status = link_layer_controller_.LinkKeyRequestNegativeReply(addr);
auto packet =
bluetooth::hci::LinkKeyRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, addr);
send_event_(std::move(packet));
}
void DualModeController::HciDeleteStoredLinkKey(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
uint16_t deleted_keys = 0;
if (args[6] == 0) {
Address addr = args.begin().extract<Address>();
deleted_keys = security_manager_.DeleteKey(addr);
}
if (args[6] == 1) {
security_manager_.DeleteAllKeys();
}
auto packet = bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, deleted_keys);
send_event_(std::move(packet));
}
void DualModeController::HciRemoteNameRequest(PacketView<true> args) {
ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
Address remote_addr = args.begin().extract<Address>();
auto status = link_layer_controller_.SendCommandToRemoteByAddress(
OpCode::REMOTE_NAME_REQUEST, args, remote_addr);
auto packet = bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetEventMask(PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
/*
uint64_t mask = args.begin().extract<uint64_t>();
link_layer_controller_.SetLeEventMask(mask);
*/
auto packet = bluetooth::hci::LeSetEventMaskCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeReadBufferSize(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
bluetooth::hci::LeBufferSize le_buffer_size;
le_buffer_size.le_data_packet_length_ = properties_.GetLeDataPacketLength();
le_buffer_size.total_num_le_packets_ = properties_.GetTotalNumLeDataPackets();
auto packet = bluetooth::hci::LeReadBufferSizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, le_buffer_size);
send_event_(std::move(packet));
}
void DualModeController::HciLeReadLocalSupportedFeatures(
PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet =
bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetLeSupportedFeatures());
send_event_(std::move(packet));
}
void DualModeController::HciLeSetRandomAddress(PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
properties_.SetLeAddress(args.begin().extract<Address>());
auto packet = bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetAdvertisingParameters(PacketView<true> args) {
ASSERT_LOG(args.size() == 15, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
properties_.SetLeAdvertisingParameters(
args_itr.extract<uint16_t>() /* AdverisingIntervalMin */,
args_itr.extract<uint16_t>() /* AdverisingIntervalMax */, args_itr.extract<uint8_t>() /* AdverisingType */,
args_itr.extract<uint8_t>() /* OwnAddressType */, args_itr.extract<uint8_t>() /* PeerAddressType */,
args_itr.extract<Address>() /* PeerAddress */, args_itr.extract<uint8_t>() /* AdvertisingChannelMap */,
args_itr.extract<uint8_t>() /* AdvertisingFilterPolicy */
);
auto packet =
bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetAdvertisingData(PacketView<true> args) {
ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size());
properties_.SetLeAdvertisement(std::vector<uint8_t>(args.begin() + 1, args.end()));
auto packet = bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetScanResponseData(PacketView<true> args) {
ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size());
properties_.SetLeScanResponse(std::vector<uint8_t>(args.begin() + 1, args.end()));
auto packet = bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetAdvertisingEnable(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
auto status = link_layer_controller_.SetLeAdvertisingEnable(
args.begin().extract<uint8_t>());
auto packet = bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
kNumCommandPackets, status);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetScanParameters(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetLeScanType(args[0]);
link_layer_controller_.SetLeScanInterval(args[1] | (args[2], 8));
link_layer_controller_.SetLeScanWindow(args[3] | (args[4], 8));
link_layer_controller_.SetLeAddressType(args[5]);
link_layer_controller_.SetLeScanFilterPolicy(args[6]);
auto packet = bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetScanEnable(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetLeScanEnable(args[0]);
link_layer_controller_.SetLeFilterDuplicates(args[1]);
auto packet = bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeCreateConnection(PacketView<true> args) {
ASSERT_LOG(args.size() == 25, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
link_layer_controller_.SetLeScanInterval(args_itr.extract<uint16_t>());
link_layer_controller_.SetLeScanWindow(args_itr.extract<uint16_t>());
uint8_t initiator_filter_policy = args_itr.extract<uint8_t>();
link_layer_controller_.SetLeInitiatorFilterPolicy(initiator_filter_policy);
if (initiator_filter_policy == 0) { // White list not used
uint8_t peer_address_type = args_itr.extract<uint8_t>();
Address peer_address = args_itr.extract<Address>();
link_layer_controller_.SetLePeerAddressType(peer_address_type);
link_layer_controller_.SetLePeerAddress(peer_address);
}
link_layer_controller_.SetLeAddressType(args_itr.extract<uint8_t>());
link_layer_controller_.SetLeConnectionIntervalMin(args_itr.extract<uint16_t>());
link_layer_controller_.SetLeConnectionIntervalMax(args_itr.extract<uint16_t>());
link_layer_controller_.SetLeConnectionLatency(args_itr.extract<uint16_t>());
link_layer_controller_.SetLeSupervisionTimeout(args_itr.extract<uint16_t>());
link_layer_controller_.SetLeMinimumCeLength(args_itr.extract<uint16_t>());
link_layer_controller_.SetLeMaximumCeLength(args_itr.extract<uint16_t>());
auto status = link_layer_controller_.SetLeConnect(true);
auto packet = bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciLeConnectionUpdate(PacketView<true> args) {
ASSERT_LOG(args.size() == 14, "%s size=%zu", __func__, args.size());
auto status_packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR, kNumCommandPackets);
send_event_(std::move(status_packet));
auto complete_packet =
bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
ErrorCode::SUCCESS, 0x0002, 0x0006, 0x0000, 0x01f4);
send_event_(std::move(complete_packet));
}
void DualModeController::HciCreateConnection(PacketView<true> args) {
ASSERT_LOG(args.size() == 13, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address address = args_itr.extract<Address>();
uint16_t packet_type = args_itr.extract<uint16_t>();
uint8_t page_scan_mode = args_itr.extract<uint8_t>();
uint16_t clock_offset = args_itr.extract<uint16_t>();
uint8_t allow_role_switch = args_itr.extract<uint8_t>();
auto status = link_layer_controller_.CreateConnection(
address, packet_type, page_scan_mode, clock_offset, allow_role_switch);
auto packet = bluetooth::hci::CreateConnectionStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciDisconnect(PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
uint8_t reason = args_itr.extract<uint8_t>();
auto status = link_layer_controller_.Disconnect(handle, reason);
auto packet = bluetooth::hci::DisconnectStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciLeConnectionCancel(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetLeConnect(false);
auto packet = bluetooth::hci::LeCreateConnectionCancelStatusBuilder::Create(
ErrorCode::SUCCESS, kNumCommandPackets);
send_event_(std::move(packet));
/* For testing Jakub's patch: Figure out a neat way to call this without
recompiling. I'm thinking about a bad device. */
/*
SendCommandCompleteOnlyStatus(OpCode::LE_CREATE_CONNECTION_CANCEL,
ErrorCode::COMMAND_DISALLOWED);
*/
}
void DualModeController::HciLeReadWhiteListSize(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::LeReadWhiteListSizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetLeWhiteListSize());
send_event_(std::move(packet));
}
void DualModeController::HciLeClearWhiteList(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.LeWhiteListClear();
auto packet = bluetooth::hci::LeClearWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeAddDeviceToWhiteList(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
if (link_layer_controller_.LeWhiteListFull()) {
auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::MEMORY_CAPACITY_EXCEEDED);
send_event_(std::move(packet));
return;
}
auto args_itr = args.begin();
uint8_t addr_type = args_itr.extract<uint8_t>();
Address address = args_itr.extract<Address>();
link_layer_controller_.LeWhiteListAddDevice(address, addr_type);
auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeRemoveDeviceFromWhiteList(PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint8_t addr_type = args_itr.extract<uint8_t>();
Address address = args_itr.extract<Address>();
link_layer_controller_.LeWhiteListRemoveDevice(address, addr_type);
auto packet =
bluetooth::hci::LeRemoveDeviceFromWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeClearResolvingList(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.LeResolvingListClear();
auto packet = bluetooth::hci::LeClearResolvingListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeAddDeviceToResolvingList(PacketView<true> args) {
ASSERT_LOG(args.size() == 39, "%s size=%zu", __func__, args.size());
if (link_layer_controller_.LeResolvingListFull()) {
auto packet =
bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::MEMORY_CAPACITY_EXCEEDED);
send_event_(std::move(packet));
return;
}
auto args_itr = args.begin();
uint8_t addr_type = args_itr.extract<uint8_t>();
Address address = args_itr.extract<Address>();
std::array<uint8_t, LinkLayerController::kIrk_size> peerIrk;
std::array<uint8_t, LinkLayerController::kIrk_size> localIrk;
for (size_t irk_ind = 0; irk_ind < LinkLayerController::kIrk_size;
irk_ind++) {
peerIrk[irk_ind] = args_itr.extract<uint8_t>();
}
for (size_t irk_ind = 0; irk_ind < LinkLayerController::kIrk_size;
irk_ind++) {
localIrk[irk_ind] = args_itr.extract<uint8_t>();
}
link_layer_controller_.LeResolvingListAddDevice(address, addr_type, peerIrk,
localIrk);
auto packet =
bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeRemoveDeviceFromResolvingList(
PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint8_t addr_type = args_itr.extract<uint8_t>();
Address address = args_itr.extract<Address>();
link_layer_controller_.LeResolvingListRemoveDevice(address, addr_type);
auto packet =
bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeSetPrivacyMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint8_t peer_identity_address_type = args_itr.extract<uint8_t>();
Address peer_identity_address = args_itr.extract<Address>();
uint8_t privacy_mode = args_itr.extract<uint8_t>();
if (link_layer_controller_.LeResolvingListContainsDevice(
peer_identity_address, peer_identity_address_type)) {
link_layer_controller_.LeSetPrivacyMode(
peer_identity_address_type, peer_identity_address, privacy_mode);
}
auto packet = bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HciLeReadRemoteFeatures(PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::LE_READ_REMOTE_FEATURES, args, handle);
auto packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::HciLeRand(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
uint64_t random_val = 0;
for (size_t rand_bytes = 0; rand_bytes < sizeof(uint64_t); rand_bytes += sizeof(RAND_MAX)) {
random_val = (random_val << (8 * sizeof(RAND_MAX))) | random();
}
auto packet = bluetooth::hci::LeRandCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, random_val);
send_event_(std::move(packet));
}
void DualModeController::HciLeReadSupportedStates(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetLeSupportedStates());
send_event_(std::move(packet));
}
void DualModeController::HciLeVendorCap(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
vector<uint8_t> caps = properties_.GetLeVendorCap();
if (caps.size() == 0) {
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_GET_VENDOR_CAPABILITIES));
return;
}
std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
std::make_unique<bluetooth::packet::RawBuilder>();
raw_builder_ptr->AddOctets1(static_cast<uint8_t>(ErrorCode::SUCCESS));
raw_builder_ptr->AddOctets(properties_.GetLeVendorCap());
auto packet = bluetooth::hci::CommandCompleteBuilder::Create(
kNumCommandPackets, OpCode::LE_GET_VENDOR_CAPABILITIES,
std::move(raw_builder_ptr));
send_event_(std::move(packet));
}
void DualModeController::HciLeVendorMultiAdv(PacketView<true> args) {
ASSERT(args.size() > 0);
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_MULTI_ADVT));
}
void DualModeController::HciLeAdvertisingFilter(PacketView<true> args) {
ASSERT(args.size() > 0);
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_ADV_FILTER));
}
void DualModeController::HciLeEnergyInfo(PacketView<true> args) {
ASSERT(args.size() > 0);
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_ENERGY_INFO));
}
void DualModeController::HciLeExtendedScanParams(PacketView<true> args) {
ASSERT(args.size() > 0);
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_EXTENDED_SCAN_PARAMS));
}
void DualModeController::HciLeStartEncryption(PacketView<true> args) {
ASSERT_LOG(args.size() == 28, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
// uint64_t random_number = args_itr.extract<uint64_t>();
// uint16_t encrypted_diversifier = args_itr.extract<uint16_t>();
// std::vector<uint8_t> long_term_key;
// for (size_t i = 0; i < 16; i++) {
// long_term_key.push_back(args_itr.extract<uint18_t>();
// }
auto status_packet = bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
ErrorCode::SUCCESS, kNumCommandPackets);
send_event_(std::move(status_packet));
auto complete_packet = bluetooth::hci::EncryptionChangeBuilder::Create(
ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::OFF);
send_event_(std::move(complete_packet));
#if 0
std::shared_ptr<packets::AclPacketBuilder> encryption_information =
std::make_shared<packets::AclPacketBuilder>(
0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
std::vector<uint8_t>({}));
encryption_information->AddPayloadOctets2(0x0011);
encryption_information->AddPayloadOctets2(0x0006);
encryption_information->AddPayloadOctets1(0x06);
encryption_information->AddPayloadOctets8(0x0706050403020100);
encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908);
send_acl_(encryption_information);
encryption_information = std::make_shared<packets::AclPacketBuilder>(
0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
std::vector<uint8_t>({}));
encryption_information->AddPayloadOctets2(0x000B);
encryption_information->AddPayloadOctets2(0x0006);
encryption_information->AddPayloadOctets1(0x07);
encryption_information->AddPayloadOctets2(0xBEEF);
encryption_information->AddPayloadOctets8(0x0706050403020100);
send_acl_(encryption_information);
encryption_information = std::make_shared<packets::AclPacketBuilder>(
0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
std::vector<uint8_t>({}));
encryption_information->AddPayloadOctets2(0x0011);
encryption_information->AddPayloadOctets2(0x0006);
encryption_information->AddPayloadOctets1(0x08);
encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908);
encryption_information->AddPayloadOctets8(0x0706050403020100);
send_acl_(encryption_information);
encryption_information = std::make_shared<packets::AclPacketBuilder>(
0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
std::vector<uint8_t>({}));
encryption_information->AddPayloadOctets2(0x0008);
encryption_information->AddPayloadOctets2(0x0006);
encryption_information->AddPayloadOctets1(0x09);
encryption_information->AddPayloadOctets1(0x01);
encryption_information->AddPayloadOctets6(0xDEADBEEFF00D);
send_acl_(encryption_information);
// send_event_(packets::EventPacketBuilder::CreateLeStartEncryption()->ToVector());
#endif
}
void DualModeController::HciReadLoopbackMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
static_cast<LoopbackMode>(loopback_mode_));
send_event_(std::move(packet));
}
void DualModeController::HciWriteLoopbackMode(PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
loopback_mode_ = static_cast<LoopbackMode>(args[0]);
// ACL channel
uint16_t acl_handle = 0x123;
auto packet_acl = bluetooth::hci::ConnectionCompleteBuilder::Create(
ErrorCode::SUCCESS, acl_handle, properties_.GetAddress(),
bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
send_event_(std::move(packet_acl));
// SCO channel
uint16_t sco_handle = 0x345;
auto packet_sco = bluetooth::hci::ConnectionCompleteBuilder::Create(
ErrorCode::SUCCESS, sco_handle, properties_.GetAddress(),
bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED);
send_event_(std::move(packet_sco));
auto packet = bluetooth::hci::WriteLoopbackModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::SetAddress(Address address) {
properties_.SetAddress(address);
}
} // namespace test_vendor_lib