# awear-rs
Rust client for [AWEAR](https://www.awear.us) EEG devices over Bluetooth Low Energy.
Provides a library crate (`awear`) for scanning, connecting, authenticating, and streaming EEG data, plus a full-screen terminal UI for real-time waveform visualization.
## Features
- BLE scanning and connection via [btleplug](https://github.com/deviceplug/btleplug)
- HMAC-SHA256 challenge-response authentication (AWEAR handshake protocol)
- LUCA protocol parsing (header + hex-encoded EEG data blocks)
- Legacy packet format fallback (24-bit signed EEG, battery, signal, misc)
- Async event stream via `tokio::sync::mpsc`
- Full-screen TUI with real-time scrolling EEG waveform (ratatui + crossterm)
- Simulation mode for development without hardware (`--simulate`)
## Quick Start
### Library
```rust
use awear::prelude::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = AwearClient::new(AwearClientConfig::default());
let (mut rx, handle) = client.connect().await?;
handle.start().await?;
while let Some(event) = rx.recv().await {
match event {
AwearEvent::Eeg(r) => println!("EEG: {} samples", r.samples.len()),
AwearEvent::Battery(b) => println!("Battery: {}%", b),
_ => {}
}
}
Ok(())
}
```
### Headless CLI
```bash
cargo run --bin awear-rs
```
Scans for AWEAR devices, connects to the first one found, authenticates, sends `START`, and prints all events to stdout.
### Terminal UI
```bash
cargo run --bin tui
```
Full-screen EEG waveform display with:
| `Tab` | Device picker |
| `+` / `-` | Zoom out / in |
| `a` | Auto-scale Y axis |
| `v` | Toggle smoothing overlay |
| `p` / `r` | Pause / resume |
| `c` | Clear waveform |
| `d` | Disconnect |
| `q` / `Esc` | Quit |
Simulation mode (no hardware needed):
```bash
cargo run --bin tui -- --simulate
```
## Building
```bash
# Full build (library + CLI + TUI)
cargo build
# Library only (no TUI dependencies)
cargo build --no-default-features
```
### macOS Bluetooth Permissions
On macOS, Bluetooth access requires an embedded `Info.plist`. The `build.rs` script handles this automatically via `ld -sectcreate`. If scanning returns no devices, ensure Bluetooth is enabled and the terminal has Bluetooth permission in System Settings > Privacy & Security.
## Protocol Overview
The AWEAR device uses a custom BLE protocol over a single GATT service:
| `FC740001-...-45951B5B01D7` | Service |
| `FC740002-...-45951B5B01D7` | TX (write commands to device) |
| `FC740003-...-45951B5B01D7` | RX (notifications from device) |
### Connection Flow
1. **Scan** for devices advertising "AWEAR" in their name
2. **Connect** and discover GATT services
3. **Handshake**: device sends `AWEAR_CONNECTED:<challenge>\n`
4. **Authenticate**: reply with `CRPL:<HMAC-SHA256-truncated>` (write-without-response)
5. **Ready**: device confirms with `AWEAR_READY:...\n`
6. **Stream**: send `START` command to begin EEG data flow
### Data Format (LUCA Protocol)
EEG data arrives as LUCA blocks:
- **LUCA header** (36 bytes): magic `LUCA` + data type + sequence + payload hint
- **Data chunks** (multiple BLE notifications): ASCII hex-encoded, decoded to 16-bit signed big-endian samples
- Single channel, 256 Hz sampling rate
## Crate Structure
```
src/
├── lib.rs # Public API and prelude
├── awear_client.rs # BLE scanning, connection, authentication, event dispatch
├── protocol.rs # GATT UUIDs, constants, HMAC challenge-response
├── types.rs # AwearEvent, EegReading, DeviceStatus, config types
├── parse.rs # LUCA and legacy binary packet parsers
├── main.rs # Headless CLI binary
└── bin/
└── tui.rs # ratatui terminal UI
```
## License
This project is licensed under the [GNU General Public License v3.0](LICENSE).