Motivation / use case
On Windows, our application needs to interact with BLE peripherals that are already connected at the OS level (e.g. user paired/connected the device in Settings, or another app holds the connection) before our process starts or without running a scan first.
With the current btleplug workflow, adapter.peripherals() is largely populated from discovery/scan cache. In that situation, the target device may be missing from peripherals(), so we cannot obtain a Peripheral and cannot call connect() / discover_services() / read-write / notify through the normal path—even though the device is connected from Windows' point of view.
Workaround:
We worked around this by using WinRT (windows-rs) in parallel:
- Enumerate connected devices via
BluetoothLEDevice::GetDeviceSelectorFromConnectionStatus(Connected) + DeviceInformation::FindAllAsyncAqsFilter.
- Open GATT using
BluetoothLEDevice::FromBluetoothAddressAsync and WinRT GATT APIs when the address is known but btleplug has no cached Peripheral.
We would prefer to reduce or eliminate this dual stack if btleplug can support (or officially document) this scenario.
Current behavior
After Manager::new() / adapter init, peripherals() may be empty or not contain a device that Windows reports as connected, until a scan has populated the cache (and even then behavior can differ).
There is no first-class API (as far as we know) to:
- list OS-connected LE devices, or
- obtain a Peripheral / GATT session by Bluetooth address without going through discovery cache first.
Requested enhancement (high level)
Any subset of the following would help:
- Enumerate connected peripherals on Windows (and ideally other platforms where meaningful), aligned with how the OS exposes "connected" LE devices—not only "seen while scanning".
- Peripheral from address (or equivalent): given a known BDAddr / PeripheralId, resolve a handle usable for connect + GATT even when the device was not discovered in the current session—or a documented, supported pattern that stays within btleplug.
- If full API support is out of scope: official documentation in README / book describing Windows limitations and recommended approach (scan vs WinRT vs pairing), so downstream apps don't each re-implement WinRT.
Platform / version
- OS: Windows 10/11
- btleplug: (fill in your version, e.g. 0.11.x)
- Rust: (fill in)
Additional note (UUID display)
We also observed that converting WinRT GUID fields to a UUID string must use the correct endianness for the first fields (Uuid::from_fields vs from_fields_le) to match SIG-style 0000xxxx-0000-1000-8000-00805f9b34fb strings. If btleplug ever surfaces WinRT UUIDs directly, matching that convention would avoid confusion.
Willingness to contribute
We maintain a local fork and can help with a PR (Windows-only behind clear API + error types) if maintainers agree on direction.
Related Issues:
This proposal is based on recurring user issues and platform differences. See above for workarounds and how this would help downstream users.
Motivation / use case
On Windows, our application needs to interact with BLE peripherals that are already connected at the OS level (e.g. user paired/connected the device in Settings, or another app holds the connection) before our process starts or without running a scan first.
With the current btleplug workflow,
adapter.peripherals()is largely populated from discovery/scan cache. In that situation, the target device may be missing fromperipherals(), so we cannot obtain aPeripheraland cannot callconnect()/discover_services()/ read-write / notify through the normal path—even though the device is connected from Windows' point of view.Workaround:
We worked around this by using WinRT (windows-rs) in parallel:
BluetoothLEDevice::GetDeviceSelectorFromConnectionStatus(Connected)+DeviceInformation::FindAllAsyncAqsFilter.BluetoothLEDevice::FromBluetoothAddressAsyncand WinRT GATT APIs when the address is known but btleplug has no cached Peripheral.We would prefer to reduce or eliminate this dual stack if btleplug can support (or officially document) this scenario.
Current behavior
After
Manager::new()/ adapter init,peripherals()may be empty or not contain a device that Windows reports as connected, until a scan has populated the cache (and even then behavior can differ).There is no first-class API (as far as we know) to:
Requested enhancement (high level)
Any subset of the following would help:
Platform / version
Additional note (UUID display)
We also observed that converting WinRT GUID fields to a UUID string must use the correct endianness for the first fields (
Uuid::from_fieldsvsfrom_fields_le) to match SIG-style0000xxxx-0000-1000-8000-00805f9b34fbstrings. If btleplug ever surfaces WinRT UUIDs directly, matching that convention would avoid confusion.Willingness to contribute
We maintain a local fork and can help with a PR (Windows-only behind clear API + error types) if maintainers agree on direction.
Related Issues:
This proposal is based on recurring user issues and platform differences. See above for workarounds and how this would help downstream users.