{ width=100 height=100 }
A Bluetooth stack, written in Python, useful for emulation, test, experimentation, and implementation of any sort of virtual device, with virtual or physical Bluetooth controllers. The project initially only supported BLE (Bluetooth Low Energy), but support for Bluetooth Classic was eventually added. Support for BLE is therefore currently somewhat more advanced than for Classic.
!!! warning This project is still very much experimental and in an alpha state where a lot of things are still missing or broken, and what's there changes frequently. Also, there are still a few hardcoded values/parameters in some of the examples and apps which need to be changed (those will eventually be command line arguments, as appropriate)
The goal of this project is to offer a suite of components that can be put together to implement a number of tasks related to Bluetooth. That's fairly open-ended, but at the very least, it should be possible to:
Some of the configurations that may be useful:
See the use cases page for more use cases.
The project is implemented in Python (Python >= 3.8 is required). A number of APIs for functionality that is inherently I/O bound is implemented in terms of python coroutines with async IO. This means that all of the concurrent tasks run in the same thread, which makes everything much simpler and more predictable.
Components of a Bluetooth stack:
The (virtual) Controller component exposes an HCI interface to a host, and connects to a virtual link-layer bus. Several instances of this class can be connected to the same bus, in which case they can communicate with each other (both broadcast for advertising data and unicast for ACL data). The bus may be process-local, in which case all the controllers attached to the bus run in the same process, or it may be remote (see Remote Link), in which case several controllers in separate processes can communicate with each other.
The Controller component communicates with other virtual controllers through a Link interface. The link interface defines basic functionality like connection, disconnection, sending and receiving ACL data, sending and receiving advertising data, and more. Included in the project are two types of Link interface implementations:
The LocalLink implementation is a simple object used by an application that instantiates more than one Controller objects and connects them in-memory and in-process.
The RemoteLink implementation communicates with other virtual controllers over a WebSocket. Multiple instances of RemoteLink objects communicate with each other through a simple WebSocket relay that can host any number of virtual ‘rooms’, where each ‘room’ is a set of controllers that can communicate between themselves. The link_relay
app is where this relay is implemented.
The Host component connects to a controller over an HCI interface. It is responsible to sending commands and ACL data to the controller and receiving back events and ACL data.
The ChannelManager is responsible for managing L2CAP channels.
The SecurityManager is responsible for pairing/bonding.
The GATT Client offers an API to discover peer services and characteristics, reading and writing characteristics, subscribing to characteristics, and all other GATT client functions.
The GATT Server offers an API to expose services and characteristics, responding to reads and writes on characteristics, handling subscriptions to characteristics, and all other GATT server functions.
SDP implements the service discovery protocol for Bluetooth Classic.
RFComm is a bi-directional serial-port-like protocol. It is used in several profiles.
The Device component it a compound object that ties together a Host, GATT Client, GATT Server, L2CAP channel access, advertising and scanning, and more.
Profiles are ways of using the underlying protocols for certain well-defined used cases, like playing music, implementing a headset, and so on.
A2DP is the Advanced Audio Profile, which enables asynchronous streaming of audio to speakers, or from microphones. Both the “source” (typically music playback source) and “sink” (typically a speaker) functions of A2DP.
Hands Free Profile. Used for headsets.
Human Interface Device. For keyboards, mice, etc.
The Hosts and Controllers communicate over a transport, which is responsible for sending/receiving HCI packets. Several types of transports are supported:
A Bumble Host object communicates with a Bumble Controller object, or external Controller, via a Transport connection. A Bumble Controller object communicates with a Bumble Host, or external Host, via a Transport connection. When both the Host and Controller are Bumble objects, they typically communicate In Process, or via a Link Relay.
See the Transports page for details.
The Host part of the stack can interact with Bumble's Controller implementation, but also with external hardware controllers.
See the Hardware page for details.
See the Examples page
See the Apps & Tools page
The core library should work on any platform on which you can run Python3. Some platforms support features that not all platforms support
See the Platforms page for details.
Future features to be considered include: