gtec
A Rust library and terminal UI for g.tec Unicorn EEG devices via the Unicorn C API and Bluetooth protocol.
Rust FFI wrapper with 100% API parity — all 16 functions from unicorn.h bound,
all types mapped to #[repr(C)] Rust equivalents, plus a pure-Rust Bluetooth
protocol implementation for macOS support.
Installation
cargo add gtec
Supported devices
| Device | Type | Channels | Resolution | Hz | Connection | Status |
|---|---|---|---|---|---|---|
| Unicorn Hybrid Black | EEG headset | 8 EEG + 3 accel + 3 gyro + battery + counter (17 total) | 24-bit | 250 | Classic Bluetooth RFCOMM | ✅ Full support |
| Unicorn Naked | OEM board (same HW) | Same as Hybrid Black | 24-bit | 250 | Classic Bluetooth RFCOMM | ✅ Full support (same device) |
| Unicorn BCI Core-8 | EEG amplifier kit | 8 EEG | 24-bit | 250 | Bluetooth 5 (BLE) | ✅ Full support (libgtecble + pure-Rust BLE) |
Unicorn BCI Core-8 support
The BCI Core-8 is supported via g.tec's official libgtecble BLE library, found
in the gtec-ble PyPI package published by
gtec-medical-engineering/gpype
(g.tec's official Python SDK). The ffi_ble module binds all 9 exported functions:
| Function | Purpose |
|---|---|
GTECBLE_GetApiVersion |
API version |
GTECBLE_GetLastErrorText |
Last error description |
GTECBLE_StartScanning |
Start BLE device scan |
GTECBLE_StopScanning |
Stop BLE device scan |
GTECBLE_RegisterDeviceDiscoveredCallback |
Callback when device found |
GTECBLE_OpenDevice |
Connect to device by serial |
GTECBLE_CloseDevice |
Disconnect device |
GTECBLE_RegisterDataAvailableCallback |
Callback for streaming data |
GTECBLE_GetDeviceInformation |
Device info (model, serial, firmware) |
Platform support for BCI Core-8:
| Platform | Library | Source |
|---|---|---|
| Windows (x64) | libgtecble.dll (311 KB) |
PyPI gtec-ble wheel |
| macOS (universal) | libgtecble.dylib (927 KB) |
PyPI gtec-ble wheel |
| Linux (x64) | Pure-Rust ble.rs via btleplug |
No native lib needed |
Other g.tec devices (not supported)
| Device | Why not supported |
|---|---|
| Unicorn tDCS Core-2 | Transcranial stimulator, not EEG |
| g.USBamp | Proprietary gAPI (commercial license, not on GitHub) |
| g.Nautilus | Proprietary gAPI |
| g.HIamp | Proprietary gAPI |
Cross-platform
Works on Windows, Linux, and macOS.
Hybrid Black
| Platform | Backend | Source |
|---|---|---|
| Windows (x64) | Unicorn.dll via ffi |
unicorn-bi/Unicorn-Hybrid-Black-Windows-APIs → c-api/Lib/ |
| Linux (x64) | libunicorn.so via ffi |
unicorn-bi/Unicorn-Suite-Hybrid-Black → Unicorn Linux C API/x64/Lib/ |
| macOS | Pure-Rust protocol.rs over BT RFCOMM |
No native lib needed |
BCI Core-8
| Platform | Backend | Source |
|---|---|---|
| Windows (x64) | libgtecble.dll via ffi_ble |
PyPI gtec-ble v2.0.1 |
| macOS (universal) | libgtecble.dylib via ffi_ble |
PyPI gtec-ble v2.0.1 |
| Linux (x64) | Pure-Rust ble.rs via btleplug |
No native lib needed |
| All OS | Pure-Rust ble.rs via btleplug |
cargo add gtec --features ble |
The ble feature (enabled by default) provides a pure-Rust BLE backend using
btleplug that works on all platforms
without any native library. GATT UUIDs were extracted from g.tec's official
libgtecble.dylib.
Note: g.tec does not provide a macOS native library, but this crate includes
a pure-Rust Bluetooth protocol implementation (protocol.rs) that enables macOS
support by communicating directly with the device over RFCOMM. The protocol was
implemented from the official UnicornBluetoothProtocol.pdf.
Protocol details
The Unicorn uses classic Bluetooth RFCOMM with a simple binary protocol:
| Element | Format |
|---|---|
| Start acquisition | 0x61 0x7C 0x87 → ACK 0x00 0x00 0x00 |
| Stop acquisition | 0x63 0x5C 0xC5 → ACK 0x00 0x00 0x00 |
| Payload (250 Hz) | 45 bytes per sample |
Payload structure:
[0..1] Header: 0xC0 0x00
[2] Battery: 4-bit voltage in low nibble
[3..26] EEG 1–8: 3 bytes each (24-bit signed, big-endian)
[27..32] Accelerometer: 2 bytes each (16-bit signed, little-endian) × 3 axes
[33..38] Gyroscope: 2 bytes each (16-bit signed, little-endian) × 3 axes
[39..42] Counter: 4 bytes (32-bit unsigned, little-endian)
[43..44] Footer: 0x0D 0x0A
Scale factors:
- EEG:
raw × 4500000 / 50331642→ µV - Accelerometer:
raw / 4096→ g - Gyroscope:
raw / 32.8→ °/s - Battery:
(raw & 0x0F) / 15 × 100→ %
Quick start
use *;
Project layout
gtec-rs/
├── Cargo.toml
├── README.md
├── CHANGELOG.md
├── LICENSE
└── src/
├── lib.rs # Crate root + prelude
├── main.rs # CLI binary
├── bin/tui.rs # ratatui TUI (8-channel EEG charts)
├── ffi.rs # Runtime-loaded Unicorn C API for Hybrid Black (16 functions)
├── ffi_ble.rs # Runtime-loaded libgtecble BLE API for BCI Core-8 (9 functions)
├── ble.rs # Pure-Rust BLE backend for BCI Core-8 via btleplug (all OS)
├── types.rs # #[repr(C)] types matching unicorn.h
├── protocol.rs # Pure-Rust BT protocol (45-byte payload decode)
├── device.rs # High-level device API
├── error.rs # Error types
├── 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
│ └── read_eeg.rs # 4-second EEG capture
└── tests/
└── types_tests.rs # FFI type layout + constant + protocol tests
Dependencies
| Crate | Purpose |
|---|---|
| libloading | Runtime DLL/so loading |
| btleplug | Cross-platform BLE (optional, ble feature) |
| tokio | Async runtime for BLE (optional, ble feature) |
| thiserror | Error type derivation |
| log | Logging facade |
| env_logger | Log output |
| libc | seccomp syscalls (Linux) |
| ratatui | Terminal UI (optional) |
| crossterm | Terminal backend (optional) |
Running tests
25 unit tests covering FFI type layouts, enum values, ABI struct sizes, protocol payload decoding (verified against official g.tec example), SHA-256 correctness, and constant validation — all without hardware.