ble-windows-server 0.2.0

A simple BLE GATT server library for Windows using WinRT APIs
# ble-windows-server


A simple, ergonomic BLE GATT server library for Windows using WinRT APIs.

[![Crates.io](https://img.shields.io/crates/v/ble-windows-server.svg)](https://crates.io/crates/ble-windows-server)
[![Documentation](https://docs.rs/ble-windows-server/badge.svg)](https://docs.rs/ble-windows-server)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features


- Create BLE GATT services with read/notify characteristics
- Automatic Bluetooth adapter discovery and selection
- Multiple data type support (strings, numbers, JSON, raw bytes)
- Async/await support with Tokio
- Zero-copy where possible
- Windows 10/11 support via WinRT

## Requirements


- Windows 10 (1803+) or Windows 11
- Bluetooth adapter with BLE peripheral role support
- Rust 1.70+

## Installation


Add to your `Cargo.toml`:

```toml
[dependencies]
ble-windows-server = "0.1"
tokio = { version = "1", features = ["full"] }
```

For JSON serialization support:

```toml
[dependencies]
ble-windows-server = { version = "0.1", features = ["json"] }
```

## Quick Start


```rust
use ble_windows_server::{WindowsBLEGattServer, Uuid};

#[tokio::main]

async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a server with a custom service UUID
    let service_uuid = Uuid::parse_str("12345678-1234-5678-1234-567812345678")?;
    let mut server = WindowsBLEGattServer::new("MyDevice".into(), service_uuid);

    // Start advertising
    server.start().await?;

    // Send notifications
    server.notify_str("Hello BLE!").await?;

    Ok(())
}
```

## API Overview


### Creating a Server


```rust
// Basic creation (characteristic UUID auto-generated)
let server = WindowsBLEGattServer::new("DeviceName".into(), service_uuid);

// With explicit characteristic UUID
let server = WindowsBLEGattServer::with_characteristic(
    "DeviceName".into(),
    service_uuid,
    characteristic_uuid,
);
```

### Adapter Selection


```rust
use ble_windows_server::list_adapters;

// List available adapters
let adapters = list_adapters().await?;
for adapter in &adapters {
    println!("{}", adapter);  // [0] Intel Bluetooth - MAC: AA:BB:CC:DD:EE:FF
}

// Use a specific adapter
server.use_adapter(&adapters[0]);

// Or use the default
server.use_default_adapter();
```

### Sending Notifications


```rust
// Raw bytes
server.notify(&[0x01, 0x02, 0x03]).await?;

// Strings
server.notify_str("Hello World").await?;

// Formatted strings
server.notify_fmt(format_args!("Temp: {:.1}C", 23.5)).await?;

// Numbers (little-endian)
server.notify_u8(255).await?;
server.notify_i16(-1000).await?;
server.notify_u32(123456).await?;
server.notify_f32(3.14159).await?;
server.notify_f64(2.718281828).await?;

// Boolean
server.notify_bool(true).await?;  // Sends 0x01

// JSON (requires "json" feature)
#[derive(serde::Serialize)]

struct SensorData {
    temperature: f32,
    humidity: u8,
}

server.notify_json(&SensorData {
    temperature: 23.5,
    humidity: 65,
}).await?;
// Sends: {"temperature":23.5,"humidity":65}
```

### Server Lifecycle


```rust
// Start the server
server.start().await?;

// Check if running
if server.is_running() {
    // Send data...
}

// Stop explicitly (also called on drop)
server.stop()?;
```

### Accessors


```rust
let name = server.device_name();           // "MyDevice"
let svc_uuid = server.service_uuid();      // Service UUID
let char_uuid = server.characteristic_uuid(); // Characteristic UUID
let running = server.is_running();         // true/false
```

## Complete Example


```rust
use std::time::Duration;
use tokio::time::sleep;
use ble_windows_server::{list_adapters, WindowsBLEGattServer, Uuid};

#[tokio::main]

async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Discover adapters
    let adapters = list_adapters().await?;
    println!("Found {} adapter(s)", adapters.len());

    // Create and configure server
    let uuid = Uuid::parse_str("12345678-1234-5678-1234-567812345678")?;
    let mut server = WindowsBLEGattServer::new("SensorHub".into(), uuid);

    // Start advertising
    server.start().await?;
    println!("BLE server started!");
    println!("Service UUID: {}", server.service_uuid());

    // Broadcast loop
    let mut counter = 0u32;
    loop {
        counter += 1;
        server.notify_fmt(format_args!("Count: {}", counter)).await?;
        sleep(Duration::from_secs(1)).await;
    }
}
```

## Testing with nRF Connect


1. Install [nRF Connect]https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-mobile on your phone
2. Run your BLE server application
3. Open nRF Connect and scan for devices
4. Connect to your device
5. Navigate to the service UUID
6. Enable notifications on the characteristic
7. Watch the data stream in!

## Troubleshooting


### "No Bluetooth adapters found"


- Ensure Bluetooth is enabled in Windows Settings
- Check that your adapter supports BLE peripheral role
- Try running as Administrator

### Adapter doesn't support peripheral role


Not all Bluetooth adapters support acting as a BLE peripheral. Check adapter capabilities:

```rust
let adapters = list_adapters().await?;
for adapter in &adapters {
    println!("Peripheral supported: {}", adapter.peripheral_supported);
}
```

### Device not visible in scans


- Windows may use the computer's Bluetooth name instead of the provided device name
- Ensure `SetIsDiscoverable(true)` is set (default in this library)
- Try restarting Bluetooth in Windows Settings

## License


MIT License - see [LICENSE](LICENSE) for details.

## Contributing


Contributions welcome! Please open an issue or PR on GitHub.