# bluetooth_core
The shared Rust crate behind the Bluetooth LE FFI. It wraps the
[btleplug](https://github.com/deviceplug/btleplug) host/central library and
exposes a small synchronous, pollable C ABI that the
[`bluetooth_dart`](../../packages/bluetooth_dart) package binds over `dart:ffi`,
and that the [`bluetooth_cli`](../bluetooth_cli) binary uses directly.
BLE only. btleplug is host/central mode and does not support Bluetooth Classic.
## What it does
A session owns a tokio runtime and the first available adapter. A background
task drains btleplug's event stream into a bounded queue and caches discovered
peripherals by id, so the host can poll events (device discovered/updated,
connected/disconnected, notifications) without callbacks across the FFI
boundary. Per-call operations (connect, discover services, read, write,
subscribe, unsubscribe) bridge the async btleplug API back to the blocking ABI.
BLE payloads cross the ABI as JSON, because they are variable-length and nested
(a peripheral carries maps of manufacturer/service data; a service carries a
list of characteristics). The Dart side decodes these verbatim.
On macOS and iOS the crate also reads and requests the CoreBluetooth
authorization status via objc2-core-bluetooth, which btleplug does not surface.
Other platforms have no app-level Bluetooth permission and report unsupported.
## Build and test
```sh
cargo build --manifest-path native/bluetooth_core/Cargo.toml
cargo test --manifest-path native/bluetooth_core/Cargo.toml
```
The crate builds a `cdylib` (for FFI from Dart), a `staticlib` (for static
linking, for example on iOS), and an `rlib` (so the in-repo CLI, example, and
tests can call the API directly). A no-FFI example is included:
```sh
cargo run --manifest-path native/bluetooth_core/Cargo.toml --example scan
```
For Flutter apps the [`bluetooth_flutter`](../../packages/bluetooth_flutter)
plugin builds this crate automatically via cargokit; you do not build it by
hand.