awear 0.1.0

Rust client for AWEAR EEG devices over BLE using btleplug
Documentation
# 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:

| Key | Action |
|-----|--------|
| `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:

| UUID | Role |
|------|------|
| `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).