Skip to content

Commit

Permalink
bluezdbus/client: Support pairing during connection establishment
Browse files Browse the repository at this point in the history
This is achieved by passing ``pairing_callbacks`` to the ``BleakClient``
constructor instead of manually calling ``pair()`` method.
  • Loading branch information
bojanpotocnik committed Nov 25, 2022
1 parent 0c0c16f commit dd50aa6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 17 deletions.
15 changes: 9 additions & 6 deletions bleak/backends/bluezdbus/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,9 @@ def __init__(self, address_or_ble_device: Union[BLEDevice, str], **kwargs):
# used to override mtu_size property
self._mtu_size: Optional[int] = None

if kwargs.get("pairing_callbacks"):
warnings.warn(
"Pairing on connect not yet implemented for BlueZ",
RuntimeWarning,
stacklevel=2,
)
self._pairing_callbacks: Optional[BaseBleakAgentCallbacks] = kwargs.get(
"pairing_callbacks"
)

def close(self):
self._bus.disconnect()
Expand Down Expand Up @@ -193,6 +190,11 @@ def on_value_changed(char_path: str, value: bytes) -> None:
#
# For additional details see https://github.com/bluez/bluez/issues/89
#
if self._pairing_callbacks:
# org.bluez.Device1.Pair() will connect to the remote device, initiate
# pairing and then retrieve all SDP records (or GATT primary services).
await self.pair(self._pairing_callbacks)

if not manager.is_connected(self._device_path):
logger.debug("Connecting to BlueZ path %s", self._device_path)
async with async_timeout(timeout):
Expand Down Expand Up @@ -400,6 +402,7 @@ async def pair(
member="Pair",
)
)
# TODO: Call "CancelPairing" if this task is cancelled

try:
assert_reply(reply)
Expand Down
35 changes: 24 additions & 11 deletions examples/pairing_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async def request_pin(self, device: BLEDevice) -> str:
return response


async def main(addr: str, unpair: bool) -> None:
async def main(addr: str, unpair: bool, auto: bool) -> None:
if unpair:
print("unpairing...")
try:
Expand All @@ -76,16 +76,26 @@ async def main(addr: str, unpair: bool) -> None:
print("device was not found")
return

print("pairing...")
if auto:
print("connecting and pairing...")

async with BleakClient(device) as client, AgentCallbacks() as callbacks:
try:
await client.pair(callbacks)
print("pairing successful")
except BleakPairingCancelledError:
print("paring was canceled")
except BleakPairingFailedError:
print("pairing failed (bad pin?)")
async with AgentCallbacks() as callbacks, BleakClient(
device, pairing_callbacks=callbacks
) as client:
print(f"connection and pairing to {client.address} successful")

else:
print("connecting...")

async with BleakClient(device) as client, AgentCallbacks() as callbacks:
try:
print("pairing...")
await client.pair(callbacks)
print("pairing successful")
except BleakPairingCancelledError:
print("paring was canceled")
except BleakPairingFailedError:
print("pairing failed (bad pin?)")


if __name__ == "__main__":
Expand All @@ -94,6 +104,9 @@ async def main(addr: str, unpair: bool) -> None:
parser.add_argument(
"--unpair", action="store_true", help="unpair first before pairing"
)
parser.add_argument(
"--auto", action="store_true", help="automatically pair during connect"
)
args = parser.parse_args()

asyncio.run(main(args.address, args.unpair))
asyncio.run(main(args.address, args.unpair, args.auto))

0 comments on commit dd50aa6

Please sign in to comment.