diff --git a/core/embed/rust/Cargo.toml b/core/embed/rust/Cargo.toml index 77091f4326..a79eb092ba 100644 --- a/core/embed/rust/Cargo.toml +++ b/core/embed/rust/Cargo.toml @@ -45,6 +45,7 @@ rgb_led = [] backlight = [] usb = [] optiga = [] +ble = [] translations = ["crypto"] test = [ "backlight", diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs index 85d906b27e..104a5736ef 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -445,6 +445,11 @@ fn generate_trezorhal_bindings() { .no_copy("buffer_jpeg_work_t") .no_copy("buffer_blurring_t") .no_copy("buffer_blurring_totals_t") + // ble + .allowlist_function("ble_get_state") + .allowlist_function("ble_issue_command") + .allowlist_type("ble_command_t") + .allowlist_type("ble_state_t") //usb .allowlist_function("usb_configured") // touch diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index 85daae685b..c17487f1c8 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -120,6 +120,7 @@ static void _librust_qstrs(void) { MP_QSTR_bitcoin__unverified_external_inputs; MP_QSTR_bitcoin__valid_signature; MP_QSTR_bitcoin__voting_rights; + MP_QSTR_ble_event; MP_QSTR_bootscreen; MP_QSTR_br_code; MP_QSTR_br_name; diff --git a/core/embed/rust/src/trezorhal/ble.rs b/core/embed/rust/src/trezorhal/ble.rs new file mode 100644 index 0000000000..993dec59cf --- /dev/null +++ b/core/embed/rust/src/trezorhal/ble.rs @@ -0,0 +1,31 @@ +use super::ffi; + +pub fn connected() -> bool { + unsafe { + let mut state = ffi::ble_state_t { + connected: false, + peer_count: 0, + }; + ffi::ble_get_state(&mut state as _); + + state.connected + } +} + +pub fn pairing_mode() { + unsafe { + ffi::ble_issue_command(ffi::ble_command_t_BLE_PAIRING_MODE); + } +} + +pub fn allow_pairing() { + unsafe { + ffi::ble_issue_command(ffi::ble_command_t_BLE_ALLOW_PAIRING); + } +} + +pub fn reject_pairing() { + unsafe { + ffi::ble_issue_command(ffi::ble_command_t_BLE_REJECT_PAIRING); + } +} diff --git a/core/embed/rust/src/trezorhal/mod.rs b/core/embed/rust/src/trezorhal/mod.rs index bab3c62660..ff66ad3aa7 100644 --- a/core/embed/rust/src/trezorhal/mod.rs +++ b/core/embed/rust/src/trezorhal/mod.rs @@ -1,4 +1,6 @@ pub mod bip39; +#[cfg(feature = "ble")] +pub mod ble; #[macro_use] #[allow(unused_macros)] pub mod fatal_error; diff --git a/core/embed/rust/src/ui/component/base.rs b/core/embed/rust/src/ui/component/base.rs index b74d85c938..4108df7264 100644 --- a/core/embed/rust/src/ui/component/base.rs +++ b/core/embed/rust/src/ui/component/base.rs @@ -12,6 +12,8 @@ use crate::{ }, }; +#[cfg(feature = "ble")] +use crate::ui::event::BLEEvent; #[cfg(feature = "button")] use crate::ui::event::ButtonEvent; use crate::ui::event::USBEvent; @@ -364,6 +366,8 @@ pub enum Event { Button(ButtonEvent), #[cfg(feature = "touch")] Touch(TouchEvent), + #[cfg(feature = "ble")] + BLE(BLEEvent), USB(USBEvent), /// Previously requested timer was triggered. This invalidates the timer /// token (another timer has to be requested). diff --git a/core/embed/rust/src/ui/event/ble.rs b/core/embed/rust/src/ui/event/ble.rs new file mode 100644 index 0000000000..89d3f31de9 --- /dev/null +++ b/core/embed/rust/src/ui/event/ble.rs @@ -0,0 +1,21 @@ +use crate::error::Error; + +#[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] +pub enum BLEEvent { + Connected, + Disconnected, + PairingRequest(&'static [u8]), +} + +impl BLEEvent { + pub fn new(event: u32, data: &'static [u8]) -> Result { + let result = match event { + 1 => Self::Connected, + 2 => Self::Disconnected, + 3 => Self::PairingRequest(data), + _ => return Err(Error::OutOfRange), + }; + Ok(result) + } +} diff --git a/core/embed/rust/src/ui/event/mod.rs b/core/embed/rust/src/ui/event/mod.rs index 62df32784e..23bfe098b7 100644 --- a/core/embed/rust/src/ui/event/mod.rs +++ b/core/embed/rust/src/ui/event/mod.rs @@ -3,6 +3,11 @@ pub mod button; #[cfg(feature = "touch")] pub mod touch; +#[cfg(feature = "ble")] +mod ble; + +#[cfg(feature = "ble")] +pub use ble::BLEEvent; #[cfg(feature = "button")] pub use button::{ButtonEvent, PhysicalButton}; #[cfg(feature = "touch")] diff --git a/core/embed/rust/src/ui/layout/obj.rs b/core/embed/rust/src/ui/layout/obj.rs index e27ddf8df2..b7169fc247 100644 --- a/core/embed/rust/src/ui/layout/obj.rs +++ b/core/embed/rust/src/ui/layout/obj.rs @@ -5,6 +5,8 @@ use core::{ }; use num_traits::{FromPrimitive, ToPrimitive}; +#[cfg(feature = "ble")] +use crate::ui::event::BLEEvent; #[cfg(feature = "button")] use crate::ui::event::ButtonEvent; #[cfg(feature = "new_rendering")] @@ -15,7 +17,7 @@ use crate::{ error::Error, maybe_trace::MaybeTrace, micropython::{ - buffer::StrBuffer, + buffer::{get_buffer, StrBuffer}, gc::{self, Gc, GcBox}, macros::{obj_dict, obj_fn_1, obj_fn_2, obj_fn_3, obj_fn_var, obj_map, obj_type}, map::Map, @@ -335,6 +337,7 @@ impl LayoutObj { Qstr::MP_QSTR_button_event => obj_fn_var!(3, 3, ui_layout_button_event).as_obj(), Qstr::MP_QSTR_progress_event => obj_fn_var!(3, 3, ui_layout_progress_event).as_obj(), Qstr::MP_QSTR_usb_event => obj_fn_var!(2, 2, ui_layout_usb_event).as_obj(), + Qstr::MP_QSTR_ble_event=> obj_fn_var!(3, 3, ui_layout_ble_event).as_obj(), Qstr::MP_QSTR_timer => obj_fn_2!(ui_layout_timer).as_obj(), Qstr::MP_QSTR_paint => obj_fn_1!(ui_layout_paint).as_obj(), Qstr::MP_QSTR_request_complete_repaint => obj_fn_1!(ui_layout_request_complete_repaint).as_obj(), @@ -469,6 +472,31 @@ extern "C" fn ui_layout_button_event(_n_args: usize, _args: *const Obj) -> Obj { Obj::const_none() } +#[cfg(feature = "ble")] +extern "C" fn ui_layout_ble_event(n_args: usize, args: *const Obj) -> Obj { + let block = |args: &[Obj], _kwargs: &Map| { + if args.len() != 3 { + return Err(Error::TypeError); + } + let this: Gc = args[0].try_into()?; + let data: Obj = args[2].try_into()?; + + let data = unsafe { get_buffer(data) }; + + let data = unwrap!(data); + + let event = BLEEvent::new(args[1].try_into()?, data)?; + let msg = this.inner_mut().obj_event(Event::BLE(event))?; + Ok(msg) + }; + unsafe { util::try_with_args_and_kwargs(n_args, args, &Map::EMPTY, block) } +} + +#[cfg(not(feature = "ble"))] +extern "C" fn ui_layout_ble_event(_n_args: usize, _args: *const Obj) -> Obj { + Obj::const_none() +} + extern "C" fn ui_layout_progress_event(n_args: usize, args: *const Obj) -> Obj { let block = |args: &[Obj], _kwargs: &Map| { if args.len() != 3 { diff --git a/core/embed/rust/trezorhal.h b/core/embed/rust/trezorhal.h index 014be2bd4a..b1334bc815 100644 --- a/core/embed/rust/trezorhal.h +++ b/core/embed/rust/trezorhal.h @@ -1,5 +1,6 @@ #include +#include "ble.h" #include "buffers.h" #include "button.h" #include "display.h"