A Rust library and terminal UI for streaming real-time EEG data from BrainBit headband devices via the NeuroSDK2 C library.
Rust FFI wrapper with 100% API parity — all 175 functions from sdk_api.h
bound, all types from cmn_type.h mapped to #[repr(C)] Rust equivalents,
SHA-256 integrity verification, and OS-level network sandboxing.
cargo add brainbit| Device | BLE Name | Scanner Family | Channels | Hz | How to distinguish |
|---|---|---|---|---|---|
| BrainBit (original) | BrainBit |
LEBrainBit |
4 (O1, O2, T3, T4) | 250 | FwMajor < 100 |
| Flex (v1) | BrainBit |
LEBrainBit |
4 (relocatable) | 250 | FwMajor >= 100 |
| BrainBit 2 | BrainBit |
LEBrainBit2 |
up to 8 | 250 | — |
| BrainBit Pro | BB Pro |
LEBrainBitPro |
up to 8 | 250 | — |
| Flex 4 | Flex |
LEBrainBitFlex |
4 | 250 | SensModel == 2 |
| Flex 8 | Flex Pro |
LEBrainBitFlex |
8 | 250 | SensModel == 3 |
| Callibri | — | LECallibri |
1 (EEG/EMG/ECG/EDA) | configurable | — |
| Headphones | — | LEHeadPhones |
7 | 250 | — |
| Headphones 2 | — | LEHeadPhones2 |
4 | 250 | — |
| Headband | — | LEHeadband |
4 | 250 | — |
| NeuroEEG | — | LENeuroEEG |
up to 24 | configurable | — |
All devices communicate over BLE. The NeuroSDK2 library handles the full Bluetooth stack internally — no external BLE library needed.
Works on Windows, Linux, and macOS. The neurosdk2 shared library
(neurosdk2.dll / libneurosdk2.so / libneurosdk2.dylib) is loaded at
runtime via libloading — no build-time C dependencies, no bindgen, no
system headers.
| Requirement | Notes |
|---|---|
| Rust ≥ 1.75 | rustup update stable |
| NeuroSDK2 native library | Run ./sdk/download.sh (auto-downloads + verifies) |
| BLE adapter | Built-in or USB Bluetooth adapter |
| Platform | Repository | File |
|---|---|---|
| Windows | neurosdk2-cpp | neurosdk2-x64.dll / neurosdk2-x32.dll |
| Linux | linux_neurosdk2 | libneurosdk2.so |
| macOS | apple_neurosdk2 | libneurosdk2.dylib (universal x86_64 + arm64) |
Use brainbit as a library in your own project:
[dependencies]
# Full build (includes the ratatui TUI feature):
brainbit = "0.0.2"
# Library only — skips ratatui / crossterm compilation:
brainbit = { version = "0.0.2", default-features = false }use brainbit::prelude::*;
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Optional: block internet access for the process
block_internet()?;
// Scan for devices
let scanner = Scanner::new(&[SensorFamily::LEBrainBit])?;
scanner.start()?;
std::thread::sleep(Duration::from_secs(5));
scanner.stop()?;
let devices = scanner.devices()?;
let mut device = BrainBitDevice::connect(&scanner, &devices[0])?;
println!("Connected: {}", device.name()?);
println!("Battery: {}%", device.battery_level()?);
// Stream 4 seconds of EEG
let samples = device.capture_signal(BRAINBIT_SAMPLING_RATE as usize * 4)?;
for s in &samples[..5] {
println!(
"#{}: O1={:.6}V O2={:.6}V T3={:.6}V T4={:.6}V",
s.pack_num, s.channels[0], s.channels[1], s.channels[2], s.channels[3]
);
}
device.disconnect()?;
Ok(())
}cargo run --bin brainbit --no-default-features
RUST_LOG=debug cargo run --bin brainbit --no-default-featuresReal-time 4-channel EEG waveform display in the terminal:
cargo run --bin brainbit-tuiThree layers of defense for the closed-source native library:
# At download time (automatic)
./sdk/download.sh
# At runtime (opt-in)
BRAINBIT_VERIFY_SDK=1 cargo run
# Programmatic
verify_library("/path/to/libneurosdk2.dylib")?;Downloads from exact commit SHAs, not main. Update sdk/download.sh
to upgrade.
use brainbit::prelude::*;
block_internet()?; // irrevocable — process can never reach the internet
// BLE still works (uses IPC, not sockets)| Platform | Mechanism | Blocks | Allows |
|---|---|---|---|
| Linux | seccomp-bpf | AF_INET/AF_INET6 sockets |
AF_UNIX (D-Bus), AF_BLUETOOTH |
| macOS | Seatbelt sandbox | network-outbound (remote) |
XPC (CoreBluetooth), IPC |
| Windows | Windows Firewall rule | Outbound TCP/UDP | WinRT Bluetooth APIs |
brainbit-rs/
├── Cargo.toml
├── README.md
├── CHANGELOG.md
├── LICENSE
└── src/
├── lib.rs # Crate root: modules + prelude
├── main.rs # Headless CLI binary
├── bin/
│ └── tui.rs # Full-screen TUI binary (ratatui)
├── ffi.rs # Cross-platform NeuroSDK2 FFI (runtime-loaded, 175 functions)
├── types.rs # #[repr(C)] FFI types matching cmn_type.h
├── scanner.rs # BLE device scanner
├── device.rs # High-level device API (signal, resist, battery)
├── error.rs # BrainBitError
├── verify.rs # SHA-256 integrity verification
└── sandbox.rs # OS-level network sandboxing
├── sdk/
│ ├── download.sh # Download + verify native libraries
│ └── checksums.sha256 # Pinned SHA-256 hashes
├── examples/
│ ├── scan.rs # Device discovery
│ ├── stream.rs # Signal streaming with callback
│ ├── resist.rs # Electrode resistance measurement
│ └── sandbox_test.rs # Network sandbox verification
└── tests/
└── types_tests.rs # FFI type layouts, enum values, ABI checks (29 tests)
# Scan for devices
cargo run --example scan
# Stream EEG data with callback
cargo run --example stream
# Measure electrode resistance
cargo run --example resist
# Verify network sandbox works
cargo run --example sandbox_test| Crate | Purpose |
|---|---|
| libloading | Runtime DLL/so/dylib loading for NeuroSDK2 |
| thiserror | Error type derivation |
| log | Logging facade |
| env_logger | Log output for binaries |
| libc | seccomp-bpf syscalls (Linux sandbox) |
| ratatui | Terminal UI (optional, tui feature) |
| crossterm | Terminal backend (optional, tui feature) |
cargo test29 unit tests cover FFI type layouts, enum discriminant values, ABI struct sizes, string extraction, SHA-256 correctness, and sampling frequency conversion — all run without hardware.