blob: 551cf40586edf296d9a5a5d0d870eccbaa8b18d3 [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.
*/
#pragma once
#include <unistd.h>
#include <cstdint>
#include <functional>
#include <memory>
#include <random>
#include <string>
#include <unordered_map>
#include <vector>
#include "hci/address.h"
#include "model/controller/controller_properties.h"
#include "model/controller/link_layer_controller.h"
#include "model/controller/vendor_commands/csr.h"
#include "model/devices/device.h"
#include "packets/hci_packets.h"
#include "packets/link_layer_packets.h"
#include "phy.h"
namespace rootcanal {
using ::bluetooth::hci::Address;
using ::bluetooth::hci::CommandView;
// Emulates a dual mode BR/EDR + LE controller by maintaining the link layer
// state machine detailed in the Bluetooth Core Specification Version 4.2,
// Volume 6, Part B, Section 1.1 (page 30). Provides methods corresponding to
// commands sent by the HCI. These methods will be registered as callbacks from
// a controller instance with the HciHandler. To implement a new Bluetooth
// command, simply add the method declaration below, with return type void and a
// single const std::vector<uint8_t>& argument. After implementing the
// method, simply register it with the HciHandler using the SET_HANDLER macro in
// the controller's default constructor. Be sure to name your method after the
// corresponding Bluetooth command in the Core Specification with the prefix
// "Hci" to distinguish it as a controller command.
class DualModeController : public Device {
public:
DualModeController(ControllerProperties properties = ControllerProperties());
DualModeController(DualModeController&&) = delete;
DualModeController(const DualModeController&) = delete;
~DualModeController() = default;
DualModeController& operator=(const DualModeController&) = delete;
// Device methods.
std::string GetTypeString() const override;
void ReceiveLinkLayerPacket(model::packets::LinkLayerPacketView incoming,
Phy::Type type, int8_t rssi) override;
void Tick() override;
void Close() override;
// Route commands and data from the stack.
void HandleAcl(std::shared_ptr<std::vector<uint8_t>> acl_packet);
void HandleCommand(std::shared_ptr<std::vector<uint8_t>> command_packet);
void HandleSco(std::shared_ptr<std::vector<uint8_t>> sco_packet);
void HandleIso(std::shared_ptr<std::vector<uint8_t>> iso_packet);
// Set the callbacks for sending packets to the HCI.
void RegisterEventChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
send_event);
void RegisterAclChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
send_acl);
void RegisterScoChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
send_sco);
void RegisterIsoChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
send_iso);
// Controller commands. For error codes, see the Bluetooth Core Specification,
// Version 4.2, Volume 2, Part D (page 370).
// Link Control Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1
// 7.1.1
void Inquiry(CommandView command);
// 7.1.2
void InquiryCancel(CommandView command);
// 7.1.5
void CreateConnection(CommandView command);
// 7.1.6
void Disconnect(CommandView command);
// Deprecated
void AddScoConnection(CommandView command);
// 7.1.7
void CreateConnectionCancel(CommandView command);
// 7.1.8
void AcceptConnectionRequest(CommandView command);
// 7.1.9
void RejectConnectionRequest(CommandView command);
// 7.1.14
void ChangeConnectionPacketType(CommandView command);
// 7.1.17
void ChangeConnectionLinkKey(CommandView command);
// 7.1.18
void CentralLinkKey(CommandView command);
// 7.1.19
void RemoteNameRequest(CommandView command);
// 7.1.21
void ReadRemoteSupportedFeatures(CommandView command);
// 7.1.22
void ReadRemoteExtendedFeatures(CommandView command);
// 7.1.23
void ReadRemoteVersionInformation(CommandView command);
// 7.1.24
void ReadClockOffset(CommandView command);
// 7.1.26
void SetupSynchronousConnection(CommandView command);
// 7.1.27
void AcceptSynchronousConnection(CommandView command);
// 7.1.28
void RejectSynchronousConnection(CommandView command);
// 7.1.45
void EnhancedSetupSynchronousConnection(CommandView command);
// 7.1.46
void EnhancedAcceptSynchronousConnection(CommandView command);
// Link Policy Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2
// 7.2.1
void HoldMode(CommandView command);
// 7.2.2
void SniffMode(CommandView command);
// 7.2.3
void ExitSniffMode(CommandView command);
// 7.2.6
void QosSetup(CommandView command);
// 7.2.7
void RoleDiscovery(CommandView command);
// 7.2.8
void SwitchRole(CommandView command);
// 7.2.9
void ReadLinkPolicySettings(CommandView command);
// 7.2.10
void WriteLinkPolicySettings(CommandView command);
// 7.2.11
void ReadDefaultLinkPolicySettings(CommandView command);
// 7.2.12
void WriteDefaultLinkPolicySettings(CommandView command);
// 7.2.13
void FlowSpecification(CommandView command);
// 7.2.14
void SniffSubrating(CommandView command);
// Link Controller Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3
// 7.3.1
void SetEventMask(CommandView command);
// 7.3.2
void Reset(CommandView command);
// 7.3.3
void SetEventFilter(CommandView command);
// 7.3.10
void DeleteStoredLinkKey(CommandView command);
// 7.3.11
void WriteLocalName(CommandView command);
// 7.3.12
void ReadLocalName(CommandView command);
// 7.3.13 - 7.3.14
void ReadConnectionAcceptTimeout(CommandView command);
void WriteConnectionAcceptTimeout(CommandView command);
// 7.3.15 - 7.3.16
void ReadPageTimeout(CommandView command);
void WritePageTimeout(CommandView command);
// 7.3.17 - 7.3.18
void ReadScanEnable(CommandView command);
void WriteScanEnable(CommandView command);
// 7.3.19 - 7.3.20
void ReadPageScanActivity(CommandView command);
void WritePageScanActivity(CommandView command);
// 7.3.21 - 7.3.22
void ReadInquiryScanActivity(CommandView command);
void WriteInquiryScanActivity(CommandView command);
// 7.3.23 - 7.3.24
void ReadAuthenticationEnable(CommandView command);
void WriteAuthenticationEnable(CommandView command);
// 7.3.25 - 7.3.26
void ReadClassOfDevice(CommandView command);
void WriteClassOfDevice(CommandView command);
// 7.3.27 - 7.3.28
void ReadVoiceSetting(CommandView command);
void WriteVoiceSetting(CommandView command);
// 7.3.35
void ReadTransmitPowerLevel(CommandView command);
// 7.3.36 - 7.3.37
void ReadSynchronousFlowControlEnable(CommandView command);
void WriteSynchronousFlowControlEnable(CommandView command);
// 7.3.39
void HostBufferSize(CommandView command);
// 7.3.42
void WriteLinkSupervisionTimeout(CommandView command);
// 7.3.43
void ReadNumberOfSupportedIac(CommandView command);
// 7.3.44 - 7.3.45
void ReadCurrentIacLap(CommandView command);
void WriteCurrentIacLap(CommandView command);
// 7.3.47
void ReadInquiryScanType(CommandView command);
// 7.3.48
void WriteInquiryScanType(CommandView command);
// 7.3.49
void ReadInquiryMode(CommandView command);
// 7.3.50
void WriteInquiryMode(CommandView command);
// 7.3.52
void ReadPageScanType(CommandView command);
// 7.3.52
void WritePageScanType(CommandView command);
// 7.3.56
void WriteExtendedInquiryResponse(CommandView command);
// 7.3.57
void RefreshEncryptionKey(CommandView command);
// 7.3.59
void WriteSimplePairingMode(CommandView command);
// 7.3.60
void ReadLocalOobData(CommandView command);
// 7.3.61
void ReadInquiryResponseTransmitPowerLevel(CommandView command);
// 7.3.66
void EnhancedFlush(CommandView command);
// 7.3.69
void SetEventMaskPage2(CommandView command);
// 7.3.74
void ReadEnhancedTransmitPowerLevel(CommandView command);
// 7.3.79
void WriteLeHostSupport(CommandView command);
// 7.3.92
void WriteSecureConnectionsHostSupport(CommandView command);
// 7.3.95
void ReadLocalOobExtendedData(CommandView command);
// Informational Parameters Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4
// 7.4.5
void ReadBufferSize(CommandView command);
// 7.4.1
void ReadLocalVersionInformation(CommandView command);
// 7.4.6
void ReadBdAddr(CommandView command);
// 7.4.2
void ReadLocalSupportedCommands(CommandView command);
// 7.4.3
void ReadLocalSupportedFeatures(CommandView command);
// 7.4.4
void ReadLocalExtendedFeatures(CommandView command);
// 7.4.8
void ReadLocalSupportedCodecsV1(CommandView command);
// Status Parameters Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.5
// 7.5.1 - 7.5.2
void ReadFailedContactCounter(CommandView command);
void ResetFailedContactCounter(CommandView command);
// 7.5.4
void ReadRssi(CommandView command);
// 7.5.7
void ReadEncryptionKeySize(CommandView command);
// Test Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.7
// 7.7.1
void ReadLoopbackMode(CommandView command);
// 7.7.2
void WriteLoopbackMode(CommandView command);
// LE Controller Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8
// 7.8.1
void LeSetEventMask(CommandView command);
// 7.8.2 - 7.8.93
void LeReadBufferSizeV1(CommandView command);
void LeReadBufferSizeV2(CommandView command);
// 7.8.3
void LeReadLocalSupportedFeatures(CommandView command);
// 7.8.4
void LeSetRandomAddress(CommandView command);
// 7.8.5 - 7.8.9
void LeSetAdvertisingParameters(CommandView command);
void LeReadAdvertisingPhysicalChannelTxPower(CommandView command);
void LeSetAdvertisingData(CommandView command);
void LeSetScanResponseData(CommandView command);
void LeSetAdvertisingEnable(CommandView command);
// 7.8.10 - 7.8.11
void LeSetScanParameters(CommandView command);
void LeSetScanEnable(CommandView command);
// 7.8.12 - 7.8.13
void LeCreateConnection(CommandView command);
void LeCreateConnectionCancel(CommandView command);
// 7.8.14 - 7.8.17
void LeReadFilterAcceptListSize(CommandView command);
void LeClearFilterAcceptList(CommandView command);
void LeAddDeviceToFilterAcceptList(CommandView command);
void LeRemoveDeviceFromFilterAcceptList(CommandView command);
// 7.8.18
void LeConnectionUpdate(CommandView command);
// 7.8.21
void LeReadRemoteFeatures(CommandView command);
// 7.8.22
void LeEncrypt(CommandView command);
// 7.8.23
void LeRand(CommandView command);
// 7.8.24
void LeStartEncryption(CommandView command);
// 7.8.25 - 7.8.26
void LeLongTermKeyRequestReply(CommandView command);
void LeLongTermKeyRequestNegativeReply(CommandView command);
// 7.8.27
void LeReadSupportedStates(CommandView command);
// 7.8.31 - 7.8.32
void LeRemoteConnectionParameterRequestReply(CommandView command);
void LeRemoteConnectionParameterRequestNegativeReply(CommandView command);
// 7.8.34 - 7.8.35
void LeReadSuggestedDefaultDataLength(CommandView command);
void LeWriteSuggestedDefaultDataLength(CommandView command);
// 7.8.38 - 7.8.41
void LeAddDeviceToResolvingList(CommandView command);
void LeRemoveDeviceFromResolvingList(CommandView command);
void LeClearResolvingList(CommandView command);
void LeReadResolvingListSize(CommandView command);
// 7.8.42 - 7.8.43
void LeReadPeerResolvableAddress(CommandView command);
void LeReadLocalResolvableAddress(CommandView command);
// 7.8.44 - 7.8.45
void LeSetAddressResolutionEnable(CommandView command);
void LeSetResolvablePrivateAddressTimeout(CommandView command);
// 7.8.46
void LeReadMaximumDataLength(CommandView command);
// 7.8.47 - 7.8.49
void LeReadPhy(CommandView command);
void LeSetDefaultPhy(CommandView command);
void LeSetPhy(CommandView command);
// 7.8.52 - 7.8.60
void LeSetAdvertisingSetRandomAddress(CommandView command);
void LeSetExtendedAdvertisingParameters(CommandView command);
void LeSetExtendedAdvertisingData(CommandView command);
void LeSetExtendedScanResponseData(CommandView command);
void LeSetExtendedAdvertisingEnable(CommandView command);
void LeReadMaximumAdvertisingDataLength(CommandView command);
void LeReadNumberOfSupportedAdvertisingSets(CommandView command);
void LeRemoveAdvertisingSet(CommandView command);
void LeClearAdvertisingSets(CommandView command);
// 7.8.61 - 7.8.63
void LeSetPeriodicAdvertisingParameters(CommandView command);
void LeSetPeriodicAdvertisingData(CommandView command);
void LeSetPeriodicAdvertisingEnable(CommandView command);
// 7.8.67 - 7.8.69
void LePeriodicAdvertisingCreateSync(CommandView command);
void LePeriodicAdvertisingCreateSyncCancel(CommandView command);
void LePeriodicAdvertisingTerminateSync(CommandView command);
// 7.8.70 - 7.8.73
void LeAddDeviceToPeriodicAdvertiserList(CommandView command);
void LeRemoveDeviceFromPeriodicAdvertiserList(CommandView command);
void LeClearPeriodicAdvertiserList(CommandView command);
void LeReadPeriodicAdvertiserListSize(CommandView command);
// 7.8.64 - 7.8.65
void LeSetExtendedScanParameters(CommandView command);
void LeSetExtendedScanEnable(CommandView command);
// 7.8.66
void LeExtendedCreateConnection(CommandView command);
// 7.8.77
void LeSetPrivacyMode(CommandView command);
// 7.8.108
void LeRequestPeerSca(CommandView command);
// 7.8.115
void LeSetHostFeature(CommandView command);
// Vendor-specific Commands
void LeGetVendorCapabilities(CommandView command);
void LeBatchScan(CommandView command);
void LeApcf(CommandView command);
void LeGetControllerActivityEnergyInfo(CommandView command);
void LeExSetScanParameters(CommandView command);
void GetControllerDebugInfo(CommandView command);
// CSR vendor command.
// Implement the command specific to the CSR controller
// used specifically by the PTS tool to pass certification tests.
void CsrVendorCommand(CommandView command);
void CsrReadVarid(CsrVarid varid, std::vector<uint8_t>& value) const;
void CsrWriteVarid(CsrVarid varid, std::vector<uint8_t> const& value) const;
void CsrReadPskey(CsrPskey pskey, std::vector<uint8_t>& value) const;
void CsrWritePskey(CsrPskey pskey, std::vector<uint8_t> const& value);
// Command pass-through.
void ForwardToLm(CommandView command);
void ForwardToLl(CommandView command);
protected:
// Controller configuration.
ControllerProperties properties_;
// Link Layer state.
LinkLayerController link_layer_controller_{address_, properties_, id_};
private:
// Send a HCI_Command_Complete event for the specified op_code with
// the error code UNKNOWN_OPCODE.
void SendCommandCompleteUnknownOpCodeEvent(
bluetooth::hci::OpCode op_code) const;
// Callbacks to send packets back to the HCI.
std::function<void(std::shared_ptr<bluetooth::hci::AclBuilder>)> send_acl_;
std::function<void(std::shared_ptr<bluetooth::hci::EventBuilder>)>
send_event_;
std::function<void(std::shared_ptr<bluetooth::hci::ScoBuilder>)> send_sco_;
std::function<void(std::shared_ptr<bluetooth::hci::IsoBuilder>)> send_iso_;
// Loopback mode (Vol 4, Part E ยง 7.6.1).
// The local loopback mode is used to pass the android Vendor Test Suite
// with RootCanal.
bluetooth::hci::LoopbackMode loopback_mode_{LoopbackMode::NO_LOOPBACK};
// Random value generator, always seeded with 0 to be deterministic.
std::mt19937_64 random_generator_{};
// Flag set to true after the HCI Reset command has been received
// the first time.
bool controller_reset_{false};
// Map command opcodes to the corresponding bit index in the
// supported command mask.
static const std::unordered_map<OpCode, OpCodeIndex>
hci_command_op_code_to_index_;
// Map all implemented opcodes to the function implementing the handler
// for the associated command. The map should be a subset of the
// supported_command field in the properties_ object. Commands
// that are supported but not implemented will raise a fatal assert.
using CommandHandler =
std::function<void(DualModeController*, bluetooth::hci::CommandView)>;
static const std::unordered_map<OpCode, CommandHandler> hci_command_handlers_;
};
} // namespace rootcanal