From b4cbebde664d33d93d87132071620421dfe953e1 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 | 5 ++++ core/embed/rust/librust_qstr.h | 1 + core/embed/rust/src/trezorhal/ble.rs | 31 ++++++++++++++++++++++++ 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 | 30 ++++++++++++++++++++++- core/embed/rust/trezorhal.h | 4 +++ 10 files changed, 105 insertions(+), 1 deletion(-) 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 83ecdc4b6e..66b0a6f3e8 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 d0b0439194..8221993afa 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -408,6 +408,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 d04460c4a2..2490677652 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -124,6 +124,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 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 52fe997999..b80b660c0d 100644 --- a/core/embed/rust/src/ui/layout/obj.rs +++ b/core/embed/rust/src/ui/layout/obj.rs @@ -7,6 +7,8 @@ use core::{ #[cfg(feature = "touch")] use num_traits::{FromPrimitive, ToPrimitive}; +#[cfg(feature = "ble")] +use crate::ui::event::BLEEvent; #[cfg(feature = "button")] use crate::ui::event::ButtonEvent; @@ -18,7 +20,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, @@ -389,6 +391,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(), @@ -523,6 +526,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 fcec05f276..9efbfd6cd7 100644 --- a/core/embed/rust/trezorhal.h +++ b/core/embed/rust/trezorhal.h @@ -11,6 +11,10 @@ #include #include "storage.h" +#ifdef USE_BLE +#include +#endif + #ifdef USE_BUTTON #include #endif