From 541e6080d6e939230dead1a2bfc13208b298ccb7 Mon Sep 17 00:00:00 2001 From: Rob Dobson Date: Sat, 24 Oct 2026 22:30:27 +0200 Subject: [PATCH] fix(winrtble): open GATT services before discovering their characteristics Some peripherals' services refuse GetCharacteristicsWithCacheModeAsync with GattCommunicationStatus::AccessDenied until the service has been opened, so discover_services() returned the service with no characteristics. Open each service with GattSharingMode::SharedReadAndWrite first. If opening fails, discovery is tried as before. --- src/winrtble/ble/device.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/winrtble/ble/device.rs b/src/winrtble/ble/device.rs index aeba8276..579d0642 100644 --- a/src/winrtble/ble/device.rs +++ b/src/winrtble/ble/device.rs @@ -22,7 +22,7 @@ use windows::{ BluetoothLEPreferredConnectionParameters, GenericAttributeProfile::{ GattCharacteristic, GattCommunicationStatus, GattDescriptor, GattDeviceService, - GattDeviceServicesResult, GattSession, + GattDeviceServicesResult, GattSession, GattSharingMode, }, }, Foundation::TypedEventHandler, @@ -129,6 +129,16 @@ impl BLEDevice { pub async fn get_characteristics( service: &GattDeviceService, ) -> Result> { + // Some services refuse characteristic discovery (AccessDenied) until they have been + // opened. Opening shared doesn't stop other apps using the service, and if it fails + // discovery is still tried as before. + match service.OpenAsync(GattSharingMode::SharedReadAndWrite) { + Ok(op) => match op.await { + Ok(status) => trace!("service open status {:?}", status), + Err(e) => debug!("service open failed {:?}", e), + }, + Err(e) => debug!("service open failed {:?}", e), + } let async_result = match timeout( GATT_CACHE_TIMEOUT, service