mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-20 09:09:02 +00:00
refactor(core): convert modtrezorio.ble to rust
[no changelog]
This commit is contained in:
parent
b35d2f4000
commit
2a40d91790
@ -402,8 +402,15 @@ fn generate_trezorhal_bindings() {
|
||||
.allowlist_type("usb_event_t")
|
||||
.allowlist_function("usb_get_state")
|
||||
// ble
|
||||
.allowlist_var("BLE_PAIRING_CODE_LEN")
|
||||
.allowlist_var("BLE_RX_PACKET_SIZE")
|
||||
.allowlist_var("BLE_TX_PACKET_SIZE")
|
||||
.allowlist_var("BLE_ADV_NAME_LEN")
|
||||
.allowlist_function("ble_get_state")
|
||||
.allowlist_function("ble_issue_command")
|
||||
.allowlist_function("ble_start")
|
||||
.allowlist_function("ble_write")
|
||||
.allowlist_function("ble_read")
|
||||
.allowlist_type("ble_command_t")
|
||||
.allowlist_type("ble_state_t")
|
||||
// touch
|
||||
|
@ -10,6 +10,7 @@ mp_obj_t protobuf_debug_msg_def_type();
|
||||
extern mp_obj_module_t mp_module_trezorproto;
|
||||
extern mp_obj_module_t mp_module_trezorui_api;
|
||||
extern mp_obj_module_t mp_module_trezortranslate;
|
||||
extern mp_obj_module_t mp_module_trezorble;
|
||||
|
||||
#if !PYOPT
|
||||
mp_obj_t ui_debug_layout_type();
|
||||
|
@ -19,6 +19,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_ATTACHED;
|
||||
MP_QSTR_AttachType;
|
||||
MP_QSTR_BacklightLevels;
|
||||
MP_QSTR_BleInterface;
|
||||
MP_QSTR_CANCELLED;
|
||||
MP_QSTR_CONFIRMED;
|
||||
MP_QSTR_DIM;
|
||||
@ -36,12 +37,14 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_NONE;
|
||||
MP_QSTR_NORMAL;
|
||||
MP_QSTR_RESUME;
|
||||
MP_QSTR_RX_PACKET_LEN;
|
||||
MP_QSTR_SWIPE_DOWN;
|
||||
MP_QSTR_SWIPE_LEFT;
|
||||
MP_QSTR_SWIPE_RIGHT;
|
||||
MP_QSTR_SWIPE_UP;
|
||||
MP_QSTR_TR;
|
||||
MP_QSTR_TRANSITIONING;
|
||||
MP_QSTR_TX_PACKET_LEN;
|
||||
MP_QSTR_TranslationsHeader;
|
||||
MP_QSTR___del__;
|
||||
MP_QSTR___dict__;
|
||||
@ -78,6 +81,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_address_label;
|
||||
MP_QSTR_address_qr;
|
||||
MP_QSTR_allow_cancel;
|
||||
MP_QSTR_allow_pairing;
|
||||
MP_QSTR_amount;
|
||||
MP_QSTR_amount_change;
|
||||
MP_QSTR_amount_label;
|
||||
@ -222,6 +226,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_confirm_value;
|
||||
MP_QSTR_confirm_value_intro;
|
||||
MP_QSTR_confirm_with_info;
|
||||
MP_QSTR_connection_flags;
|
||||
MP_QSTR_continue_recovery_homepage;
|
||||
MP_QSTR_count;
|
||||
MP_QSTR_current;
|
||||
@ -237,11 +242,13 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_device_name__change_template;
|
||||
MP_QSTR_device_name__title;
|
||||
MP_QSTR_disable_animation;
|
||||
MP_QSTR_disconnect;
|
||||
MP_QSTR_encode;
|
||||
MP_QSTR_encoded_length;
|
||||
MP_QSTR_entropy__send;
|
||||
MP_QSTR_entropy__title_confirm;
|
||||
MP_QSTR_erase;
|
||||
MP_QSTR_erase_bonds;
|
||||
MP_QSTR_experimental_mode__enable;
|
||||
MP_QSTR_experimental_mode__only_for_dev;
|
||||
MP_QSTR_experimental_mode__title;
|
||||
@ -282,6 +289,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_homescreen__title_set;
|
||||
MP_QSTR_horizontal;
|
||||
MP_QSTR_icon_name;
|
||||
MP_QSTR_iface_num;
|
||||
MP_QSTR_image;
|
||||
MP_QSTR_indeterminate;
|
||||
MP_QSTR_info;
|
||||
@ -312,6 +320,8 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_instructions__tap_to_continue;
|
||||
MP_QSTR_instructions__tap_to_start;
|
||||
MP_QSTR_instructions__view_all_data;
|
||||
MP_QSTR_interface;
|
||||
MP_QSTR_is_connected;
|
||||
MP_QSTR_is_data;
|
||||
MP_QSTR_is_type_of;
|
||||
MP_QSTR_items;
|
||||
@ -378,6 +388,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_passphrase__turn_on;
|
||||
MP_QSTR_passphrase__wallet;
|
||||
MP_QSTR_path;
|
||||
MP_QSTR_peer_count;
|
||||
MP_QSTR_pin__cancel_description;
|
||||
MP_QSTR_pin__cancel_info;
|
||||
MP_QSTR_pin__cancel_setup;
|
||||
@ -432,6 +443,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_prompt_screen;
|
||||
MP_QSTR_prompt_title;
|
||||
MP_QSTR_qr_title;
|
||||
MP_QSTR_read;
|
||||
MP_QSTR_reboot_to_bootloader__just_a_moment;
|
||||
MP_QSTR_reboot_to_bootloader__restart;
|
||||
MP_QSTR_reboot_to_bootloader__title;
|
||||
@ -487,6 +499,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_recovery__x_of_y_entered_template;
|
||||
MP_QSTR_recovery__you_have_entered;
|
||||
MP_QSTR_recovery_type;
|
||||
MP_QSTR_reject_pairing;
|
||||
MP_QSTR_remaining_shares;
|
||||
MP_QSTR_request_bip39;
|
||||
MP_QSTR_request_complete_repaint;
|
||||
@ -674,6 +687,9 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_sign_message__message_size;
|
||||
MP_QSTR_sign_message__verify_address;
|
||||
MP_QSTR_skip_first_paint;
|
||||
MP_QSTR_start_advertising;
|
||||
MP_QSTR_start_comm;
|
||||
MP_QSTR_stop_advertising;
|
||||
MP_QSTR_storage_msg__processing;
|
||||
MP_QSTR_storage_msg__starting;
|
||||
MP_QSTR_storage_msg__verifying_pin;
|
||||
@ -697,6 +713,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_total_len;
|
||||
MP_QSTR_touch_event;
|
||||
MP_QSTR_trace;
|
||||
MP_QSTR_trezorble;
|
||||
MP_QSTR_trezorproto;
|
||||
MP_QSTR_trezorui_api;
|
||||
MP_QSTR_tutorial;
|
||||
@ -729,6 +746,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_tutorial__welcome_safe5;
|
||||
MP_QSTR_type_for_name;
|
||||
MP_QSTR_type_for_wire;
|
||||
MP_QSTR_unpair;
|
||||
MP_QSTR_usb_event;
|
||||
MP_QSTR_user_fee_change;
|
||||
MP_QSTR_value;
|
||||
|
@ -1,64 +0,0 @@
|
||||
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,
|
||||
state_known: false,
|
||||
};
|
||||
ffi::ble_get_state(&mut state as _);
|
||||
|
||||
state.connected
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pairing_mode(name: &str) {
|
||||
unsafe {
|
||||
let mut cmd = ffi::ble_command_t {
|
||||
cmd_type: ffi::ble_command_type_t_BLE_PAIRING_MODE,
|
||||
data_len: 0,
|
||||
data: ffi::ble_command_data_t { raw: [0; 32] },
|
||||
};
|
||||
|
||||
let bytes = name.as_bytes();
|
||||
|
||||
// Determine how many bytes we can copy (min of buffer size and string length).
|
||||
let len = bytes.len().min(cmd.data.adv_start.name.len());
|
||||
|
||||
cmd.data.adv_start.name[..len].copy_from_slice(&bytes[..len]);
|
||||
|
||||
ffi::ble_issue_command(&mut cmd as _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allow_pairing(mut code: u32) {
|
||||
const CODE_LEN: u8 = 6;
|
||||
let mut cmd = ffi::ble_command_t {
|
||||
cmd_type: ffi::ble_command_type_t_BLE_ALLOW_PAIRING,
|
||||
data_len: CODE_LEN,
|
||||
data: ffi::ble_command_data_t { raw: [0; 32] },
|
||||
};
|
||||
unsafe {
|
||||
for i in (0..CODE_LEN).rev() {
|
||||
let digit = b'0' + ((code % 10) as u8);
|
||||
code /= 10;
|
||||
cmd.data.raw[i as usize] = digit;
|
||||
}
|
||||
ffi::ble_issue_command(&mut cmd as _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reject_pairing() {
|
||||
unsafe {
|
||||
let mut cmd = ffi::ble_command_t {
|
||||
cmd_type: ffi::ble_command_type_t_BLE_REJECT_PAIRING,
|
||||
data_len: 0,
|
||||
data: ffi::ble_command_data_t { raw: [0; 32] },
|
||||
};
|
||||
ffi::ble_issue_command(&mut cmd as _);
|
||||
}
|
||||
}
|
287
core/embed/rust/src/trezorhal/ble/micropython.rs
Normal file
287
core/embed/rust/src/trezorhal/ble/micropython.rs
Normal file
@ -0,0 +1,287 @@
|
||||
use super::*;
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::{
|
||||
buffer::{get_buffer, get_buffer_mut, StrBuffer},
|
||||
list::List,
|
||||
macros::*,
|
||||
map::Map,
|
||||
module::Module,
|
||||
obj::Obj,
|
||||
qstr::Qstr,
|
||||
simple_type::SimpleTypeObj,
|
||||
typ::Type,
|
||||
util,
|
||||
},
|
||||
strutil::ShortString,
|
||||
};
|
||||
|
||||
extern "C" fn py_erase_bonds() -> Obj {
|
||||
let block = || {
|
||||
erase_bonds()?;
|
||||
Ok(Obj::const_none())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_unpair() -> Obj {
|
||||
let block = || {
|
||||
unpair()?;
|
||||
Ok(Obj::const_none())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_start_comm() -> Obj {
|
||||
start_comm();
|
||||
Obj::const_none()
|
||||
}
|
||||
|
||||
extern "C" fn py_start_advertising(whitelist: Obj, name: Obj) -> Obj {
|
||||
let block = || {
|
||||
let whitelist: bool = whitelist.try_into()?;
|
||||
let name = name.try_into_option::<StrBuffer>()?;
|
||||
let name = name.as_deref().unwrap_or(model::FULL_NAME);
|
||||
|
||||
if whitelist {
|
||||
connectable_mode(name)?;
|
||||
} else {
|
||||
pairing_mode(name)?;
|
||||
};
|
||||
Ok(Obj::const_none())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_stop_advertising() -> Obj {
|
||||
let block = || {
|
||||
stop_advertising()?;
|
||||
Ok(Obj::const_none())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_disconnect() -> Obj {
|
||||
let block = || {
|
||||
disconnect()?;
|
||||
Ok(Obj::const_none())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_allow_pairing(code: Obj) -> Obj {
|
||||
let block = || {
|
||||
let code: u32 = code.try_into()?;
|
||||
allow_pairing(code)?;
|
||||
Ok(Obj::const_none())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_reject_pairing() -> Obj {
|
||||
let block = || {
|
||||
reject_pairing()?;
|
||||
Ok(Obj::const_none())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_peer_count() -> Obj {
|
||||
peer_count().into()
|
||||
}
|
||||
|
||||
extern "C" fn py_is_connected() -> Obj {
|
||||
is_connected().into()
|
||||
}
|
||||
|
||||
extern "C" fn py_connection_flags() -> Obj {
|
||||
let block = || {
|
||||
let mut result = List::with_capacity(4)?;
|
||||
let s = state();
|
||||
if !s.state_known {
|
||||
result.append(c"unknown".try_into()?)?;
|
||||
return Ok(result.leak().into());
|
||||
}
|
||||
if s.connectable {
|
||||
result.append(c"connectable".try_into()?)?;
|
||||
}
|
||||
if s.connected {
|
||||
result.append(c"connected".try_into()?)?;
|
||||
}
|
||||
if s.pairing {
|
||||
result.append(c"pairing".try_into()?)?;
|
||||
}
|
||||
if s.pairing_requested {
|
||||
result.append(c"pairing_requested".try_into()?)?;
|
||||
}
|
||||
Ok(result.leak().into())
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_iface_num(_self: Obj) -> Obj {
|
||||
Obj::small_int(8) // FIXME SYSHANDLE_BLE_IFACE_0
|
||||
}
|
||||
|
||||
extern "C" fn py_iface_write(_self: Obj, msg: Obj) -> Obj {
|
||||
let block = || {
|
||||
// SAFETY: reference is discarded at the end of the block
|
||||
let buf = unsafe { get_buffer(msg)? };
|
||||
if write(buf).is_ok() {
|
||||
Ok(buf.len().try_into()?)
|
||||
} else {
|
||||
Ok((-1).try_into()?)
|
||||
}
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn py_iface_read(n_args: usize, args: *const Obj) -> Obj {
|
||||
let block = |args: &[Obj], _kwargs: &Map| {
|
||||
// SAFETY: reference is discarded at the end of the block
|
||||
let mut buf = unsafe { get_buffer_mut(args[1]) }?;
|
||||
|
||||
if args.len() > 2 {
|
||||
let offset: usize = args[2].try_into()?;
|
||||
buf = buf
|
||||
.get_mut(offset..)
|
||||
.ok_or(Error::ValueError(c"Offset out of bounds"))?;
|
||||
}
|
||||
if buf.len() < RX_PACKET_SIZE {
|
||||
return Err(Error::ValueError(c"Buffer too small"));
|
||||
}
|
||||
let read_len = read(buf, RX_PACKET_SIZE)?;
|
||||
if read_len != RX_PACKET_SIZE {
|
||||
return Err(Error::ValueError(c"Unexpected read length"));
|
||||
}
|
||||
read_len.try_into()
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, &Map::EMPTY, block) }
|
||||
}
|
||||
|
||||
static BLE_INTERFACE_TYPE: Type = obj_type! {
|
||||
name: Qstr::MP_QSTR_BleInterface,
|
||||
locals: &obj_dict!(obj_map! {
|
||||
Qstr::MP_QSTR_iface_num => obj_fn_1!(py_iface_num).as_obj(),
|
||||
Qstr::MP_QSTR_write => obj_fn_2!(py_iface_write).as_obj(),
|
||||
Qstr::MP_QSTR_read => obj_fn_var!(2, 3, py_iface_read).as_obj(),
|
||||
Qstr::MP_QSTR_RX_PACKET_LEN => Obj::small_int(RX_PACKET_SIZE as u16),
|
||||
Qstr::MP_QSTR_TX_PACKET_LEN => Obj::small_int(TX_PACKET_SIZE as u16),
|
||||
}),
|
||||
};
|
||||
|
||||
static BLE_INTERFACE_OBJ: SimpleTypeObj = SimpleTypeObj::new(&BLE_INTERFACE_TYPE);
|
||||
|
||||
#[no_mangle]
|
||||
#[rustfmt::skip]
|
||||
pub static mp_module_trezorble: Module = obj_module! {
|
||||
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorble.to_obj(),
|
||||
|
||||
/// class BleInterface:
|
||||
/// """
|
||||
/// BLE interface wrapper.
|
||||
/// """
|
||||
///
|
||||
/// RX_PACKET_LEN: int
|
||||
/// """Length of one BLE RX packet."""
|
||||
///
|
||||
/// TX_PACKET_LEN: int
|
||||
/// """Length of one BLE TX packet."""
|
||||
///
|
||||
/// def iface_num(self) -> int:
|
||||
/// """
|
||||
/// Returns the configured number of this interface.
|
||||
/// """
|
||||
///
|
||||
/// def write(self, msg: bytes) -> int:
|
||||
/// """
|
||||
/// Sends message over BLE
|
||||
/// """
|
||||
///
|
||||
/// def read(self, buf: bytearray, offset: int = 0) -> int:
|
||||
/// """
|
||||
/// Reads message using BLE (device).
|
||||
/// """
|
||||
///
|
||||
/// mock:global
|
||||
///
|
||||
/// interface: BleInterface
|
||||
/// """BLE interface instance."""
|
||||
Qstr::MP_QSTR_interface => BLE_INTERFACE_OBJ.as_obj(),
|
||||
|
||||
/// mock:global
|
||||
|
||||
/// def erase_bonds():
|
||||
/// """
|
||||
/// Erases all BLE bonds.
|
||||
/// Raises exception if BLE reports an error.
|
||||
/// """
|
||||
Qstr::MP_QSTR_erase_bonds => obj_fn_0!(py_erase_bonds).as_obj(),
|
||||
|
||||
/// def unpair():
|
||||
/// """
|
||||
/// Erases bond for current connection, if any.
|
||||
/// Raises exception if BLE driver reports an error.
|
||||
/// """
|
||||
Qstr::MP_QSTR_unpair => obj_fn_0!(py_unpair).as_obj(),
|
||||
|
||||
/// def start_comm():
|
||||
/// """
|
||||
/// Start communication with BLE chip.
|
||||
/// """
|
||||
Qstr::MP_QSTR_start_comm => obj_fn_0!(py_start_comm).as_obj(),
|
||||
|
||||
/// def start_advertising(whitelist: bool, name: str | None):
|
||||
/// """
|
||||
/// Start advertising.
|
||||
/// Raises exception if BLE driver reports an error.
|
||||
/// """
|
||||
Qstr::MP_QSTR_start_advertising => obj_fn_2!(py_start_advertising).as_obj(),
|
||||
|
||||
/// def stop_advertising():
|
||||
/// """
|
||||
/// Stop advertising.
|
||||
/// Raises exception if BLE driver reports an error.
|
||||
/// """
|
||||
Qstr::MP_QSTR_stop_advertising => obj_fn_0!(py_stop_advertising).as_obj(),
|
||||
|
||||
/// def disconnect():
|
||||
/// """
|
||||
/// Disconnect BLE.
|
||||
/// Raises exception if BLE driver reports an error.
|
||||
/// """
|
||||
Qstr::MP_QSTR_disconnect => obj_fn_0!(py_disconnect).as_obj(),
|
||||
|
||||
/// def peer_count() -> int:
|
||||
/// """
|
||||
/// Get peer count (number of bonded devices).
|
||||
/// """
|
||||
Qstr::MP_QSTR_peer_count => obj_fn_0!(py_peer_count).as_obj(),
|
||||
|
||||
/// def is_connected() -> bool:
|
||||
/// """
|
||||
/// True if a host is connected to us. May or may not be paired.
|
||||
/// """
|
||||
Qstr::MP_QSTR_is_connected => obj_fn_0!(py_is_connected).as_obj(),
|
||||
|
||||
/// def connection_flags() -> list[str]:
|
||||
/// """
|
||||
/// Returns current connection state as a list of string flags.
|
||||
/// """
|
||||
Qstr::MP_QSTR_connection_flags => obj_fn_0!(py_connection_flags).as_obj(),
|
||||
|
||||
/// def allow_pairing(code: int):
|
||||
/// """
|
||||
/// Accept BLE pairing request. Code must match the one received with
|
||||
/// BLE_PAIRING_REQUEST event.
|
||||
/// Raises exception if BLE driver reports an error.
|
||||
/// """
|
||||
Qstr::MP_QSTR_allow_pairing => obj_fn_1!(py_allow_pairing).as_obj(),
|
||||
|
||||
/// def reject_pairing():
|
||||
/// """
|
||||
/// Reject BLE pairing request.
|
||||
/// Raises exception if BLE driver reports an error.
|
||||
/// """
|
||||
Qstr::MP_QSTR_reject_pairing => obj_fn_0!(py_reject_pairing).as_obj(),
|
||||
};
|
164
core/embed/rust/src/trezorhal/ble/mod.rs
Normal file
164
core/embed/rust/src/trezorhal/ble/mod.rs
Normal file
@ -0,0 +1,164 @@
|
||||
#[cfg(feature = "micropython")]
|
||||
mod micropython;
|
||||
|
||||
use crate::error::Error;
|
||||
use core::mem::size_of;
|
||||
|
||||
use super::{ffi, model};
|
||||
|
||||
pub const ADV_NAME_LEN: usize = ffi::BLE_ADV_NAME_LEN as usize;
|
||||
pub const PAIRING_CODE_LEN: usize = ffi::BLE_PAIRING_CODE_LEN as usize;
|
||||
pub const RX_PACKET_SIZE: usize = ffi::BLE_RX_PACKET_SIZE as usize;
|
||||
pub const TX_PACKET_SIZE: usize = ffi::BLE_TX_PACKET_SIZE as usize;
|
||||
|
||||
const COMMAND_FAILED: Error = Error::RuntimeError(c"BLE command failed");
|
||||
const WRITE_FAILED: Error = Error::RuntimeError(c"BLE write failed");
|
||||
|
||||
// NOTE: replace with floor_char_boundary when stable
|
||||
fn prefix_utf8_bytes(text: &str, max_len: usize) -> &[u8] {
|
||||
let mut i = text.len().min(max_len);
|
||||
while !text.is_char_boundary(i) {
|
||||
i -= 1;
|
||||
}
|
||||
&text.as_bytes()[..i]
|
||||
}
|
||||
|
||||
fn state() -> ffi::ble_state_t {
|
||||
let mut state = ffi::ble_state_t {
|
||||
connected: false,
|
||||
peer_count: 0,
|
||||
connectable: false,
|
||||
pairing: false,
|
||||
pairing_requested: false,
|
||||
state_known: false,
|
||||
};
|
||||
unsafe { ffi::ble_get_state(&mut state as _) };
|
||||
state
|
||||
}
|
||||
|
||||
fn issue_command(
|
||||
cmd_type: ffi::ble_command_type_t,
|
||||
cmd_data: ffi::ble_command_data_t,
|
||||
) -> Result<(), Error> {
|
||||
let data_len = match cmd_type {
|
||||
ffi::ble_command_type_t_BLE_ALLOW_PAIRING => PAIRING_CODE_LEN,
|
||||
ffi::ble_command_type_t_BLE_PAIRING_MODE | ffi::ble_command_type_t_BLE_SWITCH_ON => {
|
||||
size_of::<ffi::ble_adv_start_cmd_data_t>()
|
||||
}
|
||||
_ => 0,
|
||||
};
|
||||
let mut cmd = ffi::ble_command_t {
|
||||
cmd_type,
|
||||
data_len: unwrap!(data_len.try_into()),
|
||||
data: cmd_data,
|
||||
};
|
||||
if unsafe { ffi::ble_issue_command(&mut cmd as _) } {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(COMMAND_FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
fn data_advname(name: &str) -> ffi::ble_command_data_t {
|
||||
let mut data = ffi::ble_command_data_t {
|
||||
adv_start: ffi::ble_adv_start_cmd_data_t {
|
||||
name: [0u8; ADV_NAME_LEN],
|
||||
static_mac: false,
|
||||
},
|
||||
};
|
||||
let bytes = prefix_utf8_bytes(name, ADV_NAME_LEN);
|
||||
unsafe {
|
||||
data.adv_start.name[..bytes.len()].copy_from_slice(bytes);
|
||||
}
|
||||
data
|
||||
}
|
||||
|
||||
fn data_code(mut code: u32) -> ffi::ble_command_data_t {
|
||||
let mut pairing_code: [u8; PAIRING_CODE_LEN] = [0; PAIRING_CODE_LEN];
|
||||
for i in (0..PAIRING_CODE_LEN).rev() {
|
||||
let digit = b'0' + ((code % 10) as u8);
|
||||
code /= 10;
|
||||
pairing_code[i] = digit;
|
||||
}
|
||||
ffi::ble_command_data_t { pairing_code }
|
||||
}
|
||||
|
||||
const fn data_none() -> ffi::ble_command_data_t {
|
||||
ffi::ble_command_data_t { raw: [0; 32] }
|
||||
}
|
||||
|
||||
pub fn pairing_mode(name: &str) -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_PAIRING_MODE, data_advname(name))
|
||||
}
|
||||
|
||||
pub fn connectable_mode(name: &str) -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_SWITCH_ON, data_advname(name))
|
||||
}
|
||||
|
||||
pub fn stop_advertising() -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_SWITCH_OFF, data_none())
|
||||
}
|
||||
|
||||
pub fn allow_pairing(code: u32) -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_ALLOW_PAIRING, data_code(code))
|
||||
}
|
||||
|
||||
pub fn reject_pairing() -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_REJECT_PAIRING, data_none())
|
||||
}
|
||||
|
||||
pub fn erase_bonds() -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_ERASE_BONDS, data_none())
|
||||
}
|
||||
|
||||
pub fn unpair() -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_UNPAIR, data_none())
|
||||
}
|
||||
|
||||
pub fn disconnect() -> Result<(), Error> {
|
||||
issue_command(ffi::ble_command_type_t_BLE_DISCONNECT, data_none())
|
||||
}
|
||||
|
||||
pub fn start_comm() {
|
||||
unsafe { ffi::ble_start() }
|
||||
}
|
||||
|
||||
pub fn peer_count() -> u8 {
|
||||
state().peer_count
|
||||
}
|
||||
|
||||
pub fn is_started() -> bool {
|
||||
state().state_known
|
||||
}
|
||||
|
||||
pub fn is_connectable() -> bool {
|
||||
state().connectable
|
||||
}
|
||||
|
||||
pub fn is_connected() -> bool {
|
||||
state().connected
|
||||
}
|
||||
|
||||
pub fn is_pairing() -> bool {
|
||||
state().pairing
|
||||
}
|
||||
|
||||
pub fn is_pairing_requested() -> bool {
|
||||
state().pairing_requested
|
||||
}
|
||||
|
||||
pub fn write(bytes: &[u8]) -> Result<(), Error> {
|
||||
let len = bytes.len() as u16;
|
||||
let success = unsafe { ffi::ble_write(bytes.as_ptr(), len) };
|
||||
if success {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(WRITE_FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(buf: &mut [u8], max_len: usize) -> Result<usize, Error> {
|
||||
let len: u16 = max_len.try_into()?;
|
||||
let read_len = unsafe { super::ffi::ble_read(buf.as_mut_ptr(), len) };
|
||||
Ok(read_len.try_into()?)
|
||||
}
|
@ -1,333 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/sysevent.h>
|
||||
|
||||
/// package: trezorio.ble
|
||||
|
||||
///
|
||||
/// def erase_bonds() -> bool:
|
||||
/// """
|
||||
/// Erases all BLE bonds
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_erase_bonds(void) {
|
||||
ble_command_t cmd = {.cmd_type = BLE_ERASE_BONDS, .data_len = 0};
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_erase_bonds_obj,
|
||||
mod_trezorio_BLE_erase_bonds);
|
||||
|
||||
/// def unpair() -> bool:
|
||||
/// """
|
||||
/// Erases bond for current connection, if any
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_unpair(void) {
|
||||
ble_command_t cmd = {.cmd_type = BLE_UNPAIR, .data_len = 0};
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_unpair_obj,
|
||||
mod_trezorio_BLE_unpair);
|
||||
|
||||
/// def start_comm() -> bool:
|
||||
/// """
|
||||
/// Start communication with BLE chip
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_start_comm(void) {
|
||||
ble_start();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_start_comm_obj,
|
||||
mod_trezorio_BLE_start_comm);
|
||||
|
||||
/// def start_advertising(whitelist: bool, name: str | None) -> bool:
|
||||
/// """
|
||||
/// Start advertising
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_start_advertising(size_t n_args,
|
||||
const mp_obj_t *args) {
|
||||
bool whitelist_bool = mp_obj_is_true(args[0]);
|
||||
|
||||
mp_buffer_info_t name = {0};
|
||||
|
||||
char *name_buf = NULL;
|
||||
int name_len = 0;
|
||||
|
||||
if (n_args == 1 || !mp_get_buffer(args[1], &name, MP_BUFFER_READ)) {
|
||||
name_buf = MODEL_FULL_NAME;
|
||||
name_len = strlen(MODEL_FULL_NAME);
|
||||
} else {
|
||||
name_buf = name.buf;
|
||||
name_len = name.len;
|
||||
}
|
||||
|
||||
ble_command_t cmd = {
|
||||
.cmd_type = whitelist_bool ? BLE_SWITCH_ON : BLE_PAIRING_MODE,
|
||||
.data_len = sizeof(ble_adv_start_cmd_data_t)};
|
||||
|
||||
// get a minimum of the two lengths
|
||||
int len = name_len < BLE_ADV_NAME_LEN ? name_len : BLE_ADV_NAME_LEN;
|
||||
|
||||
cmd.data.adv_start.static_mac = false;
|
||||
memcpy(cmd.data.adv_start.name, name_buf, len);
|
||||
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
|
||||
mod_trezorio_BLE_start_advertising_obj, 1, 2,
|
||||
mod_trezorio_BLE_start_advertising);
|
||||
|
||||
/// def stop_advertising() -> bool:
|
||||
/// """
|
||||
/// Stop advertising
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_stop_advertising(void) {
|
||||
ble_command_t cmd = {.cmd_type = BLE_SWITCH_OFF, .data_len = 0};
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_stop_advertising_obj,
|
||||
mod_trezorio_BLE_stop_advertising);
|
||||
|
||||
/// def disconnect() -> bool:
|
||||
/// """
|
||||
/// Disconnect BLE
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_disconnect(void) {
|
||||
ble_command_t cmd = {.cmd_type = BLE_DISCONNECT, .data_len = 0};
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_disconnect_obj,
|
||||
mod_trezorio_BLE_disconnect);
|
||||
|
||||
/// def peer_count() -> int:
|
||||
/// """
|
||||
/// Get peer count (number of bonded devices)
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_peer_count(void) {
|
||||
ble_state_t state;
|
||||
ble_get_state(&state);
|
||||
return MP_OBJ_NEW_SMALL_INT(state.peer_count);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_peer_count_obj,
|
||||
mod_trezorio_BLE_peer_count);
|
||||
|
||||
/// def connection_state() -> int:
|
||||
/// """
|
||||
/// Returns current connection state as flags:
|
||||
///
|
||||
/// 0x01 state known
|
||||
/// 0x02 connectable
|
||||
/// 0x04 connected
|
||||
/// 0x08 pairing
|
||||
/// 0x10 pairing request
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_connection_state(void) {
|
||||
ble_state_t state;
|
||||
ble_get_state(&state);
|
||||
mp_int_t flags = (state.state_known << 0) | (state.connectable << 1) |
|
||||
(state.connected << 2) | (state.pairing << 3) |
|
||||
(state.pairing_requested << 4);
|
||||
return MP_OBJ_NEW_SMALL_INT(flags);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_connection_state_obj,
|
||||
mod_trezorio_BLE_connection_state);
|
||||
|
||||
const size_t CODE_LEN = 6;
|
||||
static bool encode_pairing_code(mp_obj_t obj, uint8_t *outbuf) {
|
||||
mp_int_t code = mp_obj_get_int(obj);
|
||||
if (code < 0 || code > 999999) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < CODE_LEN; i++) {
|
||||
outbuf[CODE_LEN - i - 1] = '0' + (code % 10);
|
||||
code /= 10;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// def allow_pairing(code: int) -> bool:
|
||||
/// """
|
||||
/// Accept BLE pairing request. Code must match the one received with
|
||||
/// BLE_PAIRING_REQUEST event.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_allow_pairing(mp_obj_t code) {
|
||||
ble_command_t cmd = {.cmd_type = BLE_ALLOW_PAIRING, .data_len = CODE_LEN};
|
||||
if (!encode_pairing_code(code, cmd.data.raw)) {
|
||||
return mp_const_false;
|
||||
}
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_BLE_allow_pairing_obj,
|
||||
mod_trezorio_BLE_allow_pairing);
|
||||
|
||||
/// def reject_pairing() -> bool:
|
||||
/// """
|
||||
/// Reject BLE pairing request
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BLE_reject_pairing(void) {
|
||||
ble_command_t cmd = {.cmd_type = BLE_REJECT_PAIRING, .data_len = 0};
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_reject_pairing_obj,
|
||||
mod_trezorio_BLE_reject_pairing);
|
||||
|
||||
/// class BleInterface:
|
||||
/// """
|
||||
/// BLE interface wrapper.
|
||||
/// """
|
||||
typedef struct _mp_obj_BleInterface_t {
|
||||
mp_obj_base_t base;
|
||||
} mp_obj_BleInterface_t;
|
||||
|
||||
/// def __init__(
|
||||
/// self,
|
||||
/// ) -> None:
|
||||
/// """
|
||||
/// Initialize BLE interface.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BleInterface_make_new(const mp_obj_type_t *type,
|
||||
size_t n_args, size_t n_kw,
|
||||
const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
mp_obj_BleInterface_t *o = mp_obj_malloc(mp_obj_BleInterface_t, type);
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
/// def iface_num(self) -> int:
|
||||
/// """
|
||||
/// Returns the configured number of this interface.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BleInterface_iface_num(mp_obj_t self) {
|
||||
return MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_BleInterface_iface_num_obj,
|
||||
mod_trezorio_BleInterface_iface_num);
|
||||
|
||||
/// def write(self, msg: bytes) -> int:
|
||||
/// """
|
||||
/// Sends message over BLE
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BleInterface_write(mp_obj_t self, mp_obj_t msg) {
|
||||
mp_buffer_info_t buf = {0};
|
||||
mp_get_buffer_raise(msg, &buf, MP_BUFFER_READ);
|
||||
bool success = ble_write(buf.buf, buf.len);
|
||||
if (success) {
|
||||
return MP_OBJ_NEW_SMALL_INT(buf.len);
|
||||
} else {
|
||||
return MP_OBJ_NEW_SMALL_INT(-1);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_BleInterface_write_obj,
|
||||
mod_trezorio_BleInterface_write);
|
||||
|
||||
/// def read(self, buf: bytearray, offset: int = 0) -> int:
|
||||
/// """
|
||||
/// Reads message using BLE (device).
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_BleInterface_read(size_t n_args,
|
||||
const mp_obj_t *args) {
|
||||
mp_buffer_info_t buf = {0};
|
||||
mp_get_buffer_raise(args[1], &buf, MP_BUFFER_WRITE);
|
||||
|
||||
int offset = 0;
|
||||
if (n_args >= 2) {
|
||||
offset = mp_obj_get_int(args[2]);
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
mp_raise_ValueError("Negative offset not allowed");
|
||||
}
|
||||
|
||||
if (offset > buf.len) {
|
||||
mp_raise_ValueError("Offset out of bounds");
|
||||
}
|
||||
|
||||
uint32_t buffer_space = buf.len - offset;
|
||||
|
||||
if (buffer_space < BLE_RX_PACKET_SIZE) {
|
||||
mp_raise_ValueError("Buffer too small");
|
||||
}
|
||||
|
||||
uint32_t r = ble_read(&((uint8_t *)buf.buf)[offset], BLE_RX_PACKET_SIZE);
|
||||
|
||||
if (r != BLE_RX_PACKET_SIZE) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, "Unexpected read length");
|
||||
}
|
||||
|
||||
return MP_OBJ_NEW_SMALL_INT(r);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_BleInterface_read_obj,
|
||||
2, 3,
|
||||
mod_trezorio_BleInterface_read);
|
||||
|
||||
/// RX_PACKET_LEN: int
|
||||
/// """Length of one BLE RX packet."""
|
||||
|
||||
/// TX_PACKET_LEN: int
|
||||
/// """Length of one BLE TX packet."""
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_trezorio_BleInterface_locals_dict_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_iface_num),
|
||||
MP_ROM_PTR(&mod_trezorio_BleInterface_iface_num_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_write),
|
||||
MP_ROM_PTR(&mod_trezorio_BleInterface_write_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_read),
|
||||
MP_ROM_PTR(&mod_trezorio_BleInterface_read_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_RX_PACKET_LEN), MP_ROM_INT(BLE_RX_PACKET_SIZE)},
|
||||
{MP_ROM_QSTR(MP_QSTR_TX_PACKET_LEN), MP_ROM_INT(BLE_TX_PACKET_SIZE)},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_BleInterface_locals_dict,
|
||||
mod_trezorio_BleInterface_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t mod_trezorio_BleInterface_type = {
|
||||
{&mp_type_type},
|
||||
.name = MP_QSTR_BleInterface,
|
||||
.make_new = mod_trezorio_BleInterface_make_new,
|
||||
.locals_dict = (void *)&mod_trezorio_BleInterface_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_trezorio_BLE_globals_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ble)},
|
||||
{MP_ROM_QSTR(MP_QSTR_erase_bonds),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_erase_bonds_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_unpair), MP_ROM_PTR(&mod_trezorio_BLE_unpair_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_start_comm),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_start_comm_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_start_advertising),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_start_advertising_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_stop_advertising),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_stop_advertising_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_disconnect),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_disconnect_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_peer_count),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_peer_count_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_connection_state),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_connection_state_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_allow_pairing),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_allow_pairing_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_reject_pairing),
|
||||
MP_ROM_PTR(&mod_trezorio_BLE_reject_pairing_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BleInterface),
|
||||
MP_ROM_PTR(&mod_trezorio_BleInterface_type)},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_BLE_globals,
|
||||
mod_trezorio_BLE_globals_table);
|
||||
|
||||
STATIC const mp_obj_module_t mod_trezorio_BLE_module = {
|
||||
.base = {&mp_type_module},
|
||||
.globals = (mp_obj_dict_t *)&mod_trezorio_BLE_globals};
|
@ -51,9 +51,6 @@ uint32_t last_touch_sample_time = 0;
|
||||
#include "modtrezorio-webusb.h"
|
||||
#include "modtrezorio-usb.h"
|
||||
// clang-format on
|
||||
#ifdef USE_BLE
|
||||
#include "modtrezorio-ble.h"
|
||||
#endif
|
||||
#ifdef USE_SD_CARD
|
||||
#include "modtrezorio-fatfs.h"
|
||||
#include "modtrezorio-sdcard.h"
|
||||
@ -99,7 +96,6 @@ STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
|
||||
#endif
|
||||
|
||||
#ifdef USE_BLE
|
||||
{MP_ROM_QSTR(MP_QSTR_ble), MP_ROM_PTR(&mod_trezorio_BLE_module)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BLE_EVENT), MP_ROM_INT(SYSHANDLE_BLE)},
|
||||
#endif
|
||||
#ifdef USE_TOUCH
|
||||
|
@ -31,3 +31,7 @@ MP_REGISTER_MODULE(MP_QSTR_trezorproto, mp_module_trezorproto);
|
||||
#if MICROPY_PY_TREZORTRANSLATE
|
||||
MP_REGISTER_MODULE(MP_QSTR_trezortranslate, mp_module_trezortranslate);
|
||||
#endif
|
||||
|
||||
#ifdef USE_BLE
|
||||
MP_REGISTER_MODULE(MP_QSTR_trezorble, mp_module_trezorble);
|
||||
#endif
|
||||
|
114
core/mocks/generated/trezorble.pyi
Normal file
114
core/mocks/generated/trezorble.pyi
Normal file
@ -0,0 +1,114 @@
|
||||
from typing import *
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
class BleInterface:
|
||||
"""
|
||||
BLE interface wrapper.
|
||||
"""
|
||||
RX_PACKET_LEN: int
|
||||
"""Length of one BLE RX packet."""
|
||||
TX_PACKET_LEN: int
|
||||
"""Length of one BLE TX packet."""
|
||||
|
||||
def iface_num(self) -> int:
|
||||
"""
|
||||
Returns the configured number of this interface.
|
||||
"""
|
||||
|
||||
def write(self, msg: bytes) -> int:
|
||||
"""
|
||||
Sends message over BLE
|
||||
"""
|
||||
|
||||
def read(self, buf: bytearray, offset: int = 0) -> int:
|
||||
"""
|
||||
Reads message using BLE (device).
|
||||
"""
|
||||
interface: BleInterface
|
||||
"""BLE interface instance."""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def erase_bonds():
|
||||
"""
|
||||
Erases all BLE bonds.
|
||||
Raises exception if BLE reports an error.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def unpair():
|
||||
"""
|
||||
Erases bond for current connection, if any.
|
||||
Raises exception if BLE driver reports an error.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def start_comm():
|
||||
"""
|
||||
Start communication with BLE chip.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def start_advertising(whitelist: bool, name: str | None):
|
||||
"""
|
||||
Start advertising.
|
||||
Raises exception if BLE driver reports an error.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def stop_advertising():
|
||||
"""
|
||||
Stop advertising.
|
||||
Raises exception if BLE driver reports an error.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def disconnect():
|
||||
"""
|
||||
Disconnect BLE.
|
||||
Raises exception if BLE driver reports an error.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def peer_count() -> int:
|
||||
"""
|
||||
Get peer count (number of bonded devices).
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def is_connected() -> bool:
|
||||
"""
|
||||
True if a host is connected to us. May or may not be paired.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def connection_flags() -> list[str]:
|
||||
"""
|
||||
Returns current connection state as a list of string flags.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def allow_pairing(code: int):
|
||||
"""
|
||||
Accept BLE pairing request. Code must match the one received with
|
||||
BLE_PAIRING_REQUEST event.
|
||||
Raises exception if BLE driver reports an error.
|
||||
"""
|
||||
|
||||
|
||||
# rust/src/trezorhal/ble/micropython.rs
|
||||
def reject_pairing():
|
||||
"""
|
||||
Reject BLE pairing request.
|
||||
Raises exception if BLE driver reports an error.
|
||||
"""
|
@ -1,112 +0,0 @@
|
||||
from typing import *
|
||||
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def erase_bonds() -> bool:
|
||||
"""
|
||||
Erases all BLE bonds
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def unpair() -> bool:
|
||||
"""
|
||||
Erases bond for current connection, if any
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def start_comm() -> bool:
|
||||
"""
|
||||
Start communication with BLE chip
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def start_advertising(whitelist: bool, name: str | None) -> bool:
|
||||
"""
|
||||
Start advertising
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def stop_advertising() -> bool:
|
||||
"""
|
||||
Stop advertising
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def disconnect() -> bool:
|
||||
"""
|
||||
Disconnect BLE
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def peer_count() -> int:
|
||||
"""
|
||||
Get peer count (number of bonded devices)
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def connection_state() -> int:
|
||||
"""
|
||||
Returns current connection state as flags:
|
||||
|
||||
0x01 state known
|
||||
0x02 connectable
|
||||
0x04 connected
|
||||
0x08 pairing
|
||||
0x10 pairing request
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def allow_pairing(code: int) -> bool:
|
||||
"""
|
||||
Accept BLE pairing request. Code must match the one received with
|
||||
BLE_PAIRING_REQUEST event.
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
def reject_pairing() -> bool:
|
||||
"""
|
||||
Reject BLE pairing request
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ble.h
|
||||
class BleInterface:
|
||||
"""
|
||||
BLE interface wrapper.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
) -> None:
|
||||
"""
|
||||
Initialize BLE interface.
|
||||
"""
|
||||
|
||||
def iface_num(self) -> int:
|
||||
"""
|
||||
Returns the configured number of this interface.
|
||||
"""
|
||||
|
||||
def write(self, msg: bytes) -> int:
|
||||
"""
|
||||
Sends message over BLE
|
||||
"""
|
||||
|
||||
def read(self, buf: bytearray, offset: int = 0) -> int:
|
||||
"""
|
||||
Reads message using BLE (device).
|
||||
"""
|
||||
RX_PACKET_LEN: int
|
||||
"""Length of one BLE RX packet."""
|
||||
TX_PACKET_LEN: int
|
||||
"""Length of one BLE TX packet."""
|
@ -1,6 +1,6 @@
|
||||
from trezorio import ble
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import trezorble as ble
|
||||
from trezor import TR
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -52,7 +52,7 @@ usb.bus.open(storage.device.get_device_id())
|
||||
|
||||
# enable BLE, allow connections
|
||||
if utils.USE_BLE:
|
||||
from trezorio import ble
|
||||
import trezorble as ble
|
||||
ble.start_comm()
|
||||
|
||||
# allow connections from bonded peers if any
|
||||
|
@ -24,10 +24,10 @@ workflow.start_default()
|
||||
wire.setup(usb.iface_wire)
|
||||
|
||||
if utils.USE_BLE:
|
||||
from trezorio import ble
|
||||
import trezorble as ble
|
||||
|
||||
# initialize the wire codec over BLE
|
||||
wire.setup(ble.BleInterface())
|
||||
wire.setup(ble.interface)
|
||||
|
||||
# start the event loop
|
||||
loop.run()
|
||||
|
Loading…
Reference in New Issue
Block a user