# ble-windows-server
A simple, ergonomic BLE GATT server library for Windows using WinRT APIs.
[](https://crates.io/crates/ble-windows-server)
[](https://docs.rs/ble-windows-server)
[](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.