blob: ad296f8c895a6033d4c1b9f8c4eb423c6bab73fc [file] [log] [blame]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.hardware.bluetooth;
using fuchsia.bluetooth as bt;
using fuchsia.bluetooth.bredr as bredr;
// Protocols in this file all used for emulated devices and not needed for vendor implementations
// TODO(https://fxbug.dev/42162739): Add state structures for other LE and BR/EDR operations.
// TODO(armansito): Add ability to publish GATT services
// TODO(armansito): Add ability to publish SDP records
// TODO(armansito): Add ability to specify Bluetooth HCI version.
/// Defines the list of HCI protocol error codes that a Bluetooth controller can report. These
/// values are taken from Bluetooth Core Specification v5.4, Vol 2, Part D, Section 1.3
type HciError = flexible enum : uint8 {
SUCCESS = 0x00;
UNKNOWN_COMMAND = 0x01;
UNKNOWN_CONNECTION_ID = 0x02;
HARDWARE_FAILURE = 0x03;
PAGE_TIMEOUT = 0x04;
AUTHENTICATION_FAILURE = 0x05;
PIN_OR_KEY_MISSING = 0x06;
MEMORY_CAPACITY_EXCEEDED = 0x07;
CONNECTION_TIMEOUT = 0x08;
CONNECTION_LIMIT_EXCEEDED = 0x09;
SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED = 0x0A;
CONNECTION_ALREADY_EXISTS = 0x0B;
COMMAND_DISALLOWED = 0x0C;
CONNECTION_REJECTED_LIMITED_RESOURCES = 0x0D;
CONNECTION_REJECTED_SECURITY = 0x0E;
CONNECTION_REJECTED_BAD_BD_ADDR = 0x0F;
CONNECTION_ACCEPT_TIMEOUT_EXCEEDED = 0x10;
UNSUPPORTED_FEATURE_OR_PARAMETER = 0x11;
INVALID_HCICOMMAND_PARAMETERS = 0x12;
REMOTE_USER_TERMINATED_CONNECTION = 0x13;
REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES = 0x14;
REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF = 0x15;
CONNECTION_TERMINATED_BY_LOCAL_HOST = 0x16;
REPEATED_ATTEMPTS = 0x17;
PAIRING_NOT_ALLOWED = 0x18;
UNKNOWN_LMP_PDU = 0x19;
UNSUPPORTED_REMOTE_FEATURE = 0x1A;
SCO_OFFSET_REJECTED = 0x1B;
SCO_INTERVAL_REJECTED = 0x1C;
SCO_AIR_MODE_REJECTED = 0x1D;
INVALID_LMP_OR_LL_PARAMETERS = 0x1E;
UNSPECIFIED_ERROR = 0x1F;
UNSUPPORTED_LMP_OR_LL_PARAMETER_VALUE = 0x20;
ROLE_CHANGE_NOT_ALLOWED = 0x21;
LMP_OR_LL_RESPONSE_TIMEOUT = 0x22;
LMP_ERROR_TRANSACTION_COLLISION = 0x23;
LMP_PDU_NOT_ALLOWED = 0x24;
ENCRYPTION_MODE_NOT_ACCEPTABLE = 0x25;
LINK_KEY_CANNOT_BE_CHANGED = 0x26;
REQUESTED_QOS_NOT_SUPPORTED = 0x27;
INSTANT_PASSED = 0x28;
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29;
DIFFERENT_TRANSACTION_COLLISION = 0x2A;
RESERVED0 = 0x2B;
QOS_UNACCEPTABLE_PARAMETER = 0x2C;
QOS_REJECTED = 0x2D;
CHANNEL_CLASSIFICATION_NOT_SUPPORTED = 0x2E;
INSUFFICIENT_SECURITY = 0x2F;
PARAMETER_OUT_OF_MANDATORY_RANGE = 0x30;
RESERVED1 = 0x31;
ROLE_SWITCH_PENDING = 0x32;
RESERVED2 = 0x33;
RESERVED_SLOT_VIOLATION = 0x34;
ROLE_SWITCH_FAILED = 0x35;
EXTENDED_INQUIRY_RESPONSE_TOO_LARGE = 0x36;
SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST = 0x37;
HOST_BUSY_PAIRING = 0x38;
CONNECTION_REJECTED_NO_SUITABLE_CHANNEL_FOUND = 0x39;
CONTROLLER_BUSY = 0x3A;
UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B;
DIRECTED_ADVERTISING_TIMEOUT = 0x3C;
CONNECTION_TERMINATED_MIC_FAILURE = 0x3D;
CONNECTION_FAILED_TO_BE_ESTABLISHED = 0x3E;
MAC_CONNECTION_FAILED = 0x3F;
COARSE_CLOCK_ADJUSTMENT_REJECTED = 0x40;
TYPE0_SUBMAP_NOT_DEFINED = 0x41;
UNKNOWN_ADVERTISING_IDENTIFIER = 0x42;
LIMIT_REACHED = 0x43;
OPERATION_CANCELLED_BY_HOST = 0x44;
PACKET_TOO_LONG = 0x45;
TOO_LATE = 0x46;
TOO_EARLY = 0x47;
};
type ConnectionState = flexible enum {
CONNECTED = 1;
DISCONNECTED = 2;
};
/// The maximum size (in bytes) of a local name assigned using the HCI_Write_Local_Name command
/// (see Core Specification v5.4, Vol 4, Part E, 7.3.11).
const MAX_LOCAL_NAME_LENGTH uint8 = 248;
/// Advertising data MTUs for legacy (4.x) and extended (5.x) advertising PDU types
/// (see Core Specification v5.4, Vol 4, Part E, Sections 7.3.11 & 7.8.54).
const MAX_LEGACY_ADVERTISING_DATA_LENGTH uint8 = 31;
/// Maximum service records that can be advertised at once.
const MAX_PEER_SERVICES uint8 = 32;
/// Pre-set HCI configurations.
type HciConfig = flexible enum {
/// Support both BR/EDR and LE in LMP features.
DUAL_MODE = 1;
/// Limits supported features and HCI commands to those that are required for LE only.
LE_ONLY = 2;
};
/// The HCI ACL data flow-control parameters.
type AclBufferSettings = table {
/// ACL frame MTU in bytes.
1: data_packet_length uint16;
/// The maximum number of ACL frames that the controller can buffer.
2: total_num_data_packets uint8;
};
/// Controller settings used by the emulator.
type EmulatorSettings = table {
/// The `BD_ADDR` (BR/EDR) or LE Public Device Address. Defaults to "00:00:00:00:00:00".
1: address bt.Address;
/// Supported HCI command configuration. Defaults to "`DUAL_MODE`".
2: hci_config HciConfig;
/// True if the 5.0 extended advertising features are supported. Defaults to "false".
3: extended_advertising bool;
/// The ACL-U data buffer settings. Defaults to
/// data_packet_length: 1024
/// total_num_data_packets: 5
/// IF `hci_config` is set to `DUAL_MODE`. Defaults to null otherwise.
4: acl_buffer_settings AclBufferSettings;
/// The LE-U ACL data buffer settings. Defaults to
/// data_packet_length: 251
/// total_num_data_packets: 5
5: le_acl_buffer_settings AclBufferSettings;
};
/// Error codes that can be generated for emulator-wide configurations.
type EmulatorError = flexible enum {
FAILED = 1;
HCI_ALREADY_PUBLISHED = 2;
};
/// Error codes that are generated for functions that manipulate fake peers.
type EmulatorPeerError = flexible enum {
ADDRESS_REPEATED = 1;
PARAMETERS_INVALID = 2;
NOT_FOUND = 3;
};
type AdvertisingData = table {
1: data vector<uint8>:MAX_LEGACY_ADVERTISING_DATA_LENGTH;
};
/// Parameters used to emulate a peer's behavior over the BR/EDR/Low Energy transport.
type PeerParameters = resource table {
/// The public BR/EDR BD_ADDR address of a peer. This field is mandatory.
1: address bt.Address;
/// When present and true, the peer will send connectable advertisements and accept connection
/// requests. The peer will ignore connection requests if not connectable.
2: connectable bool;
/// Server end of channel bound to Peer protocol.
3: channel server_end:Peer;
};
/// Contains Bluetooth controller & baseband parameters that are writable by the host but don't
/// fall under a particular procedural category (as are those defined below).
type ControllerParameters = table {
/// The local name used for the Link Layer name discovery procedure. This parameter only applies
/// for the BR/EDR transport. In LE, the local name is provided as an advertising parameter and
/// via GATT.
1: local_name string:MAX_LOCAL_NAME_LENGTH;
/// The local "Class of Device" used during the BR/EDR inquiry procedure.
2: device_class bt.DeviceClass;
};
/// Represents the LE scan state. The fields are present if scan parameters have been configured.
type LeScanState = table {
/// True if a scan is enabled.
1: enabled bool;
/// True if an active scan is enabled. Otherwise the scan is passive.
2: active bool;
/// The scan interval and window parameters. These are defined in Bluetooth controller
/// "timeslices" where 1 slice = 0.625 ms. Valid values range from 0x4 (2.5 ms) to 0x4000 (10.24
/// ms).
3: interval uint16;
4: window uint16;
/// True if duplicate filtering has been enabled.
5: filter_duplicates bool;
/// The type of local device address used.
6: address_type bt.AddressType;
};
/// LE legacy advertising types from Bluetooth Core Specification v5.4, Vol 4, Part E, 7.8.5.
type LegacyAdvertisingType = strict enum : uint8 {
/// Connectable and scannable.
ADV_IND = 0;
/// Connectable, high-duty cycle, directed.
ADV_DIRECT_IND = 1;
/// Scannable, undirected.
ADV_SCAN_IND = 2;
/// Non-connectable, undirected
ADV_NONCONN_IND = 3;
/// Scan response
SCAN_RSP = 4;
};
/// Controller parameters for legacy advertising.
type LegacyAdvertisingState = table {
/// True if advertising has been enabled using the HCI_LE_Set_Advertising_Enable command.
/// This field is always present.
1: enabled bool;
/// The most recently configured advertising type. This field is always present. Defaults to
/// [`fuchsia.hardware.bluetooth/LegacyAdvertisingType.ADV_IND`].
2: type LegacyAdvertisingType;
/// The LE address type being used for advertising. This field is always present. Defaults to
/// [`fuchsia.bluetooth/AddressType.PUBLIC`].
3: address_type bt.AddressType;
/// The host-specified advertising interval range parameters. Present only if configured.
4: interval_min uint16;
5: interval_max uint16;
/// Any configured advertising and scan response data. Present only if either field is non-zero.
6: advertising_data AdvertisingData;
7: scan_response AdvertisingData;
};
/// Protocol used to drive the state of a fake peer device.
open protocol Peer {
/// Assign a HCI `status` for the controller to generate in response to connection requests.
/// Applies to all successive HCI_Create_Connection and HCI_LE_Create_Connection commands. The
/// procedure is acknowledged with an empty response.
flexible AssignConnectionStatus(struct {
status HciError;
}) -> ();
/// Emulates a LE connection event. Does nothing if the peer is already connected. The
/// `role` parameter determines the link layer connection role.
flexible EmulateLeConnectionComplete(struct {
role bt.ConnectionRole;
});
/// Emulate disconnection. Does nothing if the peer is not connected.
flexible EmulateDisconnectionComplete();
/// Returns a vector of the least to most recent controller connection states.
/// This method returns when there has been a state change since the last invocation of this
/// method by this client.
///
/// Multiple calls to this method can be outstanding at a given time. All calls will resolve in
/// a response as soon as there is a change to the scan state.
// TODO(https://fxbug.dev/345262024): Update to single hanging get call
flexible WatchConnectionStates() -> (struct {
states vector<ConnectionState>:MAX;
});
/// Sets the device class reported in the inquiry response for this peer during device
/// discovery. If the peer is not BR/EDR, the server will close with the `ZX_ERR_NOT_SUPPORTED`
/// epitaph.
flexible SetDeviceClass(bt.DeviceClass) -> ();
/// Sets the peer's services that will be discoverable via Service Discovery Protocol. If the
/// peer is not BR/EDR, the server will close with the `ZX_ERR_NOT_SUPPORTED` epitaph.
flexible SetServiceDefinitions(struct {
service_definitions vector<bredr.ServiceDefinition>:MAX_PEER_SERVICES;
}) -> ();
flexible SetLeAdvertisement(table {
/// The LE address of the peer.
1: le_address bt.Address;
/// The advertising data contents. If not present, the advertising data sent by this peer
/// will be empty.
2: advertisement AdvertisingData;
/// The scan response data contents. When present, the fake controller will generate
/// scannable advertising packets and scan response events.
3: scan_response AdvertisingData;
}) -> () error EmulatorPeerError;
};
/// Protocol used to emulate a Bluetooth controller that supports the standard Bluetooth HCI.
/// Represents the bt-emulator device protocol. A bt-emulator device is used for configuring and
/// publishing fake bt-hci devices.
@discoverable
open protocol Emulator {
/// Publish a bt-hci device using the provided `settings`. Each Emulator instance can only
/// manage a single bt-hci device. Returns Emulator.`HCI_ALREADY_PUBLISHED` if the device has
/// already been published.
flexible Publish(EmulatorSettings) -> () error EmulatorError;
/// Inserts a new LE peer device to be emulated by this controller. Once registered, the state
/// of the fake peer can be driven and observed using the `peer` handle.
///
/// A reply will be sent to acknowledge the creation of the fake peer. If a peer cannot be
/// initialized (e.g. due to a missing required field in `parameters` or for containing an
/// address that is already emulated) the `peer` handle will be closed and an error reply will
/// be sent.
///
/// The peer will appear in advertising reports and respond to requests according to its
/// configuration as long as the `peer` channel is open. The emulator stops emulating this peer
/// when the channel gets closed, which makes it no longer discoverable and not respond to any
/// requests.
flexible AddLowEnergyPeer(PeerParameters) -> () error EmulatorPeerError;
/// Inserts a new BR/EDR peer device to be emulated by this controller. Once registered, the state
/// of the fake peer can be driven and observed using the `peer` handle.
///
/// A reply will be sent to acknowledge the creation of the fake peer. If a peer cannot be
/// initialized (e.g. due to a missing required field in `parameters` or for containing an
/// address that is already emulated) the `peer` handle will be closed and an error reply will
/// be sent.
///
/// The peer will appear in inquiry results and respond to requests according to its
/// configuration as long as the `peer` channel is open. The emulator stops emulating this peer
/// when the channel gets closed, which makes it no longer discoverable and not respond to any
/// requests.
flexible AddBredrPeer(PeerParameters) -> () error EmulatorPeerError;
/// Hanging get pattern for the controller parameter state will not resolve until the state has
/// changed from the last response.
flexible WatchControllerParameters() -> (ControllerParameters);
/// Returns a vector of the least to most recent states for the link layer LE scan procedure.
/// This method returns when there has been at least one state change since the last invocation
/// of this method by this client.
///
/// Multiple calls to this method can be outstanding at a given time. All calls will resolve in
/// a response as soon as there is a change to the scan state.
// TODO(https://fxbug.dev/345262024): Update to single hanging get call
flexible WatchLeScanStates() -> (struct {
states vector<LeScanState>:MAX;
});
/// Returns a vector of the least to most recent states for the link layer LE legacy
/// advertising procedure. This method returns when there has been at least one state change
/// since the last invocation of this method by this client.
///
/// Multiple calls to this method can be outstanding at a given time. All calls will resolve in
/// a response as soon as there is a change to the scan state.
// TODO(https://fxbug.dev/345262024): Update to single hanging get call
flexible WatchLegacyAdvertisingStates() -> (struct {
states vector<LegacyAdvertisingState>:MAX;
});
};