From 4f2efd8dc7d0a2c08efdbfbc2cd764c871f0401a Mon Sep 17 00:00:00 2001 From: Martin Milata Date: Tue, 8 Apr 2025 17:05:30 +0200 Subject: [PATCH] feat(core): BLE pairing flow --- core/src/apps/homescreen/device_menu.py | 9 +++- .../apps/management/ble/pair_new_device.py | 46 ++++++++++++++----- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/core/src/apps/homescreen/device_menu.py b/core/src/apps/homescreen/device_menu.py index 4d84cbde8a..43ce00419f 100644 --- a/core/src/apps/homescreen/device_menu.py +++ b/core/src/apps/homescreen/device_menu.py @@ -1,4 +1,5 @@ import storage.device +import trezorble as ble import trezorui_api from trezor import utils from trezor.ui.layouts import raise_if_not_confirmed @@ -8,7 +9,7 @@ async def handle_device_menu() -> None: # MOCK DATA failed_backup = True battery_percentage = 22 - paired_devices = ["Trezor Suite"] + paired_devices = ["Trezor Suite"] if ble.is_connected() else [] # ### firmware_version = ".".join(map(str, utils.VERSION)) device_name = storage.device.get_label() or "Trezor" @@ -27,5 +28,11 @@ async def handle_device_menu() -> None: from apps.management.ble.pair_new_device import pair_new_device await pair_new_device() + elif menu_result == "DeviceDisconnect": + from trezor.messages import BleUnpair + + from apps.management.ble.unpair import unpair + + await unpair(BleUnpair(all=False)) else: raise RuntimeError(f"Unknown menu {menu_result}") diff --git a/core/src/apps/management/ble/pair_new_device.py b/core/src/apps/management/ble/pair_new_device.py index d80daf0524..9bb5d351ca 100644 --- a/core/src/apps/management/ble/pair_new_device.py +++ b/core/src/apps/management/ble/pair_new_device.py @@ -1,17 +1,39 @@ +import trezorble as ble import trezorui_api -from trezor.ui.layouts import interact +from storage import device as storage_device +from trezor.ui.layouts import CONFIRMED, raise_if_not_confirmed +from trezor.wire import ActionCancelled + + +def _end_pairing() -> None: + if ble.peer_count() > 0: + ble.start_advertising(True, storage_device.get_label()) + else: + ble.stop_advertising() async def pair_new_device() -> None: - label = "Trezor T3W1" - await interact( - trezorui_api.show_pairing_device_name(device_name=label), - None, - raise_on_cancel=None, # for UI testing - ) + label = storage_device.get_label() or "Trezor T3W1" + ble.start_advertising(False, label) + try: + code = await raise_if_not_confirmed( + trezorui_api.show_pairing_device_name( + device_name=label, + ), + None, + ) + if not isinstance(code, int): + raise ActionCancelled - code = 12345 - await interact( - trezorui_api.show_pairing_code(code=f"{code:0>6}"), - None, - ) + result = await raise_if_not_confirmed( + trezorui_api.show_pairing_code( + code=f"{code:0>6}", + ), + None, + ) + if result is CONFIRMED: + ble.allow_pairing(code) + else: + ble.reject_pairing() + finally: + _end_pairing()