Skip to content

[Feature Proposal] Windows: Expose System-Connected BLE Devices & GATT Without Prior Scan Cache (or Document Workaround) #459

@iconFehu

Description

@iconFehu

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions