1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-15 18:00:59 +00:00

feat(core): expose BLE functionality to rust

[no changelog]
This commit is contained in:
tychovrahe 2024-10-01 10:06:21 +02:00 committed by TychoVrahe
parent 3fae6b23cf
commit 8ca51be020
10 changed files with 116 additions and 5 deletions

View File

@ -40,6 +40,7 @@ rgb_led = []
backlight = []
usb = []
optiga = []
ble = []
translations = ["crypto"]
test = [
"backlight",

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}

View File

@ -1,4 +1,6 @@
pub mod bip39;
#[cfg(feature = "ble")]
pub mod ble;
#[macro_use]
#[allow(unused_macros)]
pub mod fatal_error;

View File

@ -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).

View File

@ -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<Self, Error> {
let result = match event {
1 => Self::Connected,
2 => Self::Disconnected,
3 => Self::PairingRequest(data),
4 => Self::PairingCanceled,
_ => return Err(Error::OutOfRange),
};
Ok(result)
}
}

View File

@ -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")]

View File

@ -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<LayoutObj> = 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 {

View File

@ -13,6 +13,10 @@
#include <util/translations.h>
#include "storage.h"
#ifdef USE_BLE
#include <io/ble.h>
#endif
#ifdef USE_BUTTON
#include <io/button.h>
#endif