Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update README and rust doc #27

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,42 @@

[![CI](https://github.com/embassy-rs/trouble/actions/workflows/ci.yaml/badge.svg)](https://github.com/embassy-rs/trouble/actions/workflows/ci.yaml)

*WIP* Basic functionality works, however API is likely to change a bit. Use [`nrf-softdevice`](https://github.com/embassy-rs/nrf-softdevice) for the time being if you want a production ready BLE Rust stack for nRF.
TrouBLE is a Bluetooth Low Energy (BLE) Host implementation written in Rust, with a future goal of qualification. The initial implementation was based on [`bleps`](https://github.com/bjoernQ/bleps) but has been adopted to work with types and traits from [`bt-hci`](https://github.com/alexmoon/bt-hci).

TrouBLE is a Bluetooth Low Energy (BLE) Host implementation written in Rust, with a future goal of qualification.
### What is a Host?

The initial implementation was based on [`bleps`](https://github.com/bjoernQ/bleps) but has been adopted to work with [`bt-hci`](https://github.com/alexmoon/bt-hci), which implements Rust types for the HCI specification as well as an interface
for a BLE Controller.
A BLE Host is one side of the Host Controller Interface (HCI). The BLE specification defines the software of a BLE implementation in terms of a `controller` (lower layer) and a `host` (upper layer).

### HCI what?
These communicate via a standardized protocol, that may run over different transports such as as UART, USB or a custom in-memory IPC implementation.

The advantage of this split is that the Host can generally be reused for different controller implementations.

## Hardware support

TrouBLE can use any controller that implements the traits from `bt-hci`. At present, that includes:

* [nRF Softdevice Controller](https://github.com/alexmoon/nrf-sdc). Use [`nrf-softdevice`](https://github.com/embassy-rs/nrf-softdevice) for the time being if you want a production ready BLE Rust stack for nRF.
* [Zephyr UART HCI](https://docs.zephyrproject.org/latest/samples/bluetooth/hci_uart/README.html).
* [Raspberry Pi Pico W](https://github.com/embassy-rs/embassy/pull/2865) - This is still WIP and largely untested.

The BLE specification defines the software of a BLE implementation in terms of a `controller` (lower layer) and a `host` (upper layer). These communicate via a standardized protocol called the Host-Controller Interface (HCI), which can operate over different transports such as UART, USB or a custom IPC implementation.

## Current status

The implementation has some basic functionality working:
The implementation has the following functionality working:

* Peripheral role - advertise as a peripheral and accept connections.
* Central role - scan for devices and establish connections.
* Basic GATT server supporting write, read, notifications
* L2CAP CoC (Connection oriented Channels) with credit management (for both central and peripheral)
* Runs on any transport supporting the `Controller` and `ControllerCmd` traits from `bt-hci`. The `SerialTransport` and `ExternalController` helper types can be used to create additional implementations.

## Example
See the [issues](https://github.com/embassy-rs/trouble/issues) for a list of TODOs.

## Examples

See `examples` for example applications. Currently there are two examples:

* `nrf-sdc` for the nRF52 based using the [`nrf-sdc`](https://github.com/alexmoon/nrf-sdc) crate.
* `serial-hci` which runs on a PC using a HCI controller attached via a serial port (Such as [this Zephyr sample](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/samples/bluetooth/hci_uart/README.html)).
* `serial-hci` which runs on std using a controller attached via a serial port (Such as [this Zephyr sample](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/samples/bluetooth/hci_uart/README.html)).

## License

Expand Down
15 changes: 15 additions & 0 deletions host/src/adapter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//! Adapter
//!
//! The adapter module contains the main entry point for the TrouBLE host.
use core::future::pending;
use core::task::Poll;

Expand Down Expand Up @@ -42,13 +45,18 @@ use crate::types::l2cap::{
use crate::{attribute::AttributeTable, gatt::GattServer};
use crate::{AdapterError, Address, Error};

/// HostResources holds the resources used by the host.
///
/// The packet pool is used by the adapter to multiplex data streams, by allocating space for
/// incoming packets and dispatching to the appropriate connection and channel.
pub struct HostResources<M: RawMutex, const CHANNELS: usize, const PACKETS: usize, const L2CAP_MTU: usize> {
pool: PacketPool<M, L2CAP_MTU, PACKETS, CHANNELS>,
}

impl<M: RawMutex, const CHANNELS: usize, const PACKETS: usize, const L2CAP_MTU: usize>
HostResources<M, CHANNELS, PACKETS, L2CAP_MTU>
{
/// Create a new instance of host resources with the provided QoS requirements for packets.
pub fn new(qos: Qos) -> Self {
Self {
pool: PacketPool::new(qos),
Expand All @@ -61,6 +69,13 @@ pub trait VendorEventHandler {
fn on_event(&self, event: &Vendor<'_>);
}

/// A BLE Host adapter.
///
/// The adapter holds the runtime state of the host, and is the entry point
/// for all interactions with the controller.
///
/// The adapter performs connection management, l2cap channel management, and
/// multiplexes events and data across connections and l2cap channels.
pub struct Adapter<
'd,
M,
Expand Down
1 change: 1 addition & 0 deletions host/src/advertise.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Advertisement config.
pub use bt_hci::param::{AdvChannelMap, AdvFilterPolicy, PhyKind};
use bt_hci::param::{AdvEventProps, AdvHandle, AdvSet};
use embassy_time::Duration;
Expand Down
8 changes: 7 additions & 1 deletion host/src/connection.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! BLE connection.
use bt_hci::cmd::le::LeConnUpdate;
use bt_hci::cmd::link_control::Disconnect;
use bt_hci::cmd::status::ReadRssi;
Expand Down Expand Up @@ -45,10 +46,11 @@ impl Connection {
Self { handle }
}

pub fn handle(&self) -> ConnHandle {
pub(crate) fn handle(&self) -> ConnHandle {
self.handle
}

/// Request disconnection of this connection handle.
pub fn disconnect<
M: RawMutex,
T: Controller + ControllerCmdSync<Disconnect>,
Expand All @@ -65,6 +67,7 @@ impl Connection {
Ok(())
}

/// The connection role for this connection.
pub fn role<
M: RawMutex,
T: Controller,
Expand All @@ -81,6 +84,7 @@ impl Connection {
Ok(role)
}

/// The peer address for this connection.
pub fn peer_address<
M: RawMutex,
T: Controller,
Expand All @@ -97,6 +101,7 @@ impl Connection {
Ok(addr)
}

/// The RSSI value for this connection.
pub async fn rssi<
M: RawMutex,
T,
Expand All @@ -115,6 +120,7 @@ impl Connection {
Ok(ret.rssi)
}

/// Update connection parameters for this connection.
pub async fn set_connection_params<
M: RawMutex,
T,
Expand Down
1 change: 1 addition & 0 deletions host/src/l2cap.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! L2CAP channels.
use bt_hci::cmd::link_control::Disconnect;
use bt_hci::controller::{Controller, ControllerCmdSync};
use bt_hci::param::DisconnectReason;
Expand Down
3 changes: 3 additions & 0 deletions host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ mod attribute_server;
#[cfg(feature = "gatt")]
pub mod gatt;

/// A BLE address.
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Address {
Expand All @@ -55,13 +56,15 @@ impl Address {
}
}

/// Errors returned by the adapter.
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AdapterError<E> {
Controller(E),
Adapter(Error),
}

/// Errors related to Host.
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
Expand Down
1 change: 1 addition & 0 deletions host/src/scan.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Scan config.
use core::iter::FusedIterator;

use bt_hci::param::{AddrKind, BdAddr, LeAdvReport, LeExtAdvReport};
Expand Down
1 change: 1 addition & 0 deletions host/src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Common types.
pub(crate) mod l2cap;
pub(crate) mod primitives;
pub mod uuid;