# hive-btle
Bluetooth Low Energy mesh transport for tactical edge networking.
[](https://crates.io/crates/hive-btle)
[](https://docs.rs/hive-btle)
[](LICENSE)
## Overview
`hive-btle` provides a cross-platform Bluetooth Low Energy mesh networking stack optimized for resource-constrained tactical devices. It enables peer-to-peer discovery, advertisement, connectivity, and efficient CRDT-based data synchronization over BLE.
### Key Features
- **Cross-Platform**: Linux, Android, iOS, macOS, Windows, ESP32
- **Power Efficient**: Designed for 18+ hour battery life on smartwatches
- **Long Range**: Coded PHY support for 300m+ range (BLE 5.0+)
- **Mesh Topology**: Hierarchical mesh with automatic peer discovery
- **Efficient Sync**: Delta-based CRDT synchronization over GATT
- **Embedded Ready**: `no_std` support for bare-metal targets
### Why hive-btle?
Traditional BLE mesh implementations (like those in commercial sync SDKs) often suffer from:
| Continuous scanning | 20%+ radio duty cycle | Batched sync windows (<5%) |
| Gossip-based discovery | All devices advertise constantly | Hierarchical discovery (leaf nodes don't scan) |
| Full mesh participation | Every device relays everything | Lite profile (minimal state, single parent) |
| **Result** | **3-4 hour watch battery** | **18-24 hour battery life** |
## Status
> **Pre-release**: This crate is under active development. APIs may change.
| Linux (BlueZ) | β
Complete | BlueZ 5.48+ required |
| macOS | β
Complete | CoreBluetooth, tested with ESP32 devices |
| iOS | β
Complete | CoreBluetooth (shared with macOS) |
| ESP32 | β
Complete | ESP-IDF NimBLE integration |
| Android | π In Progress | JNI bindings to Android Bluetooth API |
| Windows | π Planned | WinRT Bluetooth APIs |
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
hive-btle = { version = "0.1", features = ["linux"] }
```
### Feature Flags
| `std` (default) | Standard library support |
| `linux` | Linux/BlueZ support via `bluer` |
| `android` | Android support via JNI |
| `ios` | iOS support via CoreBluetooth |
| `macos` | macOS support via CoreBluetooth |
| `windows` | Windows support via WinRT |
| `embedded` | Embedded/no_std support |
| `esp32` | ESP32 support via ESP-IDF |
| `coded-phy` | Enable Coded PHY for extended range |
| `extended-adv` | Enable extended advertising |
## Quick Start
```rust
use hive_btle::{BleConfig, BluetoothLETransport, NodeId, PowerProfile};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create power-efficient configuration
let config = BleConfig::hive_lite(NodeId::new(0x12345678))
.with_power_profile(PowerProfile::LowPower);
// Create platform adapter (Linux example)
#[cfg(feature = "linux")]
let adapter = hive_btle::platform::linux::BluerAdapter::new().await?;
// Create and start transport
let transport = BluetoothLETransport::new(config, adapter);
transport.start().await?;
// Transport is now advertising and ready for connections
println!("Node {} is running", transport.node_id());
// Connect to a discovered peer
// let conn = transport.connect(&peer_id).await?;
Ok(())
}
```
## Architecture
### Standalone vs HIVE Integration
hive-btle is designed for **dual use**:
1. **Standalone**: Pure embedded mesh (ESP32/Pico devices) without any full HIVE nodes
2. **HIVE Integration**: BLE transport for full HIVE nodes, with gateway translation to Automerge
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HIVE Integration Mode β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Full HIVE Node (Phone) β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β AutomergeIroh β β β
β β β (Full CRDT documents) β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Translation Layer (HIVE repo) β β β
β β β Maps: Automerge β hive-btle lightweight β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β hive-btle β β β
β β β (BLE transport + lightweight CRDTs) β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β BLE β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Embedded Node (ESP32/Pico) β β
β β hive-btle β β
β β (standalone, lightweight CRDTs) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
**Why two modes?** Automerge is too resource-intensive for embedded targets (requires ~10MB+ RAM, `std` library). hive-btle's lightweight CRDTs (GCounter, Peripheral) provide the same semantics in <256KB RAM. Full HIVE nodes translate between formats.
### Component Architecture
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Application β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β BluetoothLETransport β
β (MeshTransport trait implementation) β
ββββββββββββββββ¬βββββββββββββββ¬βββββββββββββββ¬βββββββββββββββββ€
β Discovery β GATT β Mesh β Power β
β (Beacon, β (Service, β (Topology, β (Scheduler, β
β Scanner) β Protocol) β Routing) β Profiles) β
ββββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ΄βββββββββββββββββ€
β BleAdapter Trait β
ββββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββ¬ββββββββββββββββββ€
β Linux β Android β iOS β Windows β ESP32 β
β (BlueZ) β (JNI) β(CoreBT) β (WinRT) β (NimBLE) β
ββββββββββββ΄βββββββββββ΄βββββββββββ΄βββββββββββ΄ββββββββββββββββββ
```
### Core Components
| **Discovery** | HIVE beacon format, scanning, and advertising |
| **GATT** | BLE service definition and sync protocol |
| **Mesh** | Topology management and message routing |
| **PHY** | Physical layer configuration (1M, 2M, Coded) |
| **Power** | Radio scheduling and battery optimization |
| **Sync** | Delta-based CRDT synchronization |
## Power Profiles
| Aggressive | 20% | 1 second | ~6 hours |
| Balanced | 10% | 5 seconds | ~12 hours |
| **LowPower** | **2%** | **30 seconds** | **~20 hours** |
| UltraLow | 0.5% | 2 minutes | ~36 hours |
*Estimated for typical smartwatch (300mAh battery)
## GATT Service
hive-btle defines a custom GATT service for mesh communication:
| `0xF47A` | Service | HIVE BLE Service (16-bit short form) |
| `0x0001` | Node Info | Node ID, capabilities, hierarchy level |
| `0x0002` | Sync State | Vector clock and sync metadata |
| `0x0003` | Sync Data | CRDT delta payloads (chunked) |
| `0x0004` | Command | Control commands (connect, disconnect, etc.) |
| `0x0005` | Status | Connection status and errors |
## Mesh-Wide Encryption
hive-btle supports optional mesh-wide encryption using ChaCha20-Poly1305 AEAD. When enabled, all documents are encrypted before transmission, providing confidentiality across multi-hop BLE relay.
### Enabling Encryption
```rust
use hive_btle::{HiveMesh, HiveMeshConfig, NodeId};
// Create a 32-byte shared secret (distribute securely to all mesh nodes)
let secret: [u8; 32] = [0x42; 32]; // Use a real secret in production!
// Configure mesh with encryption
let config = HiveMeshConfig::new(NodeId::new(0x12345678), "ALPHA-1", "DEMO")
.with_encryption(secret);
let mesh = HiveMesh::new(config);
// All documents sent through this mesh are now encrypted
let encrypted_doc = mesh.build_document();
```
### How It Works
- **Algorithm**: ChaCha20-Poly1305 authenticated encryption
- **Key Derivation**: HKDF-SHA256 from shared secret + mesh ID
- **Overhead**: 30 bytes per document (2 marker + 12 nonce + 16 auth tag)
- **Wire Format**: `ENCRYPTED_MARKER (0xAE) | reserved | nonce | ciphertext`
### Multi-Hop Security
```
Node A ββencryptedββ> Node B (relay) ββencryptedββ> Node C
β
Can forward but
only decrypts if
has formation key
```
Nodes without the shared secret can relay encrypted documents but cannot read their contents. This provides end-to-end confidentiality even across untrusted relay nodes.
### Backward Compatibility
- Encrypted nodes can receive unencrypted documents (for gradual rollout)
- Unencrypted nodes will reject encrypted documents they can't decrypt
## Per-Peer E2EE (End-to-End Encryption)
For sensitive communications, hive-btle supports per-peer end-to-end encryption using X25519 key exchange and ChaCha20-Poly1305. Unlike mesh-wide encryption where all formation members share a key, per-peer E2EE ensures only the sender and recipient can decrypt messagesβeven other mesh members cannot read them.
### Enabling Per-Peer E2EE
```rust
use hive_btle::{HiveMesh, HiveMeshConfig, NodeId};
// Create mesh instances
let config1 = HiveMeshConfig::new(NodeId::new(0x11111111), "ALPHA-1", "DEMO");
let mesh1 = HiveMesh::new(config1);
let config2 = HiveMeshConfig::new(NodeId::new(0x22222222), "BRAVO-1", "DEMO");
let mesh2 = HiveMesh::new(config2);
// Enable E2EE on both nodes (generates identity keys)
mesh1.enable_peer_e2ee();
mesh2.enable_peer_e2ee();
// Initiate E2EE session from mesh1 to mesh2
let key_exchange1 = mesh1.initiate_peer_e2ee(NodeId::new(0x22222222), now_ms).unwrap();
// Send key_exchange1 to mesh2 over BLE...
// mesh2 handles incoming key exchange and responds
let key_exchange2 = mesh2.handle_key_exchange(&key_exchange1, now_ms).unwrap();
// Send key_exchange2 back to mesh1...
// mesh1 completes the handshake
mesh1.handle_key_exchange(&key_exchange2, now_ms);
// Session established! Now send encrypted messages
let encrypted = mesh1.send_peer_e2ee(NodeId::new(0x22222222), b"Secret message", now_ms).unwrap();
// Send encrypted to mesh2...
// mesh2 decrypts
let plaintext = mesh2.handle_peer_e2ee_message(&encrypted, now_ms).unwrap();
assert_eq!(plaintext, b"Secret message");
```
### How It Works
1. **Key Exchange**: X25519 Diffie-Hellman to establish a shared secret
2. **Key Derivation**: HKDF-SHA256 binds the session key to both node IDs
3. **Encryption**: ChaCha20-Poly1305 AEAD with replay protection
4. **Wire Format**: `PEER_E2EE_MARKER (0xAF) | reserved | recipient | sender | counter | nonce | ciphertext`
### Security Properties
| **Forward Secrecy** | Ephemeral keys can be used for session establishment |
| **Replay Protection** | Monotonic counters prevent message replay attacks |
| **Authentication** | Poly1305 MAC ensures message integrity |
| **Confidentiality** | Only sender and recipient can decrypt |
### Overhead
Per-peer E2EE adds 46 bytes overhead per message:
- 2 bytes: Marker header
- 4 bytes: Recipient node ID
- 4 bytes: Sender node ID
- 8 bytes: Counter (replay protection)
- 12 bytes: Nonce
- 16 bytes: Authentication tag
### Use Cases
- **Sensitive Commands**: Squad leader β specific soldier
- **Private Messages**: Point-to-point communication within formation
- **Credential Exchange**: Secure key material distribution
### Encryption Layers
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phase 1: Mesh-Wide (Formation Key) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β All formation members can decrypt β β
β β Protects: External eavesdroppers β β
β β Overhead: 30 bytes β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Phase 2: Per-Peer E2EE (Session Key) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Only sender + recipient can decrypt β β
β β Protects: Other mesh members, compromised relays β β
β β Overhead: 46 bytes β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
## Platform Requirements
### Linux
- BlueZ 5.48 or later
- D-Bus system bus access
- Bluetooth adapter with BLE support
```bash
# Check BlueZ version
bluetoothctl --version
# Ensure bluetooth service is running
sudo systemctl start bluetooth
```
### Android
- Android 6.0 (API 23) or later
- `BLUETOOTH`, `BLUETOOTH_ADMIN`, `ACCESS_FINE_LOCATION` permissions
- For BLE 5.0 features: Android 8.0 (API 26) or later
### iOS
- iOS 13.0 or later
- `NSBluetoothAlwaysUsageDescription` in Info.plist
- CoreBluetooth framework
## Examples
See the [`examples/`](examples/) directory:
- `linux_scanner.rs` - Scan for HIVE nodes on Linux
- `linux_advertiser.rs` - Advertise as a HIVE node
- `mesh_demo.rs` - Two-node mesh demonstration
Run examples with:
```bash
cargo run --example linux_scanner --features linux
```
## Testing
```bash
# Run unit tests (no hardware required)
cargo test
# Run with Linux platform tests (requires Bluetooth adapter)
cargo test --features linux
# Run specific test module
cargo test sync::
```
## Contributing
Contributions are welcome! Priority areas:
1. **Android Implementation** - JNI bindings to Android Bluetooth API
2. **Windows Implementation** - WinRT Bluetooth APIs
3. **Hardware Testing** - Real-world validation on various devices
Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
## License
Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.
## Acknowledgments
Developed by [(r)evolve - Revolve Team LLC](https://revolveteam.com) as part of the HIVE Protocol project.