In src/winrtble/peripheral.rs, the ConnectionStatusChanged handler only flips connected=false on an unexpected disconnect. It does not clear shared.ble_services (unlike explicit disconnect(), which does and documents why).
Failure scenario: device goes out of range → user calls connect() again → a new BLEDevice replaces the old one, and the old one's Drop closes every GattDeviceService. discover_services() then skips every UUID because of if !self.shared.ble_services.contains_key(&uuid), so the cache keeps the closed service/characteristic objects. Every subsequent read/write/subscribe fails until the user calls disconnect() explicitly. Calling connect() while already connected hits the same path.
Fix direction: clear the service cache whenever the underlying device is (re)created / on connect, and/or on unexpected disconnect.
In
src/winrtble/peripheral.rs, theConnectionStatusChangedhandler only flipsconnected=falseon an unexpected disconnect. It does not clearshared.ble_services(unlike explicitdisconnect(), which does and documents why).Failure scenario: device goes out of range → user calls
connect()again → a newBLEDevicereplaces the old one, and the old one'sDropcloses everyGattDeviceService.discover_services()then skips every UUID because ofif !self.shared.ble_services.contains_key(&uuid), so the cache keeps the closed service/characteristic objects. Every subsequent read/write/subscribe fails until the user callsdisconnect()explicitly. Callingconnect()while already connected hits the same path.Fix direction: clear the service cache whenever the underlying device is (re)created / on connect, and/or on unexpected disconnect.