diff --git a/apps/pair.py b/apps/pair.py index 284aec1a..13dc06d4 100644 --- a/apps/pair.py +++ b/apps/pair.py @@ -69,7 +69,7 @@ class Waiter: self.linger = linger def terminate(self): - if not self.linger: + if not self.linger and not self.done.done: self.done.set_result(None) async def wait_until_terminated(self): @@ -247,15 +247,19 @@ def on_connection(connection, request): print(color(f'<<< Connection: {connection}', 'green')) # Listen for pairing events - connection.on('pairing_start', on_pairing_start) - connection.on('pairing', lambda keys: on_pairing(connection, keys)) + connection.on(connection.EVENT_PAIRING_START, on_pairing_start) + connection.on(connection.EVENT_PAIRING, lambda keys: on_pairing(connection, keys)) connection.on( - 'pairing_failure', lambda reason: on_pairing_failure(connection, reason) + connection.EVENT_CLASSIC_PAIRING, lambda: on_classic_pairing(connection) + ) + connection.on( + connection.EVENT_PAIRING_FAILURE, + lambda reason: on_pairing_failure(connection, reason), ) # Listen for encryption changes connection.on( - 'connection_encryption_change', + connection.EVENT_CONNECTION_ENCRYPTION_CHANGE, lambda: on_connection_encryption_change(connection), ) @@ -296,6 +300,20 @@ async def on_pairing(connection, keys): Waiter.instance.terminate() +# ----------------------------------------------------------------------------- +@AsyncRunner.run_in_task() +async def on_classic_pairing(connection): + print(color('***-----------------------------------', 'cyan')) + print( + color( + f'*** Paired [Classic]! (peer identity={connection.peer_address})', 'cyan' + ) + ) + print(color('***-----------------------------------', 'cyan')) + await asyncio.sleep(POST_PAIRING_DELAY) + Waiter.instance.terminate() + + # ----------------------------------------------------------------------------- @AsyncRunner.run_in_task() async def on_pairing_failure(connection, reason): diff --git a/bumble/device.py b/bumble/device.py index c5f8e096..1353e75e 100644 --- a/bumble/device.py +++ b/bumble/device.py @@ -1589,7 +1589,8 @@ class Connection(utils.CompositeEventEmitter): encryption_key_size: int authenticated: bool sc: bool - link_key_type: Optional[int] + link_key: Optional[bytes] # [Classic only] + link_key_type: Optional[int] # [Classic only] gatt_client: gatt_client.Client pairing_peer_io_capability: Optional[int] pairing_peer_authentication_requirements: Optional[int] @@ -1629,6 +1630,7 @@ class Connection(utils.CompositeEventEmitter): EVENT_PAIRING = "pairing" EVENT_PAIRING_FAILURE = "pairing_failure" EVENT_SECURITY_REQUEST = "security_request" + EVENT_LINK_KEY = "link_key" @utils.composite_listener class Listener: @@ -1692,6 +1694,7 @@ class Connection(utils.CompositeEventEmitter): self.encryption_key_size = 0 self.authenticated = False self.sc = False + self.link_key = None self.link_key_type = None self.att_mtu = ATT_DEFAULT_MTU self.data_length = DEVICE_DEFAULT_DATA_LENGTH @@ -5096,8 +5099,9 @@ class Device(utils.CompositeEventEmitter): if connection := self.find_connection_by_bd_addr( bd_addr, transport=PhysicalTransport.BR_EDR ): + connection.link_key = link_key connection.link_key_type = key_type - connection.emit('pairing', pairing_keys) + connection.emit(connection.EVENT_LINK_KEY) def add_service(self, service): self.gatt_server.add_service(service) diff --git a/bumble/hci.py b/bumble/hci.py index 6943c1c2..029c2dc0 100644 --- a/bumble/hci.py +++ b/bumble/hci.py @@ -29,13 +29,12 @@ from typing_extensions import Self from bumble import crypto from bumble.colors import color from bumble.core import ( - PhysicalTransport, AdvertisingData, DeviceClass, InvalidArgumentError, InvalidPacketError, - ProtocolError, PhysicalTransport, + ProtocolError, bit_flags_to_strings, name_or_number, padded_bytes,