Pairing agent with support for peripherals sending Slave Security Request
As discussed in https://github.com/hbldh/bleak/pull/1100, the desire of that PR is to provide stable implementation for programmatic pairing using Pin or Passkey Entry pairing methods. However, rare BLE devices can utilize advanced security features, requiring more refined (and bug-risky) operations considering pairing process. I cannot push to that branch, so I'm leaving this PR in Draft state, based to the feature branch of https://github.com/hbldh/bleak/pull/1100. Here I would try to add BlueZ and Windows support for pairing with such devices.
Original implementation of this PR using method of "pre-registering" the pairing agent is archived in https://github.com/bojanpotocnik/bleak/tree/archive/develop/pairing/preregister_agent
- [Y] ~~Use
AsyncExitStackto nest context managers - not applicable in this case~~ - [_] ~~Unregister pairing agent immediately after pairing, not only in
__aexit__~~ - [Y] ~~Check if this is possible on Windows~~
- [_] ~~Implement for Windows~~
After some testing, I discovered that some time can pass between peripheral device sending Slave Security Request and central responding with Pairing Request, so executing connect(), then registering the pairing agent, then calling pair() is fine. However, if the central tries to perform GATT Service Discovery instead of responding to Slave Security Request, the connection will be dropped. This is solved by postoping service discovery until pairing is finished.
I've tested on Windows yesterday and successfully paired the device - however there were many code changes/tweaks, so I'll try to extract what exactly is the changing factor for Windows.
I like the direction this is going.
On Windows, I don't think we can skip discovering services on connect, otherwise the device may not actually connect.
Perhaps, instead of adding the skip_discovering_services option, we could have an option to pair on connect? In the backend connect() method, this would call the OS API to pair instead of connect (if not already paired?) and then get the services.
Moved previous solution to https://github.com/bojanpotocnik/bleak/tree/archive/develop/pairing/skip_service_discovery and implemented your suggestion. Windows implementation in progress.
Now I'm trying to solve this case:
- Devices pair/bond.
- Remote device removed the bond data.
- BlueZ attempts to connect (
PairisTruebecause central does not know that remote deleted the bond data) - Connection fails with
PIN or Key Missing+Authentication Failure(btmon)
This error is not propagated via D-Bus and BlueZ does not try to re-pair (as it should) in such case.
Opened https://github.com/bluez/bluez/issues/433 for issue mentioned in the previous comment.
I think this feature would be really helpful. Would you be open to merging it after a rebase? I could probably handle the rebase if that helps @bojanpotocnik @dlech
Would you be open to merging it after a rebase?
I've been quite busy lately, so I can't promise a quick review. It has been a while, so I'll want to have a good look at this again. We'll also need to implement support on Windows. We can pull from #1100 for that as well.
we could have an option to pair on connect?
The good news is that this has already been implemented in the meantime.
I'm not familiar with the Windows or Android APIs, so I can't really develop or test those versions. I'd keep the warning saying they're not supported, does that work for you ?
Sure, no problem.