crates.io docs.rs Build Status

Bluest — Cross-platform Bluetooth LE crate for Rust

Bluest is a cross-platform [Bluetooth Low Energy] (BLE) library for [Rust]. It currently supports Windows (version 10 and later), MacOS/iOS, and Linux. Android support is planned.

The goal of Bluest is to create a thin abstraction on top of the platform-specific Bluetooth APIs in order to provide safe, cross-platform access to Bluetooth LE devices. The crate currently supports the GAP Central and GATT Client roles. Peripheral and Server roles are not supported.

Usage

```rust let adapter = Adapter::default().await.okor("Bluetooth adapter not found")?; adapter.waitavailable().await?;

println!("starting scan"); let mut scan = adapter.scan(&[]).await?; println!("scan started"); while let Some(discovereddevice) = scan.next().await { println!( "{}{}: {:?}", discovereddevice.device.name().asderef().unwrapor("(unknown)"), discovereddevice .rssi .map(|x| format!(" ({}dBm)", x)) .unwrapordefault(), discovereddevice.adv_data.services ); } ```

Overview

The primary functions provided by Bluest are:

Asynchronous runtimes

On non-linux platforms, Bluest should work with any asynchronous runtime. On linux the underlying bluer crate requires the Tokio runtime and Bluest makes use of Tokio's block_in_place API (which requires Tokio's multi-threaded runtime) to make a few methods synchronous. Linux-only asynchronous versions of those methods are also provided, which should be preferred in platform-specific code.

Platform specifics

Because Bluest aims to provide a thin abstraction over the platform-specific APIs, the available APIs represent the lowest common denominator of APIs among the supported platforms. In most cases Apple's CoreBluetooth API is the most restricted and therefore imposes the limit on what can be supported in a cross platform library. For example, CoreBluetooth never exposes the Bluetooth address of devices to applications, therefore there is no method on Device for retrieving an address or even any Bluetooth address struct in the crate.

The underlying APIs for accessing services, characteristics, and descriptors are all pretty similar and should behave consistently across platforms. However errors may not be consistent from platform to platform. For example, Linux's bluez API does not return the underlying Bluetooth protocol error in a useful way, whereas the other platforms do. Where it is possible to return a meaningful error, Bluest will attempt to do so. In other cases, Bluest may return an error with a kind of Other and you would need to look at the platform-specific source of the error for more information.

The more significant area of platform differences is in discovering and connecting to devices.

Each platform has its own methods for identifying, scanning for, and connecting to devices. Again, since CoreBluetooth is the most restrictive in the methods it provides for filtering scan results and identifying devices to connect to, the Bluest API largely follows those limitations (e.g. scanning can be filtered only by a set of service UUIDs). The implementations for other platforms have been poly-filled to match those APIs.

Connecting and disconnecting from devices is another area of API differences that cannot be as easily poly-filled. To ensure proper cross-platform behavior, you should always call connect_device before calling any methods which may require a connection. When you have finished using a device you should call disconnect_device and then drop the Device and all its child objects to ensure the OS will properly release any associated resources.

MacOS/iOS (CoreBluetooth)

Connections to devices are managed by the Adapter instance. You must call connect_device before calling any methods on a Device (or child objects) that require a connection or an error will be returned. Because the Adapter manages the connections, all connections will be closed when the Adapter is dropped, therefore you must ensure the Adapter lives as long as you need a connection to any of its devices.

When you call disconnect_device, access to that device will be terminated for the application. If no other applications running on the system have connected to the device, the underlying hardware connection will be closed.

Windows (WinRT)

Connections to devices are managed automatically by the OS. Calls to connect_device and disconnect_device are no-ops that immediately return success. The actual connection will be made as soon as a method is called on a Device that requires a connection (typically discover_services). That connection will be maintained as long as the Device instance or any child instance lives.

Feature flags

The serde feature is available to enable serializing/deserializing device identifiers.

Examples

Examples demonstrating basic usage are available in the [examples folder].

Refer to the [API documentation] for more details.