mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-25 02:08:48 +00:00
feat(core): BLE pairing flow
This commit is contained in:
parent
e9d7c1ed6d
commit
11b390c700
@ -1,4 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
strutil::TString,
|
||||||
translations::TR,
|
translations::TR,
|
||||||
ui::{
|
ui::{
|
||||||
component::{Component, Event, EventCtx, Timeout},
|
component::{Component, Event, EventCtx, Timeout},
|
||||||
@ -128,6 +129,14 @@ impl ActionBar {
|
|||||||
Self::new(Mode::PaginateOnly, None, None, None)
|
Self::new(Mode::PaginateOnly, None, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_text_only(text: TString<'static>) -> Self {
|
||||||
|
Self::new_single(
|
||||||
|
Button::with_text(text)
|
||||||
|
.styled(theme::button_always_disabled())
|
||||||
|
.initially_enabled(false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_left_short(mut self, short: bool) -> Self {
|
pub fn with_left_short(mut self, short: bool) -> Self {
|
||||||
if let Mode::Double { ref mut left_short } = self.mode {
|
if let Mode::Double { ref mut left_short } = self.mode {
|
||||||
*left_short = short;
|
*left_short = short;
|
||||||
|
@ -545,6 +545,22 @@ pub const fn button_keyboard_next() -> ButtonStyleSheet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Things that look like button but don't do anything.
|
||||||
|
pub const fn button_always_disabled() -> ButtonStyleSheet {
|
||||||
|
let style = &ButtonStyle {
|
||||||
|
font: fonts::FONT_SATOSHI_MEDIUM_26,
|
||||||
|
text_color: GREY_LIGHT,
|
||||||
|
button_color: BG,
|
||||||
|
icon_color: GREY_LIGHT,
|
||||||
|
background_color: BG,
|
||||||
|
};
|
||||||
|
ButtonStyleSheet {
|
||||||
|
normal: style,
|
||||||
|
active: style,
|
||||||
|
disabled: style,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn input_mnemonic() -> ButtonStyleSheet {
|
pub const fn input_mnemonic() -> ButtonStyleSheet {
|
||||||
ButtonStyleSheet {
|
ButtonStyleSheet {
|
||||||
normal: &ButtonStyle {
|
normal: &ButtonStyle {
|
||||||
|
@ -1003,9 +1003,7 @@ impl FirmwareUI for UIEckhart {
|
|||||||
ops = ops.text(text, font);
|
ops = ops.text(text, font);
|
||||||
let screen = TextScreen::new(FormattedText::new(ops))
|
let screen = TextScreen::new(FormattedText::new(ops))
|
||||||
.with_header(Header::new("Pair with new device".into()).with_close_button())
|
.with_header(Header::new("Pair with new device".into()).with_close_button())
|
||||||
.with_action_bar(ActionBar::new_single(Button::with_text(
|
.with_action_bar(ActionBar::new_text_only("Continue on host".into()));
|
||||||
"Continue on host".into(),
|
|
||||||
)));
|
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
let screen = crate::ui::component::BLEHandler::new(screen, true);
|
let screen = crate::ui::component::BLEHandler::new(screen, true);
|
||||||
let layout = RootComponent::new(screen);
|
let layout = RootComponent::new(screen);
|
||||||
|
@ -124,6 +124,7 @@ Q(apps.management.apply_flags)
|
|||||||
Q(apps.management.apply_settings)
|
Q(apps.management.apply_settings)
|
||||||
Q(apps.management.authenticate_device)
|
Q(apps.management.authenticate_device)
|
||||||
Q(apps.management.backup_device)
|
Q(apps.management.backup_device)
|
||||||
|
Q(apps.management.ble)
|
||||||
Q(apps.management.ble.pair_new_device)
|
Q(apps.management.ble.pair_new_device)
|
||||||
Q(apps.management.ble.unpair)
|
Q(apps.management.ble.unpair)
|
||||||
Q(apps.management.change_language)
|
Q(apps.management.change_language)
|
||||||
@ -168,6 +169,7 @@ Q(benchmark)
|
|||||||
Q(benchmarks)
|
Q(benchmarks)
|
||||||
Q(bitcoin)
|
Q(bitcoin)
|
||||||
Q(bitcoinlike)
|
Q(bitcoinlike)
|
||||||
|
Q(ble)
|
||||||
Q(bolt)
|
Q(bolt)
|
||||||
Q(boot)
|
Q(boot)
|
||||||
Q(cache)
|
Q(cache)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import storage.device
|
import storage.device
|
||||||
|
import trezorble as ble
|
||||||
import trezorui_api
|
import trezorui_api
|
||||||
from trezor import utils
|
from trezor import log, utils
|
||||||
from trezor.ui.layouts import raise_if_not_confirmed
|
from trezor.ui.layouts import raise_if_not_confirmed
|
||||||
|
|
||||||
|
|
||||||
@ -8,10 +9,14 @@ async def handle_device_menu() -> None:
|
|||||||
# MOCK DATA
|
# MOCK DATA
|
||||||
failed_backup = True
|
failed_backup = True
|
||||||
battery_percentage = 22
|
battery_percentage = 22
|
||||||
paired_devices = ["Trezor Suite"]
|
paired_devices = ["Trezor Suite"] if ble.is_connected() else []
|
||||||
# ###
|
# ###
|
||||||
firmware_version = ".".join(map(str, utils.VERSION))
|
firmware_version = ".".join(map(str, utils.VERSION))
|
||||||
device_name = storage.device.get_label() or "Trezor"
|
device_name = storage.device.get_label() or "Trezor"
|
||||||
|
log.debug(
|
||||||
|
__name__,
|
||||||
|
f"device menu, BLE state: {ble.connection_flags()} (peers: {ble.peer_count()})",
|
||||||
|
)
|
||||||
|
|
||||||
menu_result = await raise_if_not_confirmed(
|
menu_result = await raise_if_not_confirmed(
|
||||||
trezorui_api.show_device_menu(
|
trezorui_api.show_device_menu(
|
||||||
@ -27,5 +32,11 @@ async def handle_device_menu() -> None:
|
|||||||
from apps.management.ble.pair_new_device import pair_new_device
|
from apps.management.ble.pair_new_device import pair_new_device
|
||||||
|
|
||||||
await 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:
|
else:
|
||||||
raise RuntimeError(f"Unknown menu {menu_result}")
|
raise RuntimeError(f"Unknown menu {menu_result}")
|
||||||
|
0
core/src/apps/management/ble/__init__.py
Normal file
0
core/src/apps/management/ble/__init__.py
Normal file
@ -1,17 +1,43 @@
|
|||||||
|
import trezorble as ble
|
||||||
import trezorui_api
|
import trezorui_api
|
||||||
from trezor.ui.layouts import interact
|
from storage import device as storage_device
|
||||||
|
from trezor import utils
|
||||||
|
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:
|
async def pair_new_device() -> None:
|
||||||
label = "Trezor T3W1"
|
label = storage_device.get_label() or utils.MODEL_FULL_NAME
|
||||||
await interact(
|
ble.start_advertising(False, label)
|
||||||
trezorui_api.show_pairing_device_name(device_name=label),
|
try:
|
||||||
None,
|
code = await raise_if_not_confirmed(
|
||||||
raise_on_cancel=None, # for UI testing
|
trezorui_api.show_pairing_device_name(
|
||||||
)
|
device_name=label,
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
if not isinstance(code, int):
|
||||||
|
raise ActionCancelled
|
||||||
|
|
||||||
code = 12345
|
try:
|
||||||
await interact(
|
result = await raise_if_not_confirmed(
|
||||||
trezorui_api.show_pairing_code(code=f"{code:0>6}"),
|
trezorui_api.show_pairing_code(
|
||||||
None,
|
code=f"{code:0>6}",
|
||||||
)
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
ble.reject_pairing()
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
if result is CONFIRMED:
|
||||||
|
ble.allow_pairing(code)
|
||||||
|
finally:
|
||||||
|
_end_pairing()
|
||||||
|
Loading…
Reference in New Issue
Block a user