mendi 0.0.2

Rust client for the Mendi neurofeedback headband over BLE using btleplug
Documentation
//! GATT UUIDs and constants for the Mendi headband BLE protocol (V4).
//!
//! The Mendi headband exposes a custom GATT service with six characteristics,
//! each carrying protobuf-encoded messages as defined in `device_v4.proto`.
//!
//! # UUID namespaces
//!
//! Mendi uses a **vendor-specific** UUID base: `fc3eXXXX-c6c4-49e6-922a-6e551c455af5`.
//! The short codes `ABB0`–`ABB6` are embedded into this base, **not** the
//! standard Bluetooth Base UUID (`0000XXXX-0000-1000-8000-00805f9b34fb`).
//!
//! Standard BLE characteristics (firmware/hardware revision) still use the
//! Bluetooth Base UUID.

use uuid::Uuid;

// ── UUID helpers ─────────────────────────────────────────────────────────────

/// Build a full 128-bit UUID from a 16-bit short code using the **Mendi
/// vendor** base UUID: `fc3eXXXX-c6c4-49e6-922a-6e551c455af5`.
pub const fn mendi_uuid(short: u16) -> Uuid {
    // fc3e{short}-c6c4-49e6-922a-6e551c455af5
    //
    // As a u128 (big-endian):
    //   0xfc3e_XXXX_c6c4_49e6_922a_6e551c455af5
    Uuid::from_u128(
        0xfc3e_0000_c6c4_49e6_922a_6e55_1c45_5af5_u128
            | ((short as u128) << 96),
    )
}

/// Build a full 128-bit UUID from a 16-bit short code using the **standard
/// Bluetooth Base UUID**: `0000XXXX-0000-1000-8000-00805f9b34fb`.
const fn bt_uuid(short: u16) -> Uuid {
    Uuid::from_u128(
        ((short as u128) << 96)
            | 0x0000_0000_1000_8000_0080_5f9b_34fb,
    )
}

// ── Service ──────────────────────────────────────────────────────────────────

/// Primary GATT service UUID: `fc3eabb0-c6c4-49e6-922a-6e551c455af5`.
pub const MENDI_SERVICE_UUID: Uuid = mendi_uuid(0xABB0);

// ── Characteristics ──────────────────────────────────────────────────────────

/// Frame characteristic: `fc3eabb1-c6c4-49e6-922a-6e551c455af5`.
///
/// Real-time fNIRS sensor data: accelerometer, gyroscope, temperature, and
/// 3 optical channels (left, right, pulse) each with IR, red, and ambient
/// light readings.  Subscribe to notifications to stream data.
///
/// Protobuf message: [`Frame`](crate::wire::Frame)
pub const FRAME_CHARACTERISTIC: Uuid = mendi_uuid(0xABB1);

/// Sensor register access characteristic: `fc3eabb2-c6c4-49e6-922a-6e551c455af5`.
///
/// Low-level read/write access to the optical sensor's registers.
/// Write a [`Sensor`](crate::wire::Sensor) message to read or write;
/// subscribe to notifications to receive register read responses.
///
/// Protobuf message: [`Sensor`](crate::wire::Sensor)
pub const SENSOR_CHARACTERISTIC: Uuid = mendi_uuid(0xABB2);

/// IMU register access characteristic: `fc3eabb3-c6c4-49e6-922a-6e551c455af5`.
///
/// Low-level read/write access to the IMU (accelerometer/gyroscope) registers.
///
/// Protobuf message: [`Imu`](crate::wire::Imu)
pub const IMU_CHARACTERISTIC: Uuid = mendi_uuid(0xABB3);

/// ADC / Battery characteristic: `fc3eabb4-c6c4-49e6-922a-6e551c455af5`.
///
/// Battery voltage, charging status, and USB connection status.
/// Subscribe to notifications to monitor battery level.
///
/// Protobuf message: [`Adc`](crate::wire::Adc)
pub const ADC_CHARACTERISTIC: Uuid = mendi_uuid(0xABB4);

/// Diagnostics characteristic: `fc3eabb5-c6c4-49e6-922a-6e551c455af5`.
///
/// Self-test results read at power-on: ADC snapshot, IMU ok, sensor ok.
///
/// Protobuf message: [`Diagnostics`](crate::wire::Diagnostics)
pub const DIAGNOSTICS_CHARACTERISTIC: Uuid = mendi_uuid(0xABB5);

/// Calibration characteristic: `fc3eabb6-c6c4-49e6-922a-6e551c455af5`.
///
/// LED current offsets for left, right, and pulse channels.
/// Auto-calibration enable/disable and low-power mode status.
/// Subscribe to notifications to receive calibration updates.
///
/// Protobuf message: [`Calibration`](crate::wire::Calibration)
pub const CALIBRATION_CHARACTERISTIC: Uuid = mendi_uuid(0xABB6);

// ── Device info (standard BLE characteristics) ───────────────────────────────

/// Standard BLE Firmware Revision String characteristic (`0x2A26`).
pub const FIRMWARE_REVISION: Uuid = bt_uuid(0x2A26);

/// Standard BLE Hardware Revision String characteristic (`0x2A27`).
pub const HARDWARE_REVISION: Uuid = bt_uuid(0x2A27);

// ── Optical channel names ────────────────────────────────────────────────────

/// Human-readable names for the three optical channels.
///
/// Each channel measures IR, red LED, and ambient light:
/// - **Left**: left side of the forehead
/// - **Right**: right side of the forehead
/// - **Pulse**: central / pulse oximetry channel
pub const OPTICAL_CHANNEL_NAMES: [&str; 3] = ["left", "right", "pulse"];

// ── Device name prefix ───────────────────────────────────────────────────────

/// Default BLE advertised name prefix for Mendi headbands.
pub const MENDI_NAME_PREFIX: &str = "Mendi";