mirror of
https://github.com/trezor/trezor-firmware.git
synced 2026-02-20 00:33:30 +01:00
receive event
This commit is contained in:
@@ -586,6 +586,7 @@ fn generate_ipc_bindings() {
|
||||
.allowlist_function("ipc_send")
|
||||
.allowlist_function("ipc_message_free")
|
||||
.allowlist_function("ipc_try_receive")
|
||||
.allowlist_function("ipc_has_message")
|
||||
.allowlist_function("ipc_register")
|
||||
.allowlist_function("ipc_unregister")
|
||||
.allowlist_type("ipc_message_t")
|
||||
|
||||
@@ -427,6 +427,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_instructions_verb;
|
||||
MP_QSTR_interface;
|
||||
MP_QSTR_ipc_cb;
|
||||
MP_QSTR_ipc_event;
|
||||
MP_QSTR_is_connectable;
|
||||
MP_QSTR_is_connected;
|
||||
MP_QSTR_is_data;
|
||||
|
||||
@@ -122,6 +122,10 @@ impl<'a> IpcMessage<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_message(remote: RemoteSysTask) -> bool {
|
||||
unsafe { ffi::ipc_has_message(remote.into()) }
|
||||
}
|
||||
|
||||
pub fn try_receive(remote: RemoteSysTask) -> Option<Self> {
|
||||
let mut lowlevel_message = ffi::ipc_message_t {
|
||||
remote: remote.into(),
|
||||
|
||||
@@ -1507,6 +1507,9 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
||||
/// def ble_event(self, event: int, data: bytes) -> LayoutState | None:
|
||||
/// """Receive a BLE events."""
|
||||
///
|
||||
/// def ipc_event(self) -> LayoutState | None:
|
||||
/// """Signal an incoming IPC message."""
|
||||
///
|
||||
/// if utils.USE_POWER_MANAGER:
|
||||
/// def pm_event(self, flags: int) -> LayoutState | None:
|
||||
/// """Receive a power management event with packed flags."""
|
||||
|
||||
@@ -15,6 +15,7 @@ use crate::{
|
||||
|
||||
#[cfg(feature = "ble")]
|
||||
use crate::ui::event::BLEEvent;
|
||||
use crate::ui::event::IpcEvent;
|
||||
#[cfg(feature = "button")]
|
||||
use crate::ui::event::ButtonEvent;
|
||||
#[cfg(feature = "power_manager")]
|
||||
@@ -327,6 +328,7 @@ pub enum Event {
|
||||
Touch(TouchEvent),
|
||||
#[cfg(feature = "ble")]
|
||||
BLE(BLEEvent),
|
||||
IPC(IpcEvent),
|
||||
#[cfg(feature = "power_manager")]
|
||||
PM(PMEvent),
|
||||
USBWire,
|
||||
|
||||
14
core/embed/rust/src/ui/event/ipc.rs
Normal file
14
core/embed/rust/src/ui/event/ipc.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use crate::error::Error;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
|
||||
pub enum IpcEvent {
|
||||
Received,
|
||||
}
|
||||
|
||||
impl IpcEvent {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
let result = Self::Received;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,14 @@ pub mod usb;
|
||||
#[cfg(feature = "ble")]
|
||||
mod ble;
|
||||
|
||||
mod ipc;
|
||||
|
||||
#[cfg(feature = "power_manager")]
|
||||
mod power_manager;
|
||||
|
||||
#[cfg(feature = "ble")]
|
||||
pub use ble::BLEEvent;
|
||||
pub use ipc::IpcEvent;
|
||||
#[cfg(feature = "button")]
|
||||
pub use button::{ButtonEvent, PhysicalButton};
|
||||
#[cfg(feature = "power_manager")]
|
||||
|
||||
@@ -14,6 +14,8 @@ use num_traits::ToPrimitive;
|
||||
#[cfg(feature = "ble")]
|
||||
use crate::ui::event::BLEEvent;
|
||||
|
||||
use crate::ui::event::IpcEvent;
|
||||
|
||||
#[cfg(feature = "button")]
|
||||
use crate::{
|
||||
trezorhal::button::{PhysicalButton, PhysicalButtonEvent},
|
||||
@@ -412,7 +414,8 @@ 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_ble_event => obj_fn_var!(2, 3, ui_layout_ble_event).as_obj(),
|
||||
Qstr::MP_QSTR_ipc_event => obj_fn_var!(1, 1, ui_layout_ipc_event).as_obj(),
|
||||
Qstr::MP_QSTR_pm_event => obj_fn_2!(ui_layout_pm_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(),
|
||||
@@ -574,6 +577,20 @@ extern "C" fn ui_layout_ble_event(_n_args: usize, _args: *const Obj) -> Obj {
|
||||
Obj::const_none()
|
||||
}
|
||||
|
||||
extern "C" fn ui_layout_ipc_event(n_args: usize, args: *const Obj) -> Obj {
|
||||
let block = |args: &[Obj], _kwargs: &Map| {
|
||||
if args.len() != 1 {
|
||||
return Err(Error::TypeError);
|
||||
}
|
||||
let this: Gc<LayoutObj> = args[0].try_into()?;
|
||||
|
||||
let event = IpcEvent::new()?;
|
||||
let msg = this.inner_mut().obj_event(Event::IPC(event))?;
|
||||
Ok(msg)
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, &Map::EMPTY, block) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "power_manager")]
|
||||
extern "C" fn ui_layout_pm_event(this: Obj, flags: Obj) -> Obj {
|
||||
let block = || {
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::{
|
||||
text::{layout::LayoutFit, LineBreaking},
|
||||
Component, Event, EventCtx, Never, TextLayout,
|
||||
},
|
||||
event::IpcEvent,
|
||||
geometry::Rect,
|
||||
shape::Renderer,
|
||||
util::Pager,
|
||||
@@ -60,16 +61,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_next(&mut self, ctx: &mut EventCtx) {
|
||||
fn switch_next(&mut self) {
|
||||
debug_assert!(!self.content.pager.is_last());
|
||||
self.content.switch_next(ctx);
|
||||
self.content.switch_next();
|
||||
self.hint.update(self.content.pager());
|
||||
self.action_bar.update(self.content.pager());
|
||||
}
|
||||
|
||||
fn switch_prev(&mut self, ctx: &mut EventCtx) {
|
||||
fn switch_prev(&mut self) {
|
||||
debug_assert!(!self.content.pager.is_first());
|
||||
self.content.switch_prev(ctx);
|
||||
self.content.switch_prev();
|
||||
self.hint.update(self.content.pager());
|
||||
self.action_bar.update(self.content.pager());
|
||||
}
|
||||
@@ -106,12 +107,12 @@ where
|
||||
ActionBarMsg::Cancelled => return Some(LongContentScreenMsg::Cancelled),
|
||||
ActionBarMsg::Next => {
|
||||
debug_assert!(!self.content.pager.is_last());
|
||||
self.switch_next(ctx);
|
||||
self.switch_next();
|
||||
return None;
|
||||
}
|
||||
ActionBarMsg::Prev => {
|
||||
debug_assert!(!self.content.pager.is_first());
|
||||
self.switch_prev(ctx);
|
||||
self.switch_prev();
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@@ -171,7 +172,7 @@ where
|
||||
self.pager
|
||||
}
|
||||
|
||||
fn switch_next(&mut self, ctx: &mut EventCtx) {
|
||||
fn switch_next(&mut self) {
|
||||
debug_assert!(!self.pager.is_last());
|
||||
debug_assert!(matches!(self.state, ContentState::Ready));
|
||||
self.pager.goto_next();
|
||||
@@ -179,12 +180,12 @@ where
|
||||
|
||||
if self.pager.has_next() && self.cache.is_at_head() {
|
||||
let next = self.pager.next() as usize;
|
||||
self.request_page(ctx, next);
|
||||
self.request_page(next);
|
||||
self.state = ContentState::Waiting(next);
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_prev(&mut self, ctx: &mut EventCtx) {
|
||||
fn switch_prev(&mut self) {
|
||||
debug_assert!(!self.pager.is_first());
|
||||
debug_assert!(matches!(self.state, ContentState::Ready));
|
||||
self.pager.goto_prev();
|
||||
@@ -192,12 +193,12 @@ where
|
||||
|
||||
if self.pager.has_prev() && self.cache.is_at_tail() {
|
||||
let prev = self.pager.prev() as usize;
|
||||
self.request_page(ctx, prev);
|
||||
self.request_page(prev);
|
||||
self.state = ContentState::Waiting(prev);
|
||||
}
|
||||
}
|
||||
|
||||
fn request_page(&self, ctx: &mut EventCtx, idx: usize) {
|
||||
fn request_page(&self, idx: usize) {
|
||||
let data = UtilEnum::RequestPage { idx };
|
||||
|
||||
let mut arena = [MaybeUninit::<u8>::uninit(); 200];
|
||||
@@ -211,7 +212,6 @@ where
|
||||
.unwrap();
|
||||
|
||||
(self.request_cb)(&bytes, idx as u16);
|
||||
ctx.request_anim_frame();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,10 +229,10 @@ where
|
||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||
if matches!(event, Event::Attach(AttachType::Initial)) {
|
||||
debug_assert!(self.state == ContentState::Uninit);
|
||||
self.request_page(ctx, 0);
|
||||
self.request_page(0);
|
||||
}
|
||||
|
||||
if let Event::Timer(EventCtx::ANIM_FRAME_TIMER) = event {
|
||||
if let Event::IPC(IpcEvent::Received) = event {
|
||||
if let Some(message) = IpcMessage::try_receive(RemoteSysTask::Unknown(2)) {
|
||||
debug_assert!(matches!(
|
||||
self.state,
|
||||
@@ -245,7 +245,7 @@ where
|
||||
ctx.request_paint();
|
||||
if self.pager.has_next() {
|
||||
let idx = self.pager.next() as usize;
|
||||
self.request_page(ctx, idx);
|
||||
self.request_page(idx);
|
||||
ContentState::Waiting(idx)
|
||||
} else {
|
||||
ContentState::Ready
|
||||
@@ -272,7 +272,7 @@ where
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx.request_anim_frame();
|
||||
unimplemented!("Unexpected IPC message received");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ typedef struct {
|
||||
// Function code with flags (IPC_FN_xxx)
|
||||
uint32_t fn;
|
||||
// Pointer to the message payload data
|
||||
const void *data;
|
||||
const void* data;
|
||||
// Size of the payload data
|
||||
size_t size;
|
||||
} ipc_message_t;
|
||||
@@ -62,7 +62,7 @@ bool ipc_init(void);
|
||||
* @return true if the buffer was successfully registered
|
||||
*
|
||||
*/
|
||||
bool ipc_register(systask_id_t remote, void *buffer, size_t size);
|
||||
bool ipc_register(systask_id_t remote, void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Unregisters the IPC message buffer for the given task ID.
|
||||
@@ -72,6 +72,14 @@ bool ipc_register(systask_id_t remote, void *buffer, size_t size);
|
||||
*/
|
||||
void ipc_unregister(systask_id_t remote);
|
||||
|
||||
/**
|
||||
* @brief Checks if there are any pending IPC messages from the specified task.
|
||||
*
|
||||
* @param remote The remote task ID to check for messages.
|
||||
* @return true if there are pending messages, false otherwise
|
||||
*/
|
||||
bool ipc_has_message(systask_id_t remote);
|
||||
|
||||
/**
|
||||
* @brief Attempts to receive an IPC message without blocking.
|
||||
*
|
||||
@@ -79,7 +87,7 @@ void ipc_unregister(systask_id_t remote);
|
||||
* message.
|
||||
* @return true if a message was received and stored in `msg`
|
||||
*/
|
||||
bool ipc_try_receive(ipc_message_t *msg);
|
||||
bool ipc_try_receive(ipc_message_t* msg);
|
||||
|
||||
/**
|
||||
* @brief Releases resources associated with a received IPC message.
|
||||
@@ -89,7 +97,7 @@ bool ipc_try_receive(ipc_message_t *msg);
|
||||
*
|
||||
* @param msg Pointer to the freed `ipc_message_t` structure.
|
||||
*/
|
||||
void ipc_message_free(ipc_message_t *msg);
|
||||
void ipc_message_free(ipc_message_t* msg);
|
||||
|
||||
/**
|
||||
* @brief Sends an IPC message to the specified destination task.
|
||||
@@ -105,5 +113,5 @@ void ipc_message_free(ipc_message_t *msg);
|
||||
*
|
||||
* @return true if the message was successfully sent
|
||||
*/
|
||||
bool ipc_send(systask_id_t remote, uint32_t fn, const void *data,
|
||||
bool ipc_send(systask_id_t remote, uint32_t fn, const void* data,
|
||||
size_t data_size);
|
||||
|
||||
@@ -43,9 +43,9 @@ typedef struct {
|
||||
} ipc_queue_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *ptr;
|
||||
uint8_t *wptr;
|
||||
uint8_t *rptr;
|
||||
uint8_t* ptr;
|
||||
uint8_t* wptr;
|
||||
uint8_t* rptr;
|
||||
size_t size;
|
||||
} ipc_queue_t;
|
||||
|
||||
@@ -63,7 +63,7 @@ static ipc_driver_t g_ipc_driver = {
|
||||
static const syshandle_vmt_t g_ipc_handle_vmt;
|
||||
|
||||
bool ipc_init(void) {
|
||||
ipc_driver_t *drv = &g_ipc_driver;
|
||||
ipc_driver_t* drv = &g_ipc_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return true;
|
||||
@@ -73,7 +73,7 @@ bool ipc_init(void) {
|
||||
|
||||
for (systask_id_t task_id = 0; task_id < SYSTASK_MAX_TASKS; task_id++) {
|
||||
syshandle_t handle = SYSHANDLE_IPC0 + task_id;
|
||||
void *context = (void *)(uintptr_t)task_id;
|
||||
void* context = (void*)(uintptr_t)task_id;
|
||||
if (!syshandle_register(handle, &g_ipc_handle_vmt, context)) {
|
||||
return false;
|
||||
}
|
||||
@@ -83,8 +83,8 @@ bool ipc_init(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ipc_queue_t *ipc_queue(systask_id_t target, systask_id_t origin) {
|
||||
ipc_driver_t *drv = &g_ipc_driver;
|
||||
ipc_queue_t* ipc_queue(systask_id_t target, systask_id_t origin) {
|
||||
ipc_driver_t* drv = &g_ipc_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return NULL;
|
||||
@@ -97,9 +97,9 @@ ipc_queue_t *ipc_queue(systask_id_t target, systask_id_t origin) {
|
||||
return &drv->queue[target][origin];
|
||||
}
|
||||
|
||||
bool ipc_register(systask_id_t remote, void *buffer, size_t size) {
|
||||
bool ipc_register(systask_id_t remote, void* buffer, size_t size) {
|
||||
systask_id_t target = systask_id(systask_active());
|
||||
ipc_queue_t *queue = ipc_queue(target, remote);
|
||||
ipc_queue_t* queue = ipc_queue(target, remote);
|
||||
|
||||
if (queue == NULL) {
|
||||
return false;
|
||||
@@ -123,16 +123,16 @@ bool ipc_register(systask_id_t remote, void *buffer, size_t size) {
|
||||
|
||||
void ipc_unregister(systask_id_t remote) {
|
||||
systask_id_t target = systask_id(systask_active());
|
||||
ipc_queue_t *queue = ipc_queue(target, remote);
|
||||
ipc_queue_t* queue = ipc_queue(target, remote);
|
||||
if (queue != NULL) {
|
||||
memset(queue, 0, sizeof(ipc_queue_t));
|
||||
}
|
||||
}
|
||||
|
||||
bool ipc_try_receive(ipc_message_t *msg) {
|
||||
bool ipc_has_message(systask_id_t remote) {
|
||||
systask_id_t target = systask_id(systask_active());
|
||||
|
||||
ipc_queue_t *queue = ipc_queue(target, msg->remote);
|
||||
ipc_queue_t* queue = ipc_queue(target, remote);
|
||||
|
||||
if (queue == NULL || queue->ptr == NULL) {
|
||||
// Invalid target or no queue registered
|
||||
@@ -144,13 +144,23 @@ bool ipc_try_receive(ipc_message_t *msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ipc_queue_item_t *item = (ipc_queue_item_t *)queue->rptr;
|
||||
ipc_queue_item_t* item = (ipc_queue_item_t*)queue->rptr;
|
||||
|
||||
if (queue->wptr - queue->rptr - sizeof(ipc_queue_item_t) <
|
||||
ALIGN_UP(item->size, IPC_DATA_ALIGNMENT)) {
|
||||
// Invalid item size
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ipc_try_receive(ipc_message_t* msg) {
|
||||
if (!ipc_has_message(msg->remote)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ipc_queue_t* queue = ipc_queue(systask_id(systask_active()), msg->remote);
|
||||
ipc_queue_item_t* item = (ipc_queue_item_t*)queue->rptr;
|
||||
|
||||
msg->fn = item->fn;
|
||||
msg->data = item->data;
|
||||
@@ -163,21 +173,21 @@ bool ipc_try_receive(ipc_message_t *msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ipc_message_free(ipc_message_t *msg) {
|
||||
void ipc_message_free(ipc_message_t* msg) {
|
||||
systask_id_t target = systask_id(systask_active());
|
||||
|
||||
ipc_queue_t *queue = ipc_queue(target, msg->remote);
|
||||
ipc_queue_t* queue = ipc_queue(target, msg->remote);
|
||||
|
||||
if (queue == NULL || queue->ptr == NULL) {
|
||||
// Invalid target or no queue registered
|
||||
return;
|
||||
}
|
||||
|
||||
ipc_queue_item_t *item = (ipc_queue_item_t *)queue->ptr;
|
||||
ipc_queue_item_t *new_wptr = item;
|
||||
ipc_queue_item_t* item = (ipc_queue_item_t*)queue->ptr;
|
||||
ipc_queue_item_t* new_wptr = item;
|
||||
|
||||
while (item < (ipc_queue_item_t *)queue->wptr) {
|
||||
size_t remaining_size = (uint8_t *)queue->wptr - (uint8_t *)item;
|
||||
while (item < (ipc_queue_item_t*)queue->wptr) {
|
||||
size_t remaining_size = (uint8_t*)queue->wptr - (uint8_t*)item;
|
||||
|
||||
if (remaining_size < sizeof(ipc_queue_item_t) ||
|
||||
item->size > remaining_size - sizeof(ipc_queue_item_t)) {
|
||||
@@ -195,25 +205,25 @@ void ipc_message_free(ipc_message_t *msg) {
|
||||
// Move to next item
|
||||
size_t item_size =
|
||||
ALIGN_UP(sizeof(ipc_queue_item_t) + item->size, IPC_DATA_ALIGNMENT);
|
||||
item = (ipc_queue_item_t *)((uint8_t *)item + item_size);
|
||||
item = (ipc_queue_item_t*)((uint8_t*)item + item_size);
|
||||
|
||||
if (advance_wptr) {
|
||||
new_wptr = item;
|
||||
}
|
||||
}
|
||||
|
||||
queue->wptr = (uint8_t *)new_wptr;
|
||||
queue->wptr = (uint8_t*)new_wptr;
|
||||
|
||||
if (queue->wptr < queue->rptr) {
|
||||
queue->rptr = queue->wptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ipc_send(systask_id_t remote, uint32_t fn, const void *data,
|
||||
bool ipc_send(systask_id_t remote, uint32_t fn, const void* data,
|
||||
size_t data_size) {
|
||||
systask_id_t origin = systask_id(systask_active());
|
||||
|
||||
ipc_queue_t *queue = ipc_queue(remote, origin);
|
||||
ipc_queue_t* queue = ipc_queue(remote, origin);
|
||||
|
||||
if (queue == NULL || queue->ptr == NULL) {
|
||||
// Invalid target or no queue registered
|
||||
@@ -241,7 +251,7 @@ bool ipc_send(systask_id_t remote, uint32_t fn, const void *data,
|
||||
.size = data_size,
|
||||
};
|
||||
|
||||
ipc_queue_item_t *item = (ipc_queue_item_t *)queue->wptr;
|
||||
ipc_queue_item_t* item = (ipc_queue_item_t*)queue->wptr;
|
||||
ipc_memcpy(item, &item_hdr, sizeof(item_hdr));
|
||||
|
||||
if (data_size > 0) {
|
||||
@@ -253,13 +263,13 @@ bool ipc_send(systask_id_t remote, uint32_t fn, const void *data,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void on_task_created(void *context, systask_id_t task_id) {
|
||||
static void on_task_created(void* context, systask_id_t task_id) {
|
||||
systask_id_t origin = (systask_id_t)(uintptr_t)context;
|
||||
ipc_queue_t *queue = ipc_queue(task_id, origin);
|
||||
ipc_queue_t* queue = ipc_queue(task_id, origin);
|
||||
memset(queue, 0, sizeof(ipc_queue_t));
|
||||
}
|
||||
|
||||
static void on_event_poll(void *context, bool read_awaited,
|
||||
static void on_event_poll(void* context, bool read_awaited,
|
||||
bool write_awaited) {
|
||||
systask_id_t origin = (systask_id_t)(uintptr_t)context;
|
||||
|
||||
@@ -271,13 +281,13 @@ static void on_event_poll(void *context, bool read_awaited,
|
||||
}
|
||||
}
|
||||
|
||||
static bool on_check_read_ready(void *context, systask_id_t task_id,
|
||||
void *param) {
|
||||
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
||||
void* param) {
|
||||
systask_id_t origin = (systask_id_t)(uintptr_t)context;
|
||||
|
||||
UNUSED(param);
|
||||
|
||||
ipc_queue_t *queue = ipc_queue(task_id, origin);
|
||||
ipc_queue_t* queue = ipc_queue(task_id, origin);
|
||||
return (queue != NULL && queue->rptr < queue->wptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,17 @@ STATIC mp_obj_t mod_trezorio_ipc_send(mp_obj_t remote_obj, mp_obj_t fn_obj,
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_ipc_send_obj,
|
||||
mod_trezorio_ipc_send);
|
||||
|
||||
/// def ipc_has_message(remote: int) -> bool:
|
||||
/// """
|
||||
/// Checks if there are pending IPC messages from the specified remote task.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_ipc_has_message(mp_obj_t remote_obj) {
|
||||
systask_id_t remote = (systask_id_t)mp_obj_get_int(remote_obj);
|
||||
return mp_obj_new_bool(ipc_has_message(remote));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_ipc_has_message_obj,
|
||||
mod_trezorio_ipc_has_message);
|
||||
|
||||
/// class IpcMessage(NamedTuple):
|
||||
/// """
|
||||
/// IPC message structure.
|
||||
|
||||
@@ -41,7 +41,7 @@ uint32_t last_touch_sample_time = 0;
|
||||
|
||||
#define CHECK_PARAM_RANGE(value, minimum, maximum) \
|
||||
if (value < minimum || value > maximum) { \
|
||||
const char *msg = (#value " is out of range"); \
|
||||
const char* msg = (#value " is out of range"); \
|
||||
mp_raise_ValueError((mp_rom_error_text_t)msg); \
|
||||
}
|
||||
|
||||
@@ -139,6 +139,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
|
||||
#ifdef USE_IPC
|
||||
{MP_ROM_QSTR(MP_QSTR_IPC2_EVENT), MP_ROM_INT(SYSHANDLE_IPC2)},
|
||||
{MP_ROM_QSTR(MP_QSTR_ipc_send), MP_ROM_PTR(&mod_trezorio_ipc_send_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_ipc_has_message),
|
||||
MP_ROM_PTR(&mod_trezorio_ipc_has_message_obj)},
|
||||
#endif
|
||||
{MP_ROM_QSTR(MP_QSTR_USB), MP_ROM_PTR(&mod_trezorio_USB_type)},
|
||||
{MP_ROM_QSTR(MP_QSTR_USBIF), MP_ROM_PTR(&mod_trezorio_USBIF_type)},
|
||||
@@ -158,7 +160,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_trezorio_globals,
|
||||
|
||||
const mp_obj_module_t mp_module_trezorio = {
|
||||
.base = {&mp_type_module},
|
||||
.globals = (mp_obj_dict_t *)&mp_module_trezorio_globals,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_trezorio_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_trezorio, mp_module_trezorio);
|
||||
|
||||
@@ -9,6 +9,13 @@ def ipc_send(remote: int, fn: int, data: AnyBytes) -> None:
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ipc.h
|
||||
def ipc_has_message(remote: int) -> bool:
|
||||
"""
|
||||
Checks if there are pending IPC messages from the specified remote task.
|
||||
"""
|
||||
|
||||
|
||||
# upymod/modtrezorio/modtrezorio-ipc.h
|
||||
class IpcMessage(NamedTuple):
|
||||
"""
|
||||
|
||||
@@ -40,6 +40,8 @@ class LayoutObj(Generic[T]):
|
||||
if utils.USE_BLE:
|
||||
def ble_event(self, event: int, data: bytes) -> LayoutState | None:
|
||||
"""Receive a BLE events."""
|
||||
def ipc_event(self) -> LayoutState | None:
|
||||
"""Signal an incoming IPC message."""
|
||||
if utils.USE_POWER_MANAGER:
|
||||
def pm_event(self, flags: int) -> LayoutState | None:
|
||||
"""Receive a power management event with packed flags."""
|
||||
|
||||
@@ -430,6 +430,7 @@ class Layout(Generic[T]):
|
||||
yield self._handle_touch_events()
|
||||
if utils.USE_BLE:
|
||||
yield self._handle_ble_events()
|
||||
yield self._handle_ipc_events()
|
||||
if utils.USE_POWER_MANAGER:
|
||||
yield self._handle_power_manager()
|
||||
|
||||
@@ -529,6 +530,15 @@ class Layout(Generic[T]):
|
||||
except Shutdown:
|
||||
return
|
||||
|
||||
async def _handle_ipc_events(self) -> None:
|
||||
try:
|
||||
while True:
|
||||
if io.ipc_has_message(2):
|
||||
self._event(self.layout.ipc_event)
|
||||
await loop.sleep(10)
|
||||
except Shutdown:
|
||||
return
|
||||
|
||||
if utils.USE_POWER_MANAGER:
|
||||
|
||||
def _handle_power_manager(self) -> Generator[Any, int, None]:
|
||||
|
||||
@@ -6,19 +6,19 @@ use alloc::string::ToString;
|
||||
use trezor_app_sdk::{Result, crypto, log, ui, util};
|
||||
|
||||
pub fn get_public_key(msg: EthereumGetPublicKey) -> Result<EthereumPublicKey> {
|
||||
// let long_string: &str = "asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
// asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
// asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
// asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
// asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
// asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789";
|
||||
// log::info!(
|
||||
// "string chars: {}, string bytes: {}",
|
||||
// long_string.chars().count(),
|
||||
// long_string.len()
|
||||
// );
|
||||
let long_string: &str = "asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789\
|
||||
asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM0123456789";
|
||||
log::info!(
|
||||
"string chars: {}, string bytes: {}",
|
||||
long_string.chars().count(),
|
||||
long_string.len()
|
||||
);
|
||||
|
||||
// ui::confirm_long_value("title", long_string)?;
|
||||
ui::confirm_long_value("title", long_string)?;
|
||||
|
||||
// TODO: Implement Ethereum public key retrieval"
|
||||
let mut public_key = EthereumPublicKey::default();
|
||||
|
||||
Reference in New Issue
Block a user