hbldh / bleak

A cross platform Bluetooth Low Energy Client for Python using asyncio
MIT License
1.82k stars 300 forks source link

Unreachable, WinRT, GattSessionStatus.CLOSED possible Solution #1340

Open uutzinger opened 1 year ago

uutzinger commented 1 year ago

Description

I am working on a program to read Samsung gearVRC (remote controller). Its a device that does not have windows drivers but one can directly read it with a custom program (https://github.com/rdady/gear-vr-controller-linux)

I was able to scan for devices, services and characteristics on the device using the standard service_explorer.py example, however I was getting the "Unreachable" and not connected errors.

I found that a reliable way to solve the problem is by removing the device from the system and starting with a system that has no prior knowledge of the bluetooth device:

- Settings
- Bluetooth & devices 
- Devices
- Click on 3 dots next to the device name
- Remove Device
- Bluetooth Slider to Off and back to On
- If device reappears, repeat removal (above two steps), after one repetition device should be permanently removed

The unreachable problem is likely Windows related as it also occurs with BLEConsole (https://github.com/sensboston/BLEConsole) Hypothesis is that when bluetooth connection is closed, Windows retains device information that triggers a disconnection (either by Windows or the device itself). Its also possible that the incorrect device information is related to pairing. Since there is no BLE command line tool for pairing in Windows, its difficult to test.

Request

It would be useful if the documentation section Troubleshooting would list how to completely remove a Bluetooth device from a Windows system, and suggesting this as troubleshooting step before investigating the device with Wireshark.

What I Did

I made my own program to read the battery status of my device and below, in LOG file section, is the sample output. One can see that the GattService is getting closed before its possible to read the characteristic. The same behaviour can be seen with examples/service_explorer.py:

py -3 .\service_explorer.py --name 'Gear VR Controller(17DB)'

I attempted changing options for

BleakClient(myDevice, winrt=dict(address_type='public', use_cached_services=True))

which did NOT solve the unreachable issue.

I removed battery from the device to reset it. It did NOT solve the issue.

I attempted pairing with:

paired = await client.pair(protection_level=2)
print("{} is {}".format(DEVICE_NAME, 'paired' if paired else 'not paired'))

regardless of the protection_level, bleak reports device is NOT paired.

I removed the device from the system as described above and it SOLVED the issue. I need to remove the device manually each time before I can use it though.

Therefore, I attempted creating a powershell script for automatic device removal (see below) but so far I have NOT been able to mimic the manual steps listed above.

$device = Get-PnpDevice -FriendlyName "Gear VR Controller(17DB)"
pnputil.exe /remove-device $device.InstanceId
Restart-Service -Name bthserv -Force
Update-HostStorageCache

Logs

Reading Value...
Gear VR Controller(17DB) is connected
DEBUG:bleak.backends.winrt.client:session_status_changed_event_handler: id: BluetoothLE#BluetoothLEe0:d4:64:23:f6:1c-2c:ba:ba:2e:17:db, error: BluetoothError.SUCCESS, status: GattSessionStatus.CLOSED
DEBUG:bleak.backends.winrt.client:closing requester
DEBUG:bleak.backends.winrt.client:closing session
00002a19-0000-1000-8000-00805f9b34fb (Handle: 10): Battery Level: (['read', 'notify']), Error Could not read characteristic handle 10: Unreachable
dlech commented 1 year ago

BleakClient(myDevice, winrt=dict(address_type='public', use_cached_services=True))

Did you try use_cached_services=False?

Did you log Bluetooth packets with wireshark to see the disconnect reason?