Skip to content

Commit dd50aa6

Browse files
committed
bluezdbus/client: Support pairing during connection establishment
This is achieved by passing ``pairing_callbacks`` to the ``BleakClient`` constructor instead of manually calling ``pair()`` method.
1 parent 0c0c16f commit dd50aa6

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

bleak/backends/bluezdbus/client.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,9 @@ def __init__(self, address_or_ble_device: Union[BLEDevice, str], **kwargs):
9696
# used to override mtu_size property
9797
self._mtu_size: Optional[int] = None
9898

99-
if kwargs.get("pairing_callbacks"):
100-
warnings.warn(
101-
"Pairing on connect not yet implemented for BlueZ",
102-
RuntimeWarning,
103-
stacklevel=2,
104-
)
99+
self._pairing_callbacks: Optional[BaseBleakAgentCallbacks] = kwargs.get(
100+
"pairing_callbacks"
101+
)
105102

106103
def close(self):
107104
self._bus.disconnect()
@@ -193,6 +190,11 @@ def on_value_changed(char_path: str, value: bytes) -> None:
193190
#
194191
# For additional details see https://github.com/bluez/bluez/issues/89
195192
#
193+
if self._pairing_callbacks:
194+
# org.bluez.Device1.Pair() will connect to the remote device, initiate
195+
# pairing and then retrieve all SDP records (or GATT primary services).
196+
await self.pair(self._pairing_callbacks)
197+
196198
if not manager.is_connected(self._device_path):
197199
logger.debug("Connecting to BlueZ path %s", self._device_path)
198200
async with async_timeout(timeout):
@@ -400,6 +402,7 @@ async def pair(
400402
member="Pair",
401403
)
402404
)
405+
# TODO: Call "CancelPairing" if this task is cancelled
403406

404407
try:
405408
assert_reply(reply)

examples/pairing_agent.py

+24-11
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ async def request_pin(self, device: BLEDevice) -> str:
5959
return response
6060

6161

62-
async def main(addr: str, unpair: bool) -> None:
62+
async def main(addr: str, unpair: bool, auto: bool) -> None:
6363
if unpair:
6464
print("unpairing...")
6565
try:
@@ -76,16 +76,26 @@ async def main(addr: str, unpair: bool) -> None:
7676
print("device was not found")
7777
return
7878

79-
print("pairing...")
79+
if auto:
80+
print("connecting and pairing...")
8081

81-
async with BleakClient(device) as client, AgentCallbacks() as callbacks:
82-
try:
83-
await client.pair(callbacks)
84-
print("pairing successful")
85-
except BleakPairingCancelledError:
86-
print("paring was canceled")
87-
except BleakPairingFailedError:
88-
print("pairing failed (bad pin?)")
82+
async with AgentCallbacks() as callbacks, BleakClient(
83+
device, pairing_callbacks=callbacks
84+
) as client:
85+
print(f"connection and pairing to {client.address} successful")
86+
87+
else:
88+
print("connecting...")
89+
90+
async with BleakClient(device) as client, AgentCallbacks() as callbacks:
91+
try:
92+
print("pairing...")
93+
await client.pair(callbacks)
94+
print("pairing successful")
95+
except BleakPairingCancelledError:
96+
print("paring was canceled")
97+
except BleakPairingFailedError:
98+
print("pairing failed (bad pin?)")
8999

90100

91101
if __name__ == "__main__":
@@ -94,6 +104,9 @@ async def main(addr: str, unpair: bool) -> None:
94104
parser.add_argument(
95105
"--unpair", action="store_true", help="unpair first before pairing"
96106
)
107+
parser.add_argument(
108+
"--auto", action="store_true", help="automatically pair during connect"
109+
)
97110
args = parser.parse_args()
98111

99-
asyncio.run(main(args.address, args.unpair))
112+
asyncio.run(main(args.address, args.unpair, args.auto))

0 commit comments

Comments
 (0)