blob: e9feca4806151af7c7632c41dcbef485360aec94 [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"
namespace gd_hci = ::bluetooth::hci;
using gd_hci::ErrorCode;
using gd_hci::LoopbackMode;
using gd_hci::OpCode;
using std::vector;
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 = gd_hci::EventPacketBuilder::Create(
gd_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_[opcode] = [this](CommandPacketView param) { \
method(param); \
};
SET_HANDLER(OpCode::RESET, Reset);
SET_HANDLER(OpCode::READ_BUFFER_SIZE, ReadBufferSize);
SET_HANDLER(OpCode::HOST_BUFFER_SIZE, HostBufferSize);
SET_HANDLER(OpCode::SNIFF_SUBRATING, SniffSubrating);
SET_HANDLER(OpCode::READ_ENCRYPTION_KEY_SIZE, ReadEncryptionKeySize);
SET_HANDLER(OpCode::READ_LOCAL_VERSION_INFORMATION,
ReadLocalVersionInformation);
SET_HANDLER(OpCode::READ_BD_ADDR, ReadBdAddr);
SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_COMMANDS,
ReadLocalSupportedCommands);
SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_FEATURES,
ReadLocalSupportedFeatures);
SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_CODECS_V1, ReadLocalSupportedCodecs);
SET_HANDLER(OpCode::READ_LOCAL_EXTENDED_FEATURES, ReadLocalExtendedFeatures);
SET_HANDLER(OpCode::READ_REMOTE_EXTENDED_FEATURES,
ReadRemoteExtendedFeatures);
SET_HANDLER(OpCode::SWITCH_ROLE, SwitchRole);
SET_HANDLER(OpCode::READ_REMOTE_SUPPORTED_FEATURES,
ReadRemoteSupportedFeatures);
SET_HANDLER(OpCode::READ_CLOCK_OFFSET, ReadClockOffset);
SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_REPLY, IoCapabilityRequestReply);
SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_REPLY,
UserConfirmationRequestReply);
SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY,
UserConfirmationRequestNegativeReply);
SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY,
IoCapabilityRequestNegativeReply);
SET_HANDLER(OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL,
ReadInquiryResponseTransmitPowerLevel);
SET_HANDLER(OpCode::WRITE_SIMPLE_PAIRING_MODE, WriteSimplePairingMode);
SET_HANDLER(OpCode::WRITE_LE_HOST_SUPPORT, WriteLeHostSupport);
SET_HANDLER(OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
WriteSecureConnectionsHostSupport);
SET_HANDLER(OpCode::SET_EVENT_MASK, SetEventMask);
SET_HANDLER(OpCode::READ_INQUIRY_MODE, ReadInquiryMode);
SET_HANDLER(OpCode::WRITE_INQUIRY_MODE, WriteInquiryMode);
SET_HANDLER(OpCode::READ_PAGE_SCAN_TYPE, ReadPageScanType);
SET_HANDLER(OpCode::WRITE_PAGE_SCAN_TYPE, WritePageScanType);
SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_TYPE, WriteInquiryScanType);
SET_HANDLER(OpCode::READ_INQUIRY_SCAN_TYPE, ReadInquiryScanType);
SET_HANDLER(OpCode::AUTHENTICATION_REQUESTED, AuthenticationRequested);
SET_HANDLER(OpCode::SET_CONNECTION_ENCRYPTION, SetConnectionEncryption);
SET_HANDLER(OpCode::CHANGE_CONNECTION_LINK_KEY, ChangeConnectionLinkKey);
SET_HANDLER(OpCode::MASTER_LINK_KEY, MasterLinkKey);
SET_HANDLER(OpCode::WRITE_AUTHENTICATION_ENABLE, WriteAuthenticationEnable);
SET_HANDLER(OpCode::READ_AUTHENTICATION_ENABLE, ReadAuthenticationEnable);
SET_HANDLER(OpCode::WRITE_CLASS_OF_DEVICE, WriteClassOfDevice);
SET_HANDLER(OpCode::READ_PAGE_TIMEOUT, ReadPageTimeout);
SET_HANDLER(OpCode::WRITE_PAGE_TIMEOUT, WritePageTimeout);
SET_HANDLER(OpCode::WRITE_LINK_SUPERVISION_TIMEOUT,
WriteLinkSupervisionTimeout);
SET_HANDLER(OpCode::HOLD_MODE, HoldMode);
SET_HANDLER(OpCode::SNIFF_MODE, SniffMode);
SET_HANDLER(OpCode::EXIT_SNIFF_MODE, ExitSniffMode);
SET_HANDLER(OpCode::QOS_SETUP, QosSetup);
SET_HANDLER(OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS,
WriteDefaultLinkPolicySettings);
SET_HANDLER(OpCode::FLOW_SPECIFICATION, FlowSpecification);
SET_HANDLER(OpCode::WRITE_LINK_POLICY_SETTINGS, WriteLinkPolicySettings);
SET_HANDLER(OpCode::CHANGE_CONNECTION_PACKET_TYPE,
ChangeConnectionPacketType);
SET_HANDLER(OpCode::WRITE_LOCAL_NAME, WriteLocalName);
SET_HANDLER(OpCode::READ_LOCAL_NAME, ReadLocalName);
SET_HANDLER(OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE,
WriteExtendedInquiryResponse);
SET_HANDLER(OpCode::REFRESH_ENCRYPTION_KEY, RefreshEncryptionKey);
SET_HANDLER(OpCode::WRITE_VOICE_SETTING, WriteVoiceSetting);
SET_HANDLER(OpCode::READ_NUMBER_OF_SUPPORTED_IAC, ReadNumberOfSupportedIac);
SET_HANDLER(OpCode::READ_CURRENT_IAC_LAP, ReadCurrentIacLap);
SET_HANDLER(OpCode::WRITE_CURRENT_IAC_LAP, WriteCurrentIacLap);
SET_HANDLER(OpCode::READ_PAGE_SCAN_ACTIVITY, ReadPageScanActivity);
SET_HANDLER(OpCode::WRITE_PAGE_SCAN_ACTIVITY, WritePageScanActivity);
SET_HANDLER(OpCode::READ_INQUIRY_SCAN_ACTIVITY, ReadInquiryScanActivity);
SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_ACTIVITY, WriteInquiryScanActivity);
SET_HANDLER(OpCode::READ_SCAN_ENABLE, ReadScanEnable);
SET_HANDLER(OpCode::WRITE_SCAN_ENABLE, WriteScanEnable);
SET_HANDLER(OpCode::SET_EVENT_FILTER, SetEventFilter);
SET_HANDLER(OpCode::INQUIRY, Inquiry);
SET_HANDLER(OpCode::INQUIRY_CANCEL, InquiryCancel);
SET_HANDLER(OpCode::ACCEPT_CONNECTION_REQUEST, AcceptConnectionRequest);
SET_HANDLER(OpCode::REJECT_CONNECTION_REQUEST, RejectConnectionRequest);
SET_HANDLER(OpCode::LINK_KEY_REQUEST_REPLY, LinkKeyRequestReply);
SET_HANDLER(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY,
LinkKeyRequestNegativeReply);
SET_HANDLER(OpCode::DELETE_STORED_LINK_KEY, DeleteStoredLinkKey);
SET_HANDLER(OpCode::REMOTE_NAME_REQUEST, RemoteNameRequest);
SET_HANDLER(OpCode::LE_SET_EVENT_MASK, LeSetEventMask);
SET_HANDLER(OpCode::LE_READ_BUFFER_SIZE_V1, LeReadBufferSize);
SET_HANDLER(OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES,
LeReadLocalSupportedFeatures);
SET_HANDLER(OpCode::LE_SET_RANDOM_ADDRESS, LeSetRandomAddress);
SET_HANDLER(OpCode::LE_SET_ADVERTISING_PARAMETERS,
LeSetAdvertisingParameters);
SET_HANDLER(OpCode::LE_SET_ADVERTISING_DATA, LeSetAdvertisingData);
SET_HANDLER(OpCode::LE_SET_SCAN_RESPONSE_DATA, LeSetScanResponseData);
SET_HANDLER(OpCode::LE_SET_ADVERTISING_ENABLE, LeSetAdvertisingEnable);
SET_HANDLER(OpCode::LE_SET_SCAN_PARAMETERS, LeSetScanParameters);
SET_HANDLER(OpCode::LE_SET_SCAN_ENABLE, LeSetScanEnable);
SET_HANDLER(OpCode::LE_CREATE_CONNECTION, LeCreateConnection);
SET_HANDLER(OpCode::CREATE_CONNECTION, CreateConnection);
SET_HANDLER(OpCode::DISCONNECT, Disconnect);
SET_HANDLER(OpCode::LE_CREATE_CONNECTION_CANCEL, LeConnectionCancel);
SET_HANDLER(OpCode::LE_READ_WHITE_LIST_SIZE, LeReadWhiteListSize);
SET_HANDLER(OpCode::LE_CLEAR_WHITE_LIST, LeClearWhiteList);
SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_WHITE_LIST, LeAddDeviceToWhiteList);
SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_WHITE_LIST,
LeRemoveDeviceFromWhiteList);
SET_HANDLER(OpCode::LE_RAND, LeRand);
SET_HANDLER(OpCode::LE_READ_SUPPORTED_STATES, LeReadSupportedStates);
SET_HANDLER(OpCode::LE_GET_VENDOR_CAPABILITIES, LeVendorCap);
SET_HANDLER(OpCode::LE_MULTI_ADVT, LeVendorMultiAdv);
SET_HANDLER(OpCode::LE_ADV_FILTER, LeAdvertisingFilter);
SET_HANDLER(OpCode::LE_ENERGY_INFO, LeEnergyInfo);
SET_HANDLER(OpCode::LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS,
LeSetExtendedAdvertisingRandomAddress);
SET_HANDLER(OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS,
LeSetExtendedAdvertisingParameters);
SET_HANDLER(OpCode::LE_SET_EXTENDED_ADVERTISING_DATA,
LeSetExtendedAdvertisingData);
SET_HANDLER(OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE,
LeSetExtendedAdvertisingScanResponse);
SET_HANDLER(OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE,
LeSetExtendedAdvertisingEnable);
SET_HANDLER(OpCode::LE_READ_REMOTE_FEATURES, LeReadRemoteFeatures);
SET_HANDLER(OpCode::READ_REMOTE_VERSION_INFORMATION,
ReadRemoteVersionInformation);
SET_HANDLER(OpCode::LE_CONNECTION_UPDATE, LeConnectionUpdate);
SET_HANDLER(OpCode::LE_START_ENCRYPTION, LeStartEncryption);
SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
LeAddDeviceToResolvingList);
SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST,
LeRemoveDeviceFromResolvingList);
SET_HANDLER(OpCode::LE_CLEAR_RESOLVING_LIST, LeClearResolvingList);
SET_HANDLER(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS,
LeSetExtendedScanParameters);
SET_HANDLER(OpCode::LE_SET_EXTENDED_SCAN_ENABLE, LeSetExtendedScanEnable);
SET_HANDLER(OpCode::LE_EXTENDED_CREATE_CONNECTION,
LeExtendedCreateConnection);
SET_HANDLER(OpCode::LE_SET_PRIVACY_MODE, LeSetPrivacyMode);
// Testing Commands
SET_HANDLER(OpCode::READ_LOOPBACK_MODE, ReadLoopbackMode);
SET_HANDLER(OpCode::WRITE_LOOPBACK_MODE, WriteLoopbackMode);
#undef SET_HANDLER
}
void DualModeController::SniffSubrating(CommandPacketView command) {
auto command_view = gd_hci::SniffSubratingView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
send_event_(gd_hci::SniffSubratingCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
command_view.GetConnectionHandle()));
}
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);
send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
completed_packets));
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);
send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
completed_packets));
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();
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>(255);
raw_builder_ptr->AddOctets(*packet);
send_event_(bluetooth::hci::LoopbackCommandBuilder::Create(
std::move(raw_builder_ptr)));
} else if (active_hci_commands_.count(op) > 0) {
active_hci_commands_[op](command_packet);
} else {
uint16_t opcode = static_cast<uint16_t>(op);
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::Reset(CommandPacketView command) {
auto command_view = gd_hci::ResetView::Create(command);
ASSERT(command_view.IsValid());
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::ReadBufferSize(CommandPacketView command) {
auto command_view = gd_hci::ReadBufferSizeView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::ReadBufferSizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetAclDataPacketSize(),
properties_.GetSynchronousDataPacketSize(),
properties_.GetTotalNumAclDataPackets(),
properties_.GetTotalNumSynchronousDataPackets());
send_event_(std::move(packet));
}
void DualModeController::ReadEncryptionKeySize(CommandPacketView command) {
auto command_view = gd_hci::ReadEncryptionKeySizeView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
command_view.GetConnectionHandle(), properties_.GetEncryptionKeySize());
send_event_(std::move(packet));
}
void DualModeController::HostBufferSize(CommandPacketView command) {
auto command_view = gd_hci::HostBufferSizeView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::HostBufferSizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadLocalVersionInformation(
CommandPacketView command) {
auto command_view = gd_hci::ReadLocalVersionInformationView::Create(command);
ASSERT(command_view.IsValid());
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::ReadRemoteVersionInformation(
CommandPacketView command) {
auto command_view = gd_hci::ReadRemoteVersionInformationView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_REMOTE_VERSION_INFORMATION, command.GetPayload(),
command_view.GetConnectionHandle());
auto packet =
bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::ReadBdAddr(CommandPacketView command) {
auto command_view = gd_hci::ReadBdAddrView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetAddress());
send_event_(std::move(packet));
}
void DualModeController::ReadLocalSupportedCommands(CommandPacketView command) {
auto command_view = gd_hci::ReadLocalSupportedCommandsView::Create(command);
ASSERT(command_view.IsValid());
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::ReadLocalSupportedFeatures(CommandPacketView command) {
auto command_view = gd_hci::ReadLocalSupportedFeaturesView::Create(command);
ASSERT(command_view.IsValid());
auto packet =
bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetSupportedFeatures());
send_event_(std::move(packet));
}
void DualModeController::ReadLocalSupportedCodecs(CommandPacketView command) {
auto command_view = gd_hci::ReadLocalSupportedCodecsV1View::Create(command);
ASSERT(command_view.IsValid());
auto packet =
bluetooth::hci::ReadLocalSupportedCodecsV1CompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetSupportedCodecs(),
properties_.GetVendorSpecificCodecs());
send_event_(std::move(packet));
}
void DualModeController::ReadLocalExtendedFeatures(CommandPacketView command) {
auto command_view = gd_hci::ReadLocalExtendedFeaturesView::Create(command);
ASSERT(command_view.IsValid());
uint8_t page_number = command_view.GetPageNumber();
auto pakcet =
bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, page_number,
properties_.GetExtendedFeaturesMaximumPageNumber(),
properties_.GetExtendedFeatures(page_number));
send_event_(std::move(pakcet));
}
void DualModeController::ReadRemoteExtendedFeatures(CommandPacketView command) {
auto command_view = gd_hci::ReadRemoteExtendedFeaturesView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_REMOTE_EXTENDED_FEATURES, command_view.GetPayload(),
command_view.GetConnectionHandle());
auto packet = bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::SwitchRole(CommandPacketView command) {
auto command_view = gd_hci::SwitchRoleView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
auto status = link_layer_controller_.SwitchRole(
command_view.GetBdAddr(), static_cast<uint8_t>(command_view.GetRole()));
auto packet = bluetooth::hci::SwitchRoleStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::ReadRemoteSupportedFeatures(
CommandPacketView command) {
auto command_view = gd_hci::ReadRemoteSupportedFeaturesView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_REMOTE_SUPPORTED_FEATURES, command_view.GetPayload(),
command_view.GetConnectionHandle());
auto packet =
bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::ReadClockOffset(CommandPacketView command) {
auto command_view = gd_hci::ReadClockOffsetView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::READ_CLOCK_OFFSET, command_view.GetPayload(), handle);
auto packet = bluetooth::hci::ReadClockOffsetStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::IoCapabilityRequestReply(CommandPacketView command) {
auto command_view = gd_hci::IoCapabilityRequestReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
uint8_t io_capability = static_cast<uint8_t>(command_view.GetIoCapability());
uint8_t oob_data_present_flag =
static_cast<uint8_t>(command_view.GetOobPresent());
uint8_t authentication_requirements =
static_cast<uint8_t>(command_view.GetAuthenticationRequirements());
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::UserConfirmationRequestReply(
CommandPacketView command) {
auto command_view = gd_hci::UserConfirmationRequestReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
auto status = link_layer_controller_.UserConfirmationRequestReply(peer);
auto packet =
bluetooth::hci::UserConfirmationRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::UserConfirmationRequestNegativeReply(
CommandPacketView command) {
auto command_view = gd_hci::UserConfirmationRequestNegativeReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
auto status =
link_layer_controller_.UserConfirmationRequestNegativeReply(peer);
auto packet =
bluetooth::hci::UserConfirmationRequestNegativeReplyCompleteBuilder::
Create(kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::UserPasskeyRequestReply(CommandPacketView command) {
auto command_view = gd_hci::UserPasskeyRequestReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
uint32_t numeric_value = command_view.GetNumericValue();
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::UserPasskeyRequestNegativeReply(
CommandPacketView command) {
auto command_view = gd_hci::UserPasskeyRequestNegativeReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
auto status = link_layer_controller_.UserPasskeyRequestNegativeReply(peer);
auto packet =
bluetooth::hci::UserPasskeyRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::RemoteOobDataRequestReply(CommandPacketView command) {
auto command_view = gd_hci::RemoteOobDataRequestReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
std::array<uint8_t, 16> c = command_view.GetC();
std::array<uint8_t, 16> r = command_view.GetR();
auto status = link_layer_controller_.RemoteOobDataRequestReply(
peer, std::vector<uint8_t>(c.begin(), c.end()),
std::vector<uint8_t>(r.begin(), r.end()));
auto packet =
bluetooth::hci::RemoteOobDataRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::RemoteOobDataRequestNegativeReply(
CommandPacketView command) {
auto command_view = gd_hci::RemoteOobDataRequestNegativeReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
auto status = link_layer_controller_.RemoteOobDataRequestNegativeReply(peer);
auto packet =
bluetooth::hci::RemoteOobDataRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::IoCapabilityRequestNegativeReply(
CommandPacketView command) {
auto command_view = gd_hci::IoCapabilityRequestNegativeReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address peer = command_view.GetBdAddr();
ErrorCode reason = command_view.GetReason();
auto status =
link_layer_controller_.IoCapabilityRequestNegativeReply(peer, reason);
auto packet =
bluetooth::hci::IoCapabilityRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
void DualModeController::ReadInquiryResponseTransmitPowerLevel(
CommandPacketView command) {
auto command_view = gd_hci::ReadInquiryResponseTransmitPowerLevelView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
uint8_t tx_power = 20; // maximum
auto packet =
bluetooth::hci::ReadInquiryResponseTransmitPowerLevelCompleteBuilder::
Create(kNumCommandPackets, ErrorCode::SUCCESS, tx_power);
send_event_(std::move(packet));
}
void DualModeController::WriteSimplePairingMode(CommandPacketView command) {
auto command_view = gd_hci::WriteSimplePairingModeView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.WriteSimplePairingMode(
command_view.GetSimplePairingMode() == gd_hci::Enable::ENABLED);
auto packet = bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ChangeConnectionPacketType(CommandPacketView command) {
auto command_view = gd_hci::ChangeConnectionPacketTypeView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint16_t packet_type = static_cast<uint16_t>(command_view.GetPacketType());
auto status =
link_layer_controller_.ChangeConnectionPacketType(handle, packet_type);
auto packet = bluetooth::hci::ChangeConnectionPacketTypeStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::WriteLeHostSupport(CommandPacketView command) {
auto command_view = gd_hci::WriteLeHostSupportView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::WriteSecureConnectionsHostSupport(
CommandPacketView command) {
auto command_view = gd_hci::WriteSecureConnectionsHostSupportView::Create(
gd_hci::SecurityCommandView::Create(command));
properties_.SetExtendedFeatures(properties_.GetExtendedFeatures(1) | 0x8, 1);
auto packet =
bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::SetEventMask(CommandPacketView command) {
auto command_view = gd_hci::SetEventMaskView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::SetEventMaskCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadInquiryMode(CommandPacketView command) {
auto command_view = gd_hci::ReadInquiryModeView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
gd_hci::InquiryMode inquiry_mode = gd_hci::InquiryMode::STANDARD;
auto packet = bluetooth::hci::ReadInquiryModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, inquiry_mode);
send_event_(std::move(packet));
}
void DualModeController::WriteInquiryMode(CommandPacketView command) {
auto command_view = gd_hci::WriteInquiryModeView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.SetInquiryMode(
static_cast<uint8_t>(command_view.GetInquiryMode()));
auto packet = bluetooth::hci::WriteInquiryModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadPageScanType(CommandPacketView command) {
auto command_view = gd_hci::ReadPageScanTypeView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
gd_hci::PageScanType page_scan_type = gd_hci::PageScanType::STANDARD;
auto packet = bluetooth::hci::ReadPageScanTypeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, page_scan_type);
send_event_(std::move(packet));
}
void DualModeController::WritePageScanType(CommandPacketView command) {
auto command_view = gd_hci::WritePageScanTypeView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WritePageScanTypeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadInquiryScanType(CommandPacketView command) {
auto command_view = gd_hci::ReadInquiryScanTypeView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
gd_hci::InquiryScanType inquiry_scan_type = gd_hci::InquiryScanType::STANDARD;
auto packet = bluetooth::hci::ReadInquiryScanTypeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, inquiry_scan_type);
send_event_(std::move(packet));
}
void DualModeController::WriteInquiryScanType(CommandPacketView command) {
auto command_view = gd_hci::WriteInquiryScanTypeView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::AuthenticationRequested(CommandPacketView command) {
auto command_view = gd_hci::AuthenticationRequestedView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
auto status = link_layer_controller_.AuthenticationRequested(handle);
auto packet = bluetooth::hci::AuthenticationRequestedStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::SetConnectionEncryption(CommandPacketView command) {
auto command_view = gd_hci::SetConnectionEncryptionView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint8_t encryption_enable =
static_cast<uint8_t>(command_view.GetEncryptionEnable());
auto status =
link_layer_controller_.SetConnectionEncryption(handle, encryption_enable);
auto packet = bluetooth::hci::SetConnectionEncryptionStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::ChangeConnectionLinkKey(CommandPacketView command) {
auto command_view = gd_hci::ChangeConnectionLinkKeyView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
auto status = link_layer_controller_.ChangeConnectionLinkKey(handle);
auto packet = bluetooth::hci::ChangeConnectionLinkKeyStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::MasterLinkKey(CommandPacketView command) {
auto command_view = gd_hci::MasterLinkKeyView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint8_t key_flag = static_cast<uint8_t>(command_view.GetKeyFlag());
auto status = link_layer_controller_.MasterLinkKey(key_flag);
auto packet = bluetooth::hci::MasterLinkKeyStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::WriteAuthenticationEnable(CommandPacketView command) {
auto command_view = gd_hci::WriteAuthenticationEnableView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
properties_.SetAuthenticationEnable(
static_cast<uint8_t>(command_view.GetAuthenticationEnable()));
auto packet =
bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadAuthenticationEnable(CommandPacketView command) {
auto command_view = gd_hci::ReadAuthenticationEnableView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
static_cast<bluetooth::hci::AuthenticationEnable>(
properties_.GetAuthenticationEnable()));
send_event_(std::move(packet));
}
void DualModeController::WriteClassOfDevice(CommandPacketView command) {
auto command_view = gd_hci::WriteClassOfDeviceView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
ClassOfDevice class_of_device = command_view.GetClassOfDevice();
properties_.SetClassOfDevice(class_of_device.cod[0], class_of_device.cod[1],
class_of_device.cod[2]);
auto packet = bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadPageTimeout(CommandPacketView command) {
auto command_view = gd_hci::ReadPageTimeoutView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t page_timeout = 0x2000;
auto packet = bluetooth::hci::ReadPageTimeoutCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, page_timeout);
send_event_(std::move(packet));
}
void DualModeController::WritePageTimeout(CommandPacketView command) {
auto command_view = gd_hci::WritePageTimeoutView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WritePageTimeoutCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::HoldMode(CommandPacketView command) {
auto command_view = gd_hci::HoldModeView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint16_t hold_mode_max_interval = command_view.GetHoldModeMaxInterval();
uint16_t hold_mode_min_interval = command_view.GetHoldModeMinInterval();
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::SniffMode(CommandPacketView command) {
auto command_view = gd_hci::SniffModeView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint16_t sniff_max_interval = command_view.GetSniffMaxInterval();
uint16_t sniff_min_interval = command_view.GetSniffMinInterval();
uint16_t sniff_attempt = command_view.GetSniffAttempt();
uint16_t sniff_timeout = command_view.GetSniffTimeout();
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::ExitSniffMode(CommandPacketView command) {
auto command_view = gd_hci::ExitSniffModeView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
auto status =
link_layer_controller_.ExitSniffMode(command_view.GetConnectionHandle());
auto packet = bluetooth::hci::ExitSniffModeStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::QosSetup(CommandPacketView command) {
auto command_view = gd_hci::QosSetupView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint8_t service_type = static_cast<uint8_t>(command_view.GetServiceType());
uint32_t token_rate = command_view.GetTokenRate();
uint32_t peak_bandwidth = command_view.GetPeakBandwidth();
uint32_t latency = command_view.GetLatency();
uint32_t delay_variation = command_view.GetDelayVariation();
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::WriteDefaultLinkPolicySettings(
CommandPacketView command) {
auto command_view = gd_hci::WriteDefaultLinkPolicySettingsView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet =
bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::FlowSpecification(CommandPacketView command) {
auto command_view = gd_hci::FlowSpecificationView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint8_t flow_direction =
static_cast<uint8_t>(command_view.GetFlowDirection());
uint8_t service_type = static_cast<uint8_t>(command_view.GetServiceType());
uint32_t token_rate = command_view.GetTokenRate();
uint32_t token_bucket_size = command_view.GetTokenBucketSize();
uint32_t peak_bandwidth = command_view.GetPeakBandwidth();
uint32_t access_latency = command_view.GetAccessLatency();
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::WriteLinkPolicySettings(CommandPacketView command) {
auto command_view = gd_hci::WriteLinkPolicySettingsView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint16_t settings = command_view.GetLinkPolicySettings();
auto status =
link_layer_controller_.WriteLinkPolicySettings(handle, settings);
auto packet = bluetooth::hci::WriteLinkPolicySettingsCompleteBuilder::Create(
kNumCommandPackets, status, handle);
send_event_(std::move(packet));
}
void DualModeController::WriteLinkSupervisionTimeout(
CommandPacketView command) {
auto command_view = gd_hci::WriteLinkSupervisionTimeoutView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetHandle();
uint16_t timeout = command_view.GetLinkSupervisionTimeout();
auto status =
link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout);
auto packet =
bluetooth::hci::WriteLinkSupervisionTimeoutCompleteBuilder::Create(
kNumCommandPackets, status, handle);
send_event_(std::move(packet));
}
void DualModeController::ReadLocalName(CommandPacketView command) {
auto command_view = gd_hci::ReadLocalNameView::Create(command);
ASSERT(command_view.IsValid());
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::WriteLocalName(CommandPacketView command) {
auto command_view = gd_hci::WriteLocalNameView::Create(command);
ASSERT(command_view.IsValid());
const auto local_name = command_view.GetLocalName();
std::vector<uint8_t> name_vec(248);
for (size_t i = 0; i < 248; i++) {
name_vec[i] = local_name[i];
}
properties_.SetName(name_vec);
auto packet = bluetooth::hci::WriteLocalNameCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::WriteExtendedInquiryResponse(
CommandPacketView command) {
auto command_view = gd_hci::WriteExtendedInquiryResponseView::Create(command);
ASSERT(command_view.IsValid());
properties_.SetExtendedInquiryData(std::vector<uint8_t>(
command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
auto packet =
bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::RefreshEncryptionKey(CommandPacketView command) {
auto command_view = gd_hci::RefreshEncryptionKeyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
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::WriteVoiceSetting(CommandPacketView command) {
auto command_view = gd_hci::WriteVoiceSettingView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadNumberOfSupportedIac(CommandPacketView command) {
auto command_view = gd_hci::ReadNumberOfSupportedIacView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
uint8_t num_support_iac = 0x1;
auto packet = bluetooth::hci::ReadNumberOfSupportedIacCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, num_support_iac);
send_event_(std::move(packet));
}
void DualModeController::ReadCurrentIacLap(CommandPacketView command) {
auto command_view = gd_hci::ReadCurrentIacLapView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
gd_hci::Lap lap;
lap.lap_ = 0x30;
auto packet = bluetooth::hci::ReadCurrentIacLapCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, {lap});
send_event_(std::move(packet));
}
void DualModeController::WriteCurrentIacLap(CommandPacketView command) {
auto command_view = gd_hci::WriteCurrentIacLapView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadPageScanActivity(CommandPacketView command) {
auto command_view = gd_hci::ReadPageScanActivityView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t interval = 0x1000;
uint16_t window = 0x0012;
auto packet = bluetooth::hci::ReadPageScanActivityCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, interval, window);
send_event_(std::move(packet));
}
void DualModeController::WritePageScanActivity(CommandPacketView command) {
auto command_view = gd_hci::WritePageScanActivityView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WritePageScanActivityCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadInquiryScanActivity(CommandPacketView command) {
auto command_view = gd_hci::ReadInquiryScanActivityView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t interval = 0x1000;
uint16_t window = 0x0012;
auto packet = bluetooth::hci::ReadInquiryScanActivityCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, interval, window);
send_event_(std::move(packet));
}
void DualModeController::WriteInquiryScanActivity(CommandPacketView command) {
auto command_view = gd_hci::WriteInquiryScanActivityView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::ReadScanEnable(CommandPacketView command) {
auto command_view = gd_hci::ReadScanEnableView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::ReadScanEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, gd_hci::ScanEnable::NO_SCANS);
send_event_(std::move(packet));
}
void DualModeController::WriteScanEnable(CommandPacketView command) {
auto command_view = gd_hci::WriteScanEnableView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.SetInquiryScanEnable(
command_view.GetScanEnable() ==
gd_hci::ScanEnable::INQUIRY_AND_PAGE_SCAN ||
command_view.GetScanEnable() == gd_hci::ScanEnable::INQUIRY_SCAN_ONLY);
link_layer_controller_.SetPageScanEnable(
command_view.GetScanEnable() ==
gd_hci::ScanEnable::INQUIRY_AND_PAGE_SCAN ||
command_view.GetScanEnable() == gd_hci::ScanEnable::PAGE_SCAN_ONLY);
auto packet = bluetooth::hci::WriteScanEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::SetEventFilter(CommandPacketView command) {
auto command_view = gd_hci::SetEventFilterView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::SetEventFilterCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::Inquiry(CommandPacketView command) {
auto command_view = gd_hci::InquiryView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.SetInquiryLAP(command_view.GetLap().lap_);
link_layer_controller_.SetInquiryMaxResponses(command_view.GetNumResponses());
link_layer_controller_.StartInquiry(
std::chrono::milliseconds(command_view.GetInquiryLength() * 1280));
auto packet = bluetooth::hci::InquiryStatusBuilder::Create(
ErrorCode::SUCCESS, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::InquiryCancel(CommandPacketView command) {
auto command_view = gd_hci::InquiryCancelView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.InquiryCancel();
auto packet = bluetooth::hci::InquiryCancelCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::AcceptConnectionRequest(CommandPacketView command) {
auto command_view = gd_hci::AcceptConnectionRequestView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
Address addr = command_view.GetBdAddr();
bool try_role_switch = command_view.GetRole() ==
gd_hci::AcceptConnectionRequestRole::BECOME_MASTER;
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::RejectConnectionRequest(CommandPacketView command) {
auto command_view = gd_hci::RejectConnectionRequestView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
Address addr = command_view.GetBdAddr();
uint8_t reason = static_cast<uint8_t>(command_view.GetReason());
auto status = link_layer_controller_.RejectConnectionRequest(addr, reason);
auto packet = bluetooth::hci::RejectConnectionRequestStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::LinkKeyRequestReply(CommandPacketView command) {
auto command_view = gd_hci::LinkKeyRequestReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address addr = command_view.GetBdAddr();
auto key = command_view.GetLinkKey();
auto status = link_layer_controller_.LinkKeyRequestReply(addr, key);
auto packet = bluetooth::hci::LinkKeyRequestReplyCompleteBuilder::Create(
kNumCommandPackets, status);
send_event_(std::move(packet));
}
void DualModeController::LinkKeyRequestNegativeReply(
CommandPacketView command) {
auto command_view = gd_hci::LinkKeyRequestNegativeReplyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
Address addr = command_view.GetBdAddr();
auto status = link_layer_controller_.LinkKeyRequestNegativeReply(addr);
auto packet =
bluetooth::hci::LinkKeyRequestNegativeReplyCompleteBuilder::Create(
kNumCommandPackets, status, addr);
send_event_(std::move(packet));
}
void DualModeController::DeleteStoredLinkKey(CommandPacketView command) {
auto command_view = gd_hci::DeleteStoredLinkKeyView::Create(
gd_hci::SecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t deleted_keys = 0;
auto flag = command_view.GetDeleteAllFlag();
if (flag == gd_hci::DeleteStoredLinkKeyDeleteAllFlag::SPECIFIED_BD_ADDR) {
Address addr = command_view.GetBdAddr();
deleted_keys = security_manager_.DeleteKey(addr);
}
if (flag == gd_hci::DeleteStoredLinkKeyDeleteAllFlag::ALL) {
security_manager_.DeleteAllKeys();
}
auto packet = bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, deleted_keys);
send_event_(std::move(packet));
}
void DualModeController::RemoteNameRequest(CommandPacketView command) {
auto command_view = gd_hci::RemoteNameRequestView::Create(
gd_hci::DiscoveryCommandView::Create(command));
ASSERT(command_view.IsValid());
Address remote_addr = command_view.GetBdAddr();
auto status = link_layer_controller_.SendCommandToRemoteByAddress(
OpCode::REMOTE_NAME_REQUEST, command_view.GetPayload(), remote_addr);
auto packet = bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::LeSetEventMask(CommandPacketView command) {
auto command_view = gd_hci::LeSetEventMaskView::Create(command);
ASSERT(command_view.IsValid());
/*
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::LeReadBufferSize(CommandPacketView command) {
auto command_view = gd_hci::LeReadBufferSizeV1View::Create(command);
ASSERT(command_view.IsValid());
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::LeReadBufferSizeV1CompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, le_buffer_size);
send_event_(std::move(packet));
}
void DualModeController::LeReadLocalSupportedFeatures(
CommandPacketView command) {
auto command_view = gd_hci::LeReadLocalSupportedFeaturesView::Create(command);
ASSERT(command_view.IsValid());
auto packet =
bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetLeSupportedFeatures());
send_event_(std::move(packet));
}
void DualModeController::LeSetRandomAddress(CommandPacketView command) {
auto command_view = gd_hci::LeSetRandomAddressView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
properties_.SetLeAddress(command_view.GetRandomAddress());
auto packet = bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetAdvertisingParameters(CommandPacketView command) {
auto command_view = gd_hci::LeSetAdvertisingParametersView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
properties_.SetLeAdvertisingParameters(
command_view.GetIntervalMin(), command_view.GetIntervalMax(),
static_cast<uint8_t>(command_view.GetType()),
static_cast<uint8_t>(command_view.GetOwnAddressType()),
static_cast<uint8_t>(command_view.GetPeerAddressType()),
command_view.GetPeerAddress(), command_view.GetChannelMap(),
static_cast<uint8_t>(command_view.GetFilterPolicy()));
auto packet =
bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetAdvertisingData(CommandPacketView command) {
auto command_view = gd_hci::LeSetAdvertisingDataView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
auto payload = command.GetPayload();
std::vector<uint8_t> payload_bytes{payload.begin() + 1,
payload.begin() + *payload.begin()};
ASSERT_LOG(command_view.IsValid(), "%s command.size() = %zu",
gd_hci::OpCodeText(command.GetOpCode()).c_str(), command.size());
ASSERT(command_view.GetPayload().size() == 32);
properties_.SetLeAdvertisement(payload_bytes);
auto packet = bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetScanResponseData(CommandPacketView command) {
auto command_view = gd_hci::LeSetScanResponseDataView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
ASSERT(command_view.GetPayload().size() == 32);
properties_.SetLeScanResponse(std::vector<uint8_t>(
command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
auto packet = bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetAdvertisingEnable(CommandPacketView command) {
auto command_view = gd_hci::LeSetAdvertisingEnableView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
auto status = link_layer_controller_.SetLeAdvertisingEnable(
command_view.GetAdvertisingEnable() == gd_hci::Enable::ENABLED);
auto packet = bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
kNumCommandPackets, status);
send_event_(std::move(packet));
}
void DualModeController::LeSetScanParameters(CommandPacketView command) {
auto command_view = gd_hci::LeSetScanParametersView::Create(
gd_hci::LeScanningCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.SetLeScanType(
static_cast<uint8_t>(command_view.GetLeScanType()));
link_layer_controller_.SetLeScanInterval(command_view.GetLeScanInterval());
link_layer_controller_.SetLeScanWindow(command_view.GetLeScanWindow());
link_layer_controller_.SetLeAddressType(
static_cast<uint8_t>(command_view.GetOwnAddressType()));
link_layer_controller_.SetLeScanFilterPolicy(
static_cast<uint8_t>(command_view.GetScanningFilterPolicy()));
auto packet = bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetScanEnable(CommandPacketView command) {
auto command_view = gd_hci::LeSetScanEnableView::Create(
gd_hci::LeScanningCommandView::Create(command));
ASSERT(command_view.IsValid());
if (command_view.GetLeScanEnable() == gd_hci::Enable::ENABLED) {
link_layer_controller_.SetLeScanEnable(gd_hci::OpCode::LE_SET_SCAN_ENABLE);
} else {
link_layer_controller_.SetLeScanEnable(gd_hci::OpCode::NONE);
}
link_layer_controller_.SetLeFilterDuplicates(
command_view.GetFilterDuplicates() == gd_hci::Enable::ENABLED);
auto packet = bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeCreateConnection(CommandPacketView command) {
auto command_view = gd_hci::LeCreateConnectionView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.SetLeScanInterval(command_view.GetLeScanInterval());
link_layer_controller_.SetLeScanWindow(command_view.GetLeScanWindow());
uint8_t initiator_filter_policy =
static_cast<uint8_t>(command_view.GetInitiatorFilterPolicy());
link_layer_controller_.SetLeInitiatorFilterPolicy(initiator_filter_policy);
if (initiator_filter_policy == 0) { // White list not used
uint8_t peer_address_type =
static_cast<uint8_t>(command_view.GetPeerAddressType());
Address peer_address = command_view.GetPeerAddress();
link_layer_controller_.SetLePeerAddressType(peer_address_type);
link_layer_controller_.SetLePeerAddress(peer_address);
}
link_layer_controller_.SetLeAddressType(
static_cast<uint8_t>(command_view.GetOwnAddressType()));
link_layer_controller_.SetLeConnectionIntervalMin(
command_view.GetConnIntervalMin());
link_layer_controller_.SetLeConnectionIntervalMax(
command_view.GetConnIntervalMax());
link_layer_controller_.SetLeConnectionLatency(command_view.GetConnLatency());
link_layer_controller_.SetLeSupervisionTimeout(
command_view.GetSupervisionTimeout());
link_layer_controller_.SetLeMinimumCeLength(
command_view.GetMinimumCeLength());
link_layer_controller_.SetLeMaximumCeLength(
command_view.GetMaximumCeLength());
auto status = link_layer_controller_.SetLeConnect(true);
auto packet = bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::LeConnectionUpdate(CommandPacketView command) {
auto command_view = gd_hci::LeConnectionUpdateView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
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::CreateConnection(CommandPacketView command) {
auto command_view = gd_hci::CreateConnectionView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
Address address = command_view.GetBdAddr();
uint16_t packet_type = command_view.GetPacketType();
uint8_t page_scan_mode =
static_cast<uint8_t>(command_view.GetPageScanRepetitionMode());
uint16_t clock_offset =
(command_view.GetClockOffsetValid() == gd_hci::ClockOffsetValid::VALID
? command_view.GetClockOffset()
: 0);
uint8_t allow_role_switch =
static_cast<uint8_t>(command_view.GetAllowRoleSwitch());
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::Disconnect(CommandPacketView command) {
auto command_view = gd_hci::DisconnectView::Create(
gd_hci::ConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
uint8_t reason = static_cast<uint8_t>(command_view.GetReason());
auto status = link_layer_controller_.Disconnect(handle, reason);
auto packet = bluetooth::hci::DisconnectStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::LeConnectionCancel(CommandPacketView command) {
auto command_view = gd_hci::LeCreateConnectionCancelView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
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::LeReadWhiteListSize(CommandPacketView command) {
auto command_view = gd_hci::LeReadWhiteListSizeView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::LeReadWhiteListSizeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetLeWhiteListSize());
send_event_(std::move(packet));
}
void DualModeController::LeClearWhiteList(CommandPacketView command) {
auto command_view = gd_hci::LeClearWhiteListView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.LeWhiteListClear();
auto packet = bluetooth::hci::LeClearWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeAddDeviceToWhiteList(CommandPacketView command) {
auto command_view = gd_hci::LeAddDeviceToWhiteListView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
if (link_layer_controller_.LeWhiteListFull()) {
auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::MEMORY_CAPACITY_EXCEEDED);
send_event_(std::move(packet));
return;
}
uint8_t addr_type = static_cast<uint8_t>(command_view.GetAddressType());
Address address = command_view.GetAddress();
link_layer_controller_.LeWhiteListAddDevice(address, addr_type);
auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeRemoveDeviceFromWhiteList(
CommandPacketView command) {
auto command_view = gd_hci::LeRemoveDeviceFromWhiteListView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint8_t addr_type = static_cast<uint8_t>(command_view.GetAddressType());
Address address = command_view.GetAddress();
link_layer_controller_.LeWhiteListRemoveDevice(address, addr_type);
auto packet =
bluetooth::hci::LeRemoveDeviceFromWhiteListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeClearResolvingList(CommandPacketView command) {
auto command_view = gd_hci::LeClearResolvingListView::Create(
gd_hci::LeSecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
link_layer_controller_.LeResolvingListClear();
auto packet = bluetooth::hci::LeClearResolvingListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeAddDeviceToResolvingList(CommandPacketView command) {
auto command_view = gd_hci::LeAddDeviceToResolvingListView::Create(
gd_hci::LeSecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
if (link_layer_controller_.LeResolvingListFull()) {
auto packet =
bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::MEMORY_CAPACITY_EXCEEDED);
send_event_(std::move(packet));
return;
}
uint8_t addr_type =
static_cast<uint8_t>(command_view.GetPeerIdentityAddressType());
Address address = command_view.GetPeerIdentityAddress();
std::array<uint8_t, LinkLayerController::kIrk_size> peerIrk =
command_view.GetPeerIrk();
std::array<uint8_t, LinkLayerController::kIrk_size> localIrk =
command_view.GetLocalIrk();
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::LeRemoveDeviceFromResolvingList(
CommandPacketView command) {
auto command_view = gd_hci::LeRemoveDeviceFromResolvingListView::Create(
gd_hci::LeSecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
uint8_t addr_type =
static_cast<uint8_t>(command_view.GetPeerIdentityAddressType());
Address address = command_view.GetPeerIdentityAddress();
link_layer_controller_.LeResolvingListRemoveDevice(address, addr_type);
auto packet =
bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetExtendedScanParameters(
CommandPacketView command) {
auto command_view = gd_hci::LeSetExtendedScanParametersView::Create(
gd_hci::LeScanningCommandView::Create(command));
ASSERT(command_view.IsValid());
auto parameters = command_view.GetParameters();
// Multiple phys are not supported.
ASSERT(command_view.GetScanningPhys() == 1);
ASSERT(parameters.size() == 1);
link_layer_controller_.SetLeScanType(
static_cast<uint8_t>(parameters[0].le_scan_type_));
link_layer_controller_.SetLeScanInterval(parameters[0].le_scan_interval_);
link_layer_controller_.SetLeScanWindow(parameters[0].le_scan_window_);
link_layer_controller_.SetLeAddressType(
static_cast<uint8_t>(command_view.GetOwnAddressType()));
link_layer_controller_.SetLeScanFilterPolicy(
static_cast<uint8_t>(command_view.GetScanningFilterPolicy()));
auto packet =
bluetooth::hci::LeSetExtendedScanParametersCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetExtendedScanEnable(CommandPacketView command) {
auto command_view = gd_hci::LeSetExtendedScanEnableView::Create(
gd_hci::LeScanningCommandView::Create(command));
ASSERT(command_view.IsValid());
if (command_view.GetEnable() == gd_hci::Enable::ENABLED) {
link_layer_controller_.SetLeScanEnable(
gd_hci::OpCode::LE_SET_EXTENDED_SCAN_ENABLE);
} else {
link_layer_controller_.SetLeScanEnable(gd_hci::OpCode::NONE);
}
link_layer_controller_.SetLeFilterDuplicates(
command_view.GetFilterDuplicates() == gd_hci::FilterDuplicates::ENABLED);
auto packet = bluetooth::hci::LeSetExtendedScanEnableCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeExtendedCreateConnection(CommandPacketView command) {
auto command_view = gd_hci::LeExtendedCreateConnectionView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
ASSERT_LOG(command_view.GetInitiatingPhys() == 1, "Only LE_1M is supported");
auto params = command_view.GetPhyScanParameters();
link_layer_controller_.SetLeScanInterval(params[0].scan_interval_);
link_layer_controller_.SetLeScanWindow(params[0].scan_window_);
auto initiator_filter_policy = command_view.GetInitiatorFilterPolicy();
link_layer_controller_.SetLeInitiatorFilterPolicy(
static_cast<uint8_t>(initiator_filter_policy));
if (initiator_filter_policy ==
gd_hci::InitiatorFilterPolicy::USE_PEER_ADDRESS) {
link_layer_controller_.SetLePeerAddressType(
static_cast<uint8_t>(command_view.GetPeerAddressType()));
link_layer_controller_.SetLePeerAddress(command_view.GetPeerAddress());
}
link_layer_controller_.SetLeAddressType(
static_cast<uint8_t>(command_view.GetOwnAddressType()));
link_layer_controller_.SetLeConnectionIntervalMin(
params[0].conn_interval_min_);
link_layer_controller_.SetLeConnectionIntervalMax(
params[0].conn_interval_max_);
link_layer_controller_.SetLeConnectionLatency(params[0].conn_latency_);
link_layer_controller_.SetLeSupervisionTimeout(
params[0].supervision_timeout_);
link_layer_controller_.SetLeMinimumCeLength(params[0].min_ce_length_);
link_layer_controller_.SetLeMaximumCeLength(params[0].max_ce_length_);
auto status = link_layer_controller_.SetLeConnect(true);
send_event_(bluetooth::hci::LeExtendedCreateConnectionStatusBuilder::Create(
status, kNumCommandPackets));
}
void DualModeController::LeSetPrivacyMode(CommandPacketView command) {
auto command_view = gd_hci::LeSetPrivacyModeView::Create(
gd_hci::LeSecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
uint8_t peer_identity_address_type =
static_cast<uint8_t>(command_view.GetPeerIdentityAddressType());
Address peer_identity_address = command_view.GetPeerIdentityAddress();
uint8_t privacy_mode = static_cast<uint8_t>(command_view.GetPrivacyMode());
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::LeReadRemoteFeatures(CommandPacketView command) {
auto command_view = gd_hci::LeReadRemoteFeaturesView::Create(
gd_hci::LeConnectionManagementCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
OpCode::LE_READ_REMOTE_FEATURES, command_view.GetPayload(), handle);
auto packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
status, kNumCommandPackets);
send_event_(std::move(packet));
}
void DualModeController::LeRand(CommandPacketView command) {
auto command_view = gd_hci::LeRandView::Create(
gd_hci::LeSecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
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::LeReadSupportedStates(CommandPacketView command) {
auto command_view = gd_hci::LeReadSupportedStatesView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
properties_.GetLeSupportedStates());
send_event_(std::move(packet));
}
void DualModeController::LeVendorCap(CommandPacketView command) {
auto command_view = gd_hci::LeGetVendorCapabilitiesView::Create(
gd_hci::VendorCommandView::Create(command));
ASSERT(command_view.IsValid());
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::LeVendorMultiAdv(CommandPacketView command) {
auto command_view = gd_hci::LeMultiAdvtView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_MULTI_ADVT));
}
void DualModeController::LeAdvertisingFilter(CommandPacketView command) {
auto command_view = gd_hci::LeAdvFilterView::Create(
gd_hci::LeScanningCommandView::Create(command));
ASSERT(command_view.IsValid());
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_ADV_FILTER));
}
void DualModeController::LeEnergyInfo(CommandPacketView command) {
auto command_view = gd_hci::LeEnergyInfoView::Create(
gd_hci::VendorCommandView::Create(command));
ASSERT(command_view.IsValid());
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_ENERGY_INFO));
}
void DualModeController::LeSetExtendedAdvertisingRandomAddress(
CommandPacketView command) {
auto command_view = gd_hci::LeSetExtendedAdvertisingRandomAddressView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
properties_.SetLeAddress(command_view.GetAdvertisingRandomAddress());
send_event_(
bluetooth::hci::LeSetExtendedAdvertisingRandomAddressCompleteBuilder::
Create(kNumCommandPackets, ErrorCode::SUCCESS));
}
void DualModeController::LeSetExtendedAdvertisingParameters(
CommandPacketView command) {
auto command_view =
gd_hci::LeSetExtendedAdvertisingLegacyParametersView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
// TODO: Support non-legacy parameters
ASSERT(command_view.IsValid());
properties_.SetLeAdvertisingParameters(
command_view.GetPrimaryAdvertisingIntervalMin(),
command_view.GetPrimaryAdvertisingIntervalMax(),
static_cast<uint8_t>(bluetooth::hci::AdvertisingEventType::ADV_IND),
static_cast<uint8_t>(command_view.GetOwnAddressType()),
static_cast<uint8_t>(command_view.GetPeerAddressType()),
command_view.GetPeerAddress(),
command_view.GetPrimaryAdvertisingChannelMap(),
static_cast<uint8_t>(command_view.GetAdvertisingFilterPolicy()));
send_event_(
bluetooth::hci::LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS, 0xa5));
}
void DualModeController::LeSetExtendedAdvertisingData(
CommandPacketView command) {
auto command_view = gd_hci::LeSetExtendedAdvertisingDataView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
auto raw_command_view = gd_hci::LeSetExtendedAdvertisingDataRawView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(raw_command_view.IsValid());
properties_.SetLeAdvertisement(raw_command_view.GetAdvertisingData());
auto packet =
bluetooth::hci::LeSetExtendedAdvertisingDataCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
void DualModeController::LeSetExtendedAdvertisingScanResponse(
CommandPacketView command) {
auto command_view = gd_hci::LeSetExtendedAdvertisingScanResponseView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
properties_.SetLeScanResponse(std::vector<uint8_t>(
command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
send_event_(
bluetooth::hci::LeSetExtendedAdvertisingScanResponseCompleteBuilder::
Create(kNumCommandPackets, ErrorCode::SUCCESS));
}
void DualModeController::LeSetExtendedAdvertisingEnable(
CommandPacketView command) {
auto command_view = gd_hci::LeSetExtendedAdvertisingEnableView::Create(
gd_hci::LeAdvertisingCommandView::Create(command));
ASSERT(command_view.IsValid());
auto status = link_layer_controller_.SetLeAdvertisingEnable(
command_view.GetEnable() == gd_hci::Enable::ENABLED);
send_event_(
bluetooth::hci::LeSetExtendedAdvertisingEnableCompleteBuilder::Create(
kNumCommandPackets, status));
}
void DualModeController::LeExtendedScanParams(CommandPacketView command) {
auto command_view = gd_hci::LeExtendedScanParamsView::Create(
gd_hci::LeScanningCommandView::Create(command));
ASSERT(command_view.IsValid());
SendCommandCompleteUnknownOpCodeEvent(
static_cast<uint16_t>(OpCode::LE_EXTENDED_SCAN_PARAMS));
}
void DualModeController::LeStartEncryption(CommandPacketView command) {
auto command_view = gd_hci::LeStartEncryptionView::Create(
gd_hci::LeSecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
uint16_t handle = command_view.GetConnectionHandle();
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));
}
void DualModeController::ReadLoopbackMode(CommandPacketView command) {
auto command_view = gd_hci::ReadLoopbackModeView::Create(command);
ASSERT(command_view.IsValid());
auto packet = bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create(
kNumCommandPackets, ErrorCode::SUCCESS,
static_cast<LoopbackMode>(loopback_mode_));
send_event_(std::move(packet));
}
void DualModeController::WriteLoopbackMode(CommandPacketView command) {
auto command_view = gd_hci::WriteLoopbackModeView::Create(command);
ASSERT(command_view.IsValid());
loopback_mode_ = command_view.GetLoopbackMode();
// 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