From 8ca51be020973234ffc1e342a9c510c468f95d7b Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Tue, 1 Oct 2024 10:06:21 +0200 Subject: [PATCH] feat(core): expose BLE functionality to rust [no changelog] --- core/embed/rust/Cargo.toml | 1 + core/embed/rust/build.rs | 7 +++++ core/embed/rust/librust_qstr.h | 1 + core/embed/rust/src/trezorhal/ble.rs | 34 ++++++++++++++++++++ core/embed/rust/src/trezorhal/mod.rs | 2 ++ core/embed/rust/src/ui/component/base.rs | 4 +++ core/embed/rust/src/ui/event/ble.rs | 23 ++++++++++++++ core/embed/rust/src/ui/event/mod.rs | 5 +++ core/embed/rust/src/ui/layout/obj.rs | 40 +++++++++++++++++++++--- core/embed/rust/trezorhal.h | 4 +++ 10 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 core/embed/rust/src/trezorhal/ble.rs create mode 100644 core/embed/rust/src/ui/event/ble.rs diff --git a/core/embed/rust/Cargo.toml b/core/embed/rust/Cargo.toml index 47eeb50aa9..984e7e8bd5 100644 --- a/core/embed/rust/Cargo.toml +++ b/core/embed/rust/Cargo.toml @@ -40,6 +40,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 bd95b4e5c8..9c20f380d0 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -35,6 +35,7 @@ const DEFAULT_BINDGEN_MACROS_COMMON: &[&str] = &[ "-I../../vendor/micropython/lib/uzlib", "-I../rtl/inc", "-I../gfx/inc", + "-I../io/ble/inc", "-I../io/button/inc", "-I../io/display/inc", "-I../io/haptic/inc", @@ -51,6 +52,7 @@ const DEFAULT_BINDGEN_MACROS_COMMON: &[&str] = &[ "-DUSE_TOUCH", "-DUSE_HAPTIC", "-DUSE_RGB_LED", + "-DUSE_BLE", ]; #[cfg(feature = "layout_bolt")] @@ -412,6 +414,11 @@ fn generate_trezorhal_bindings() { //usb .allowlist_type("usb_event_t") .allowlist_function("usb_get_state") + // ble + .allowlist_function("ble_get_state") + .allowlist_function("ble_issue_command") + .allowlist_type("ble_command_t") + .allowlist_type("ble_state_t") // touch .allowlist_function("touch_get_event") // button diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index a6afb178f0..6b0e7c3e49 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..3bef99eb25 --- /dev/null +++ b/core/embed/rust/src/trezorhal/ble.rs @@ -0,0 +1,34 @@ +use super::ffi; + +pub fn connected() -> bool { + unsafe { + let mut state = ffi::ble_state_t { + connected: false, + peer_count: 0, + connectable: false, + pairing: false, + pairing_requested: false, + }; + 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 228b276e13..51632ea62e 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 e23b7223eb..9b24c44fd1 100644 --- a/core/embed/rust/src/ui/component/base.rs +++ b/core/embed/rust/src/ui/component/base.rs @@ -11,6 +11,8 @@ use crate::{ }, }; +#[cfg(feature = "ble")] +use crate::ui::event::BLEEvent; #[cfg(feature = "button")] use crate::ui::event::ButtonEvent; use crate::ui::event::USBEvent; @@ -319,6 +321,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..fd0f8d0172 --- /dev/null +++ b/core/embed/rust/src/ui/event/ble.rs @@ -0,0 +1,23 @@ +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]), + PairingCanceled, +} + +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), + 4 => Self::PairingCanceled, + _ => 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 1b7a3aa267..661efcadd0 100644 --- a/core/embed/rust/src/ui/event/mod.rs +++ b/core/embed/rust/src/ui/event/mod.rs @@ -5,6 +5,11 @@ pub mod touch; pub mod usb; +#[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 93a63f0a6a..4ec68214a4 100644 --- a/core/embed/rust/src/ui/layout/obj.rs +++ b/core/embed/rust/src/ui/layout/obj.rs @@ -4,16 +4,20 @@ use core::{ marker::PhantomData, ops::{Deref, DerefMut}, }; + +#[cfg(feature = "touch")] +use crate::ui::{event::TouchEvent, geometry::Direction}; #[cfg(feature = "touch")] use num_traits::{FromPrimitive, ToPrimitive}; +#[cfg(feature = "ble")] +use crate::micropython::buffer::get_buffer; +#[cfg(feature = "ble")] +use crate::ui::event::BLEEvent; + #[cfg(feature = "button")] use crate::ui::event::ButtonEvent; -use crate::ui::{display::Color, shape::render_on_display}; - -#[cfg(feature = "touch")] -use crate::ui::{event::TouchEvent, geometry::Direction}; use crate::{ error::Error, maybe_trace::MaybeTrace, @@ -35,8 +39,9 @@ use crate::{ base::{AttachType, TimerToken}, Component, Event, EventCtx, Never, }, - display, + display::{self, Color}, event::USBEvent, + shape::render_on_display, CommonUI, ModelUI, }, }; @@ -388,6 +393,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(), @@ -522,6 +528,30 @@ 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 = unsafe { get_buffer(args[2]) }; + + 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 3267801220..6e00aac760 100644 --- a/core/embed/rust/trezorhal.h +++ b/core/embed/rust/trezorhal.h @@ -13,6 +13,10 @@ #include #include "storage.h" +#ifdef USE_BLE +#include +#endif + #ifdef USE_BUTTON #include #endif