The Fuchsia Bluetooth system (a.k.a. Sapphire) provides a modern, dual mode implementation of the Bluetooth Host Subsystem (5.0+) supporting a number of Low Energy and Traditional profiles.
The Sapphire stack is organized in three major layers with communication between layers happening via FIDL and Zircon channels: driver, host, and profile.
The driver layer is responsible for discovery and communication with controller hardware in two stages:
SCO, ACL, and HCI sockets are connected to the bt-host component through the Bluetooth Hardware HCI Protocol.
The host layer is comprised of the bt-init, bt-host, and bt-gap components.
The bt-init component is eagerly started on a Fuchsia system to discover and connect bt-host components as well as manage the lifetime of ambient profile components and route protocols through pairing and RFCOMM passthrough components.
One bt-host is started for each connected controller, and manages host state as well as sending commands and receiving events, tracking state, and managing connections. It also contains Low Energy advertising and GATT handlers, and an SDP server. L2CAP and GATT traffic is routed through bt-host and sent to the above associated profiles.
The bt-gap component coordinates the system Bluetooth state to all of the bt-host components, serves the system APIs and routes connections from profile and protocol components to the active host.
The profile layer encompasses all profile components included in the product assembly. Profiles are enabled by including them. They register themselves with the host layer when started. Common profile configurations will be provided in separate Assembly Input Bundles and are documented in their individual directories and/or bundles. Profile components are independently testable and updatable.
Source code shortcuts:
For more information about the structure of the Sapphire stack, please refer to the Bluetooth Architecture guide, or READMEs in specific subdirectories.
For a note on used (and avoided) vocabulary, see Bluetooth Vocabulary
Examples using Fuchsia's Bluetooth Low Energy APIs can be found here.
Dual-mode (LE + Classic) GAP operations that are typically exposed to privileged clients are performed using the fuchsia.bluetooth.sys protocol. This API is intended for managing local adapters, device discovery & discoverability, pairing/bonding, and global settings.
bt-cli is a command-line front-end for privileged access operations:
$ bt-cli bt> list-adapters Adapter: Identifier: e5878e9f642d8908 Address: 34:13:E8:86:8C:19 Technology: DualMode Local Name: siren-relic-wad-pout Discoverable: false Discovering: false Local UUIDs: None
See the bluetooth/tools package for more information on available command line tools for testing/debugging.
Your build configuration may or may not include Bluetooth tests. Ensure Bluetooth tests are built and installed when paving or OTA'ing with
$ fx set workstation_eng.x64 --with //src/connectivity/bluetooth,//bundles/tools
The Bluetooth codebase follows the Fuchsia testing best practices. In general, the Bluetooth codebase defines an associated unit test binary for each production binary and library, as well as a number of integration test binaries. Without good reason, no code should be added without an appropriate (unit, integration, etc) corresponding test. Look in the
GN file of a production binary or library to find its associated unit tests.
For more information, see the Fuchsia testing guide.
Run all the bt-host unit tests:
$ fx test //src/connectivity/bluetooth/core/bt-host
Run a specific test within
$ fx test //src/connectivity/bluetooth/core/bt-host -- --gtest_filter='Foo.Bar'
Foo.Bar are the fixture name and the test name, respectively.
To see all options for running these tests, run
fx test --help.
If you don't have physical hardware available, you can run the tests in the Fuchsia emulator (FEMU) using the same commands as above. See the instructions for FEMU.
TODO(fxbug.dev/96421): Updated Integration Documentation
The most reliable way to enable higher log verbosity is to enable them using kernel command line parameters. The
//src/connectivity/bluetooth:driver-debug-logging target is provided as a convenience to add all the existing chipsets and should be included in
dev_bootfs_labels, for example using the
fx set command:
fx set core.x64 --args="dev_bootfs_labels=[\"//src/connectivity/bluetooth:driver-debug-logging\"]"
fx set writes these values into the image, so they will survive a system restart. For more detail on driver logging, see Zircon driver logging
All other components can be controlled at runtime, using the diagnostics selector method. For example, to show all logs up to
DEBUG level in the A2DP profile component, use:
ffx log --select core/bt-a2dp#DEBUG
Component monikers can be found using
ffx component list.
On Fuchsia, Sapphire supports inspection through the Inspect API. With the exception of the driver layer, all components expose information through inspect. Each component's documentation includes an example of the expected inspect tree.
ffx inspect show bootstrap/driver_manager --file class/bt-host/000.inspectexposes information about the controller, peers, and services.
ffx inspect show core/bluetooth-core/bt-gapexposes information on host devices managed by bt-gap, pairing capabilities, stored bonds, and actively connected peers.
ffx inspect show core/bt-a2dpexposes information on audio streaming capabilities and active streams
ffx inspect show core/bt-snoopexposes information about which HCI devices are being logged and how much data is stored.
ffx inspect show core/bluetooth-core/*
ffx inspect show core/bt-*
See the ffx documentation for complete instructions on using
TODO(fxbug.dev/54127): Find a better link for ffx inspect usage
Inclusivity is central to Fuchsia's culture, and our values include treating each other with dignity. As such, it’s important that everyone can contribute without facing the harmful effects of bias and discrimination.
Bluetooth Core Specification 5.3 updated certain terms that were identified as inappropriate to more inclusive versions. For example, usages of ‘master’ and ‘slave’ were changed to ‘central’ and ‘peripheral’, respectively. We have transitioned our code's terminology to the more appropriate language. We no longer allow uses of the prior terms. For more information, see the Appropriate Language Mapping Table published by the Bluetooth SIG.
See the Fuchsia project guide on best practices for more information.