1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-26 16:18:22 +00:00

bunch of api cleanups

This commit is contained in:
Jan Pochyla 2017-09-16 15:00:31 +02:00
parent a7b6ea808a
commit 49cc4651c2
20 changed files with 235 additions and 218 deletions

View File

@ -3,7 +3,8 @@ from trezor.utils import unimport
# used to confirm/cancel the dialogs from outside of this module (i.e.
# through debug link)
signal = loop.Signal()
if __debug__:
signal = loop.signal()
@unimport
@ -20,7 +21,12 @@ async def confirm(ctx, content, code=None, *args, **kwargs):
if code is None:
code = Other
await ctx.call(ButtonRequest(code=code), ButtonAck)
return await loop.Wait((signal, dialog)) == CONFIRMED
if __debug__:
waiter = loop.wait(signal, dialog)
else:
waiter = dialog
return await waiter == CONFIRMED
@unimport
@ -37,7 +43,12 @@ async def hold_to_confirm(ctx, content, code=None, *args, **kwargs):
if code is None:
code = Other
await ctx.call(ButtonRequest(code=code), ButtonAck)
return await loop.Wait((signal, dialog)) == CONFIRMED
if __debug__:
waiter = loop.wait(signal, dialog)
else:
waiter = dialog
return await waiter == CONFIRMED
@unimport

View File

@ -1,4 +1,5 @@
from micropython import const
import ustruct
import utime

View File

@ -312,7 +312,7 @@ def send_cmd(cmd: Cmd, iface: io.HID) -> None:
def boot(iface: io.HID):
loop.schedule_task(handle_reports(iface))
loop.schedule(handle_reports(iface))
async def handle_reports(iface: io.HID):
@ -446,7 +446,7 @@ class ConfirmState:
self.deadline_ms = utime.ticks_ms() + _CONFIRM_STATE_TIMEOUT_MS
self.task = self.confirm()
workflow.onstart(self.task)
loop.schedule_task(self.task)
loop.schedule(self.task)
def kill(self) -> None:
if self.task is not None:

View File

@ -10,10 +10,10 @@ async def swipe_to_rotate():
async def dim_screen():
await loop.Sleep(5 * 1000000)
await loop.sleep(5 * 1000000)
await ui.backlight_slide(ui.BACKLIGHT_DIM)
while True:
await loop.Sleep(1000000)
await loop.sleep(1000000)
def display_homescreen():
@ -35,4 +35,4 @@ def display_homescreen():
async def layout_homescreen():
while True:
display_homescreen()
await loop.Wait([swipe_to_rotate(), dim_screen()])
await loop.wait(swipe_to_rotate(), dim_screen())

View File

@ -1,5 +1,3 @@
from micropython import const
from trezor import config
from trezor import io
from trezor import log

View File

@ -5,20 +5,20 @@ bytes, string, embedded message and repeated fields.
For de-sererializing (loading) protobuf types, object with `AsyncReader`
interface is required:
class AsyncReader:
async def areadinto(self, buffer):
"""
Reads `len(buffer)` bytes into `buffer`, or raises `EOFError`.
"""
>>> class AsyncReader:
>>> async def areadinto(self, buffer):
>>> """
>>> Reads `len(buffer)` bytes into `buffer`, or raises `EOFError`.
>>> """
For serializing (dumping) protobuf types, object with `AsyncWriter` interface is
required:
class AsyncWriter:
async def awrite(self, buffer):
"""
Writes all bytes from `buffer`, or raises `EOFError`.
"""
>>> class AsyncWriter:
>>> async def awrite(self, buffer):
>>> """
>>> Writes all bytes from `buffer`, or raises `EOFError`.
>>> """
'''
from micropython import const

View File

@ -2,14 +2,15 @@
class Hmac:
def __init__(self, key, msg, digestmod):
self.__digestmod = digestmod
self.__inner = digestmod()
self.digest_size = self.__inner.digest_size
self.block_size = self.__inner.block_size
self.digestmod = digestmod
self.inner = digestmod()
self.digest_size = self.inner.digest_size
self.block_size = self.inner.block_size
if len(key) > self.block_size:
key = digestmod(key).digest()
self.__key = key + bytes(self.block_size - len(key))
self.__inner.update(bytes((x ^ 0x36) for x in self.__key))
self.key = key + bytes(self.block_size - len(key))
self.inner.update(bytes((x ^ 0x36) for x in self.key))
if msg is not None:
self.update(msg)
@ -17,15 +18,15 @@ class Hmac:
'''
Update the context with data.
'''
self.__inner.update(msg)
self.inner.update(msg)
def digest(self) -> bytes:
'''
Returns the digest of processed data.
'''
outer = self.__digestmod()
outer.update(bytes((x ^ 0x5C) for x in self.__key))
outer.update(self.__inner.digest())
outer = self.digestmod()
outer.update(bytes((x ^ 0x5C) for x in self.key))
outer.update(self.inner.digest())
return outer.digest()

View File

@ -4,8 +4,7 @@ the form of python coroutines (either plain generators or `async` functions) are
stepped through until completion, and can get asynchronously blocked by
`yield`ing or `await`ing a syscall.
See `schedule_task`, `run`, and syscalls `Sleep`, `Select`, `Signal`
and `Wait`.
See `schedule`, `run`, and syscalls `sleep`, `select`, `signal` and `wait`.
'''
import utime
@ -14,21 +13,11 @@ from micropython import const
from trezor import log
from trezor import io
TOUCH = io.TOUCH
TOUCH_START = io.TOUCH_START
TOUCH_MOVE = io.TOUCH_MOVE
TOUCH_END = io.TOUCH_END
READ = io.POLL_READ
WRITE = io.POLL_WRITE
after_step_hook = None # function, called after each task step
_MAX_SELECT_DELAY = const(1000000) # usec delay if queue is empty
_MAX_QUEUE_SIZE = const(64) # maximum number of scheduled tasks
_paused_tasks = {} # {message interface: [task]}
_scheduled_tasks = utimeq.utimeq(_MAX_QUEUE_SIZE)
_QUEUE_SIZE = const(64) # maximum number of scheduled tasks
_queue = utimeq.utimeq(_QUEUE_SIZE)
_paused = {}
if __debug__:
# for performance stats
@ -38,47 +27,48 @@ if __debug__:
log_delay_rb = array.array('i', [0] * log_delay_rb_len)
def schedule_task(task, value=None, deadline=None):
def schedule(task, value=None, deadline=None):
'''
Schedule task to be executed with `value` on given `deadline` (in
microseconds). Does not start the event loop itself, see `run`.
'''
if deadline is None:
deadline = utime.ticks_us()
_scheduled_tasks.push(deadline, task, value)
_queue.push(deadline, task, value)
def unschedule_task(task):
def unschedule(task):
'''
Remove task from the time queue. Cancels previous `schedule_task`.
Remove task from the time queue. Cancels previous `schedule`.
'''
global _scheduled_tasks
global _queue
task_entry = [0, 0, 0] # deadline, task, value
queue_copy = utimeq.utimeq(_MAX_QUEUE_SIZE)
while _scheduled_tasks:
_scheduled_tasks.pop(task_entry)
if task_entry[1] is not task:
queue_copy.push(task_entry[0], task_entry[1], task_entry[2])
_scheduled_tasks = queue_copy
queue_copy = utimeq.utimeq(_QUEUE_SIZE)
while _queue:
_queue.pop(task_entry)
t, v, d = task_entry
if t is not task:
queue_copy.push(t, v, d)
_queue = queue_copy
def _pause_task(task, iface):
tasks = _paused_tasks.get(iface, None)
def pause(task, iface):
tasks = _paused.get(iface, None)
if tasks is None:
tasks = _paused_tasks[iface] = []
tasks = _paused[iface] = []
tasks.append(task)
def _unpause_task(task):
for iface in _paused_tasks:
if task in _paused_tasks[iface]:
_paused_tasks[iface].remove(task)
def unpause(task):
for iface in _paused:
if task in _paused[iface]:
_paused[iface].remove(task)
def run():
'''
Loop forever, stepping through scheduled tasks and awaiting I/O events
inbetween. Use `schedule_task` first to add a coroutine to the task queue.
inbetween. Use `schedule` first to add a coroutine to the task queue.
Tasks yield back to the scheduler on any I/O, usually by calling `await` on
a `Syscall`.
'''
@ -86,34 +76,35 @@ def run():
if __debug__:
global log_delay_pos
max_delay = const(1000000) # usec delay if queue is empty
task_entry = [0, 0, 0] # deadline, task, value
msg_entry = [0, 0] # iface | flags, value
while True:
# compute the maximum amount of time we can wait for a message
if _scheduled_tasks:
delay = utime.ticks_diff(
_scheduled_tasks.peektime(), utime.ticks_us())
if _queue:
delay = utime.ticks_diff(_queue.peektime(), utime.ticks_us())
else:
delay = _MAX_SELECT_DELAY
delay = max_delay
if __debug__:
# add current delay to ring buffer for performance stats
log_delay_rb[log_delay_pos] = delay
log_delay_pos = (log_delay_pos + 1) % log_delay_rb_len
if io.poll(_paused_tasks, msg_entry, delay):
if io.poll(_paused, msg_entry, delay):
# message received, run tasks paused on the interface
msg_tasks = _paused_tasks.pop(msg_entry[0], ())
msg_tasks = _paused.pop(msg_entry[0], ())
for task in msg_tasks:
_step_task(task, msg_entry[1])
_step(task, msg_entry[1])
else:
# timeout occurred, run the first scheduled task
if _scheduled_tasks:
_scheduled_tasks.pop(task_entry)
_step_task(task_entry[1], task_entry[2])
if _queue:
_queue.pop(task_entry)
_step(task_entry[1], task_entry[2])
def _step_task(task, value):
def _step(task, value):
try:
if isinstance(value, Exception):
result = task.throw(value)
@ -129,7 +120,7 @@ def _step_task(task, value):
if isinstance(result, Syscall):
result.handle(task)
elif result is None:
schedule_task(task)
schedule(task)
else:
if __debug__:
log.error(__name__, 'unknown syscall: %s', result)
@ -148,15 +139,16 @@ class Syscall:
return (yield self)
class Sleep(Syscall):
class sleep(Syscall):
'''
Pause current task and resume it after given delay. Although the delay is
given in microseconds, sub-millisecond precision is not guaranteed. Result
value is the calculated deadline.
Example:
planned = await loop.Sleep(1000 * 1000) # sleep for 1ms
print('missed by %d us', utime.ticks_diff(utime.ticks_us(), planned))
>>> planned = await loop.sleep(1000 * 1000) # sleep for 1ms
>>> print('missed by %d us', utime.ticks_diff(utime.ticks_us(), planned))
'''
def __init__(self, delay_us):
@ -164,43 +156,45 @@ class Sleep(Syscall):
def handle(self, task):
deadline = utime.ticks_add(utime.ticks_us(), self.delay_us)
schedule_task(task, deadline, deadline)
schedule(task, deadline, deadline)
class Select(Syscall):
class select(Syscall):
'''
Pause current task, and resume only after a message on `msg_iface` is
received. Messages are received either from an USB interface, or the
touch display. Result value a tuple of message values.
Example:
hid_report, = await loop.Select(0xABCD) # await USB HID report
event, x, y = await loop.Select(loop.TOUCH) # await touch event
>>> hid_report, = await loop.select(0xABCD) # await USB HID report
>>> event, x, y = await loop.select(io.TOUCH) # await touch event
'''
def __init__(self, msg_iface):
self.msg_iface = msg_iface
def handle(self, task):
_pause_task(task, self.msg_iface)
pause(task, self.msg_iface)
_NO_VALUE = ()
class Signal(Syscall):
class signal(Syscall):
'''
Pause current task, and let other running task to resume it later with a
result value or an exception.
Example:
# in task #1:
signal = loop.Signal()
result = await signal
print('awaited result:', result)
# in task #2:
signal.send('hello from task #2')
# prints in the next iteration of the event loop
>>> # in task #1:
>>> signal = loop.signal()
>>> result = await signal
>>> print('awaited result:', result)
>>> # in task #2:
>>> signal.send('hello from task #2')
>>> # prints in the next iteration of the event loop
'''
def __init__(self):
@ -217,36 +211,37 @@ class Signal(Syscall):
def _deliver(self):
if self.task is not None and self.value is not _NO_VALUE:
schedule_task(self.task, self.value)
schedule(self.task, self.value)
self.task = None
self.value = _NO_VALUE
class Wait(Syscall):
class wait(Syscall):
'''
Execute one or more children tasks and wait until one or more of them exit.
Return value of `Wait` is the return value of task that triggered the
completion. By default, `Wait` returns after the first child completes, and
Return value of `wait` is the return value of task that triggered the
completion. By default, `wait` returns after the first child completes, and
other running children are killed (by cancelling any pending schedules and
calling `close()`).
Example:
# async def wait_for_touch(): ...
# async def animate_logo(): ...
touch_task = wait_for_touch()
animation_task = animate_logo()
waiter = loop.Wait((touch_task, animation_task))
result = await waiter
if animation_task in waiter.finished:
print('animation task returned', result)
else:
print('touch task returned', result)
Note: You should not directly `yield` a `Wait` instance, see logic in
`Wait.__iter__` for explanation. Always use `await`.
>>> # async def wait_for_touch(): ...
>>> # async def animate_logo(): ...
>>> touch_task = wait_for_touch()
>>> animation_task = animate_logo()
>>> waiter = loop.wait(touch_task, animation_task)
>>> result = await waiter
>>> if animation_task in waiter.finished:
>>> print('animation task returned', result)
>>> else:
>>> print('touch task returned', result)
Note: You should not directly `yield` a `wait` instance, see logic in
`wait.__iter__` for explanation. Always use `await`.
'''
def __init__(self, children, wait_for=1, exit_others=True):
def __init__(self, *children, wait_for=1, exit_others=True):
self.children = children
self.wait_for = wait_for
self.exit_others = exit_others
@ -259,13 +254,13 @@ class Wait(Syscall):
self.finished = []
self.scheduled = [self._wait(c) for c in self.children]
for ct in self.scheduled:
schedule_task(ct)
schedule(ct)
def exit(self):
for task in self.scheduled:
if task not in self.finished:
_unpause_task(task)
unschedule_task(task)
unpause(task)
unschedule(task)
task.close()
async def _wait(self, child):
@ -281,7 +276,7 @@ class Wait(Syscall):
if self.wait_for == len(self.finished) or isinstance(result, Exception):
if self.exit_others:
self.exit()
schedule_task(self.callback, result)
schedule(self.callback, result)
def __iter__(self):
try:
@ -293,10 +288,10 @@ class Wait(Syscall):
raise
class Put(Syscall):
class put(Syscall):
def __init__(self, chan, value=None):
self.chan = chan
def __init__(self, ch, value=None):
self.ch = ch
self.value = value
def __call__(self, value):
@ -304,30 +299,30 @@ class Put(Syscall):
return self
def handle(self, task):
self.chan.schedule_put(schedule_task, task, self.value)
self.ch.schedule_put(schedule, task, self.value)
class Take(Syscall):
class take(Syscall):
def __init__(self, chan):
self.chan = chan
def __init__(self, ch):
self.ch = ch
def __call__(self):
return self
def handle(self, task):
if self.chan.schedule_take(schedule_task, task) and self.chan.id is not None:
_pause_task(self.chan, self.chan.id)
if self.ch.schedule_take(schedule, task) and self.ch.id is not None:
pause(self.ch, self.ch.id)
class Chan:
class chan:
def __init__(self, id=None):
self.id = id
self.putters = []
self.takers = []
self.put = Put(self)
self.take = Take(self)
self.put = put(self)
self.take = take(self)
def schedule_publish(self, schedule, value):
if self.takers:
@ -357,9 +352,3 @@ class Chan:
else:
self.takers.append(taker)
return False
select = Select
sleep = Sleep
wait = Wait
signal = Signal

View File

@ -5,11 +5,14 @@ import math
import utime
from trezorui import Display
from trezor import loop, res
from trezor import io
from trezor import loop
from trezor import res
display = Display()
if sys.platform not in ('trezor', 'pyboard'): # stmhal
if sys.platform != 'trezor':
loop.after_step_hook = display.refresh
@ -72,7 +75,7 @@ ICON_WIPE = 'trezor/res/header_icons/wipe.toig'
ICON_RECOVERY = 'trezor/res/header_icons/recovery.toig'
def in_area(pos: tuple, area: tuple) -> bool:
def contains(pos: tuple, area: tuple) -> bool:
x, y = pos
ax, ay, aw, ah = area
return ax <= x <= ax + aw and ay <= y <= ay + ah
@ -88,42 +91,35 @@ def blend(ca: int, cb: int, t: float) -> int:
lerpi((ca << 3) & 0xF8, (cb << 3) & 0xF8, t))
def pulse(delay):
while True:
# normalize sin from interval -1:1 to 0:1
yield 0.5 + 0.5 * math.sin(utime.ticks_us() / delay)
async def alert(count=3):
short_sleep = loop.sleep(20000)
long_sleep = loop.sleep(80000)
current = display.backlight()
for i in range(count * 2):
if i % 2 == 0:
display.backlight(BACKLIGHT_MAX)
yield loop.Sleep(20000)
yield short_sleep
else:
display.backlight(BACKLIGHT_NORMAL)
yield loop.Sleep(80000)
yield long_sleep
display.backlight(current)
async def backlight_slide(val, speed=20000):
async def backlight_slide(val, delay=20000):
sleep = loop.sleep(delay)
current = display.backlight()
for i in range(current, val, -1 if current > val else 1):
display.backlight(i)
await loop.Sleep(speed)
await sleep
def animate_pulse(func, ca, cb, speed=200000, delay=30000):
while True:
# normalize sin from interval -1:1 to 0:1
y = 0.5 + 0.5 * math.sin(utime.ticks_us() / speed)
c = blend(ca, cb, y)
func(c)
yield loop.Sleep(delay)
def header(title, icon=ICON_RESET, fg=BLACK, bg=BLACK):
display.bar(0, 0, 240, 32, bg)
if icon is not None:
display.icon(8, 4, res.load(icon), fg, bg)
display.text(8 + 24 + 2, 24, title, BOLD, fg, bg)
def rotate_coords(pos: tuple) -> tuple:
def rotate(pos: tuple) -> tuple:
r = display.orientation()
if r == 0:
return pos
@ -136,6 +132,13 @@ def rotate_coords(pos: tuple) -> tuple:
return (240 - y, x)
def header(title, icon=ICON_RESET, fg=BLACK, bg=BLACK):
display.bar(0, 0, 240, 32, bg)
if icon is not None:
display.icon(8, 4, res.load(icon), fg, bg)
display.text(8 + 24 + 2, 24, title, BOLD, fg, bg)
class Widget:
def render(self):
@ -145,9 +148,10 @@ class Widget:
pass
def __iter__(self):
touch = loop.select(io.TOUCH)
while True:
self.render()
event, *pos = yield loop.Select(loop.TOUCH)
event, *pos = yield touch
result = self.touch(event, pos)
if result is not None:
return result

View File

@ -1,6 +1,12 @@
from micropython import const
from trezor import ui, loop
from . import display, in_area, rotate_coords, Widget
from trezor import io
from trezor import ui
from trezor.ui import display
from trezor.ui import contains
from trezor.ui import rotate
from trezor.ui import Widget
DEFAULT_BUTTON = {
@ -142,18 +148,18 @@ class Button(Widget):
if self.state & BTN_DISABLED:
return
if not self.absolute:
pos = rotate_coords(pos)
if event == loop.TOUCH_START:
if in_area(pos, self.area):
pos = rotate(pos)
if event == io.TOUCH_START:
if contains(pos, self.area):
self.state = BTN_STARTED | BTN_DIRTY | BTN_ACTIVE
elif event == loop.TOUCH_MOVE and self.state & BTN_STARTED:
if in_area(pos, self.area):
elif event == io.TOUCH_MOVE and self.state & BTN_STARTED:
if contains(pos, self.area):
if not self.state & BTN_ACTIVE:
self.state = BTN_STARTED | BTN_DIRTY | BTN_ACTIVE
else:
if self.state & BTN_ACTIVE:
self.state = BTN_STARTED | BTN_DIRTY
elif event == loop.TOUCH_END and self.state & BTN_STARTED:
elif event == io.TOUCH_END and self.state & BTN_STARTED:
self.state = BTN_DIRTY
if in_area(pos, self.area):
if contains(pos, self.area):
return BTN_CLICKED

View File

@ -41,7 +41,7 @@ class ConfirmDialog(Widget):
return CANCELLED
async def __iter__(self):
return await loop.Wait((super().__iter__(), self.content))
return await loop.wait(super().__iter__(), self.content)
_STARTED = const(-1)
@ -82,5 +82,5 @@ class HoldToConfirmDialog(Widget):
else:
content_loop = self.content
confirm_loop = super().__iter__() # default loop (render on touch)
result = await loop.wait((content_loop, confirm_loop))
result = await loop.wait(content_loop, confirm_loop)
return result

View File

@ -1,4 +1,4 @@
from trezor import ui, res, loop
from trezor import ui, res, loop, io
from trezor.crypto import bip39
from trezor.ui import display
from trezor.ui.button import Button, BTN_CLICKED, CLEAR_BUTTON, CLEAR_BUTTON_ACTIVE
@ -136,9 +136,9 @@ class KeyboardMultiTap(ui.Widget):
btn.disable()
def __iter__(self):
timeout = loop.Sleep(1000 * 1000 * 1)
touch = loop.Select(loop.TOUCH)
wait = loop.Wait((touch, timeout))
timeout = loop.sleep(1000 * 1000 * 1)
touch = loop.select(io.TOUCH)
wait = loop.wait(touch, timeout)
while True:
self.render()
result = yield wait
@ -223,9 +223,9 @@ class KeyboardZooming(ui.Widget):
break
def __iter__(self):
timeout = loop.Sleep(1000 * 1000 * 1)
touch = loop.Select(loop.TOUCH)
wait = loop.Wait((touch, timeout))
timeout = loop.sleep(1000 * 1000 * 1)
touch = loop.select(io.TOUCH)
wait = loop.wait(touch, timeout)
while True:
self.render()
result = yield wait

View File

@ -16,7 +16,7 @@ async def paginate(render_page, page_count, page=0, *args):
while True:
changer = change_page(page, page_count)
renderer = render_page(page, page_count, *args)
waiter = loop.Wait([changer, renderer])
waiter = loop.wait(changer, renderer)
result = await waiter
if changer in waiter.finished:
page = result
@ -25,25 +25,28 @@ async def paginate(render_page, page_count, page=0, *args):
async def animate_swipe():
await ui.animate_pulse(render_swipe_icon, ui.GREY, ui.DARK_GREY, speed=300000, delay=200000)
time_delay = const(30000)
draw_delay = const(200000)
def render_swipe_icon(fg):
ui.display.bar_radius(102, 214, 36, 4, fg, ui.BLACK, 2)
ui.display.bar_radius(106, 222, 28, 4, fg, ui.BLACK, 2)
ui.display.bar_radius(110, 230, 20, 4, fg, ui.BLACK, 2)
sleep = loop.sleep(time_delay)
for t in ui.pulse(draw_delay):
fg = ui.blend(ui.GREY, ui.DARK_GREY, t)
ui.display.bar_radius(102, 214, 36, 4, fg, ui.BLACK, 2)
ui.display.bar_radius(106, 222, 28, 4, fg, ui.BLACK, 2)
ui.display.bar_radius(110, 230, 20, 4, fg, ui.BLACK, 2)
await sleep
def render_scrollbar(page, page_count):
screen_height = const(220)
bbox = const(220)
size = const(10)
padding = 18
if page_count * padding > screen_height:
padding = screen_height // page_count
if page_count * padding > bbox:
padding = bbox // page_count
x = const(225)
y = (screen_height // 2) - (page_count // 2) * padding
y = (bbox // 2) - (page_count // 2) * padding
for i in range(0, page_count):
if i != page:

View File

@ -1,7 +1,7 @@
import utime
from micropython import const
from trezor import loop, ui
from . import in_area, rotate_coords
from trezor import io, ui
from . import contains, rotate
_SWIPE_DISTANCE_THRESHOLD = const(20) # Min pixels in the primary direction
_SWIPE_VELOCITY_THRESHOLD = const(200) # Min pixels per second
@ -26,12 +26,12 @@ class Swipe(ui.Widget):
def touch(self, event, pos):
if not self.absolute:
pos = rotate_coords(pos)
pos = rotate(pos)
temp_time = utime.ticks_ms() / 1000
# primary now for fading purposes
if event == loop.TOUCH_MOVE and self.start_pos is not None:
if event == io.TOUCH_MOVE and self.start_pos is not None:
pdx = pos[0] - self.start_pos[0]
pdy = pos[1] - self.start_pos[1]
td = temp_time - self.start_time
@ -52,13 +52,13 @@ class Swipe(ui.Widget):
else:
ui.display.backlight(self.light_target)
elif event == loop.TOUCH_START and in_area(pos, self.area):
elif event == io.TOUCH_START and contains(pos, self.area):
self.start_time = temp_time
self.start_pos = pos
self.light_origin = ui.BACKLIGHT_NORMAL
ui.display.backlight(self.light_origin)
elif event == loop.TOUCH_END and self.start_pos is not None:
elif event == io.TOUCH_END and self.start_pos is not None:
td = temp_time - self.start_time
pdx = pos[0] - self.start_pos[0]
pdy = pos[1] - self.start_pos[1]

View File

@ -22,7 +22,7 @@ def setup(iface):
'''Initialize the wire stack on passed USB interface.'''
session_supervisor = codec_v2.SesssionSupervisor(iface, session_handler)
session_supervisor.open(codec_v1.SESSION_ID)
loop.schedule_task(session_supervisor.listen())
loop.schedule(session_supervisor.listen())
class Context:

View File

@ -1,6 +1,7 @@
from micropython import const
import ustruct
from trezor import io
from trezor import loop
from trezor import utils
@ -37,7 +38,7 @@ class Reader:
on this session. `self.type` and `self.size` are initialized and
available after `aopen()` returns.
'''
read = loop.select(self.iface.iface_num() | loop.READ)
read = loop.select(self.iface.iface_num() | io.POLL_READ)
while True:
# wait for initial report
report = await read
@ -63,7 +64,7 @@ class Reader:
if self.size < len(buf):
raise EOFError
read = loop.select(self.iface.iface_num() | loop.READ)
read = loop.select(self.iface.iface_num() | io.POLL_READ)
nread = 0
while nread < len(buf):
if self.ofs == len(self.data):
@ -122,7 +123,7 @@ class Writer:
if self.size < len(buf):
raise EOFError
write = loop.select(self.iface.iface_num() | loop.WRITE)
write = loop.select(self.iface.iface_num() | io.POLL_WRITE)
nwritten = 0
while nwritten < len(buf):
# copy as much as possible to report buffer
@ -148,5 +149,5 @@ class Writer:
self.data[self.ofs] = 0x00
self.ofs += 1
await loop.select(self.iface.iface_num() | loop.WRITE)
await loop.select(self.iface.iface_num() | io.POLL_WRITE)
self.iface.write(self.data)

View File

@ -1,6 +1,7 @@
from micropython import const
import ustruct
from trezor import io
from trezor import loop
from trezor import utils
from trezor.crypto import random
@ -59,7 +60,7 @@ class Reader:
on this session. `self.type` and `self.size` are initialized and
available after `aopen()` returns.
'''
read = loop.select(self.iface.iface_num() | loop.READ)
read = loop.select(self.iface.iface_num() | io.POLL_READ)
while True:
# wait for initial report
report = await read
@ -83,7 +84,7 @@ class Reader:
if self.size < len(buf):
raise EOFError
read = loop.select(self.iface.iface_num() | loop.READ)
read = loop.select(self.iface.iface_num() | io.POLL_READ)
nread = 0
while nread < len(buf):
if self.ofs == len(self.data):
@ -148,7 +149,7 @@ class Writer:
if self.size < len(buf):
raise EOFError
write = loop.select(self.iface.iface_num() | loop.WRITE)
write = loop.select(self.iface.iface_num() | io.POLL_WRITE)
nwritten = 0
while nwritten < len(buf):
# copy as much as possible to report buffer
@ -177,7 +178,7 @@ class Writer:
self.data[self.ofs] = 0x00
self.ofs += 1
await loop.select(self.iface.iface_num() | loop.WRITE)
await loop.select(self.iface.iface_num() | io.POLL_WRITE)
self.iface.write(self.data)
@ -197,8 +198,8 @@ class SesssionSupervisor:
After close request, the handling task is closed and session terminated.
Both requests receive responses confirming the operation.
'''
read = loop.select(self.iface.iface_num() | loop.READ)
write = loop.select(self.iface.iface_num() | loop.WRITE)
read = loop.select(self.iface.iface_num() | io.POLL_READ)
write = loop.select(self.iface.iface_num() | io.POLL_WRITE)
while True:
report = await read
repmarker, repsid = ustruct.unpack(_REP, report)
@ -221,7 +222,7 @@ class SesssionSupervisor:
def open(self, sid):
if sid not in self.handling_tasks:
task = self.handling_tasks[sid] = self.handler(self.iface, sid)
loop.schedule_task(task)
loop.schedule(task)
def close(self, sid):
if sid in self.handling_tasks:

View File

@ -38,6 +38,6 @@ def startdefault(handler):
if not default:
default_handler = handler
default = handler()
loop.schedule_task(default)
loop.schedule(default)
ui.display.backlight(ui.BACKLIGHT_NORMAL)
log.debug(__name__, 'startdefault')

View File

@ -6,7 +6,8 @@ from utest import *
from ustruct import pack, unpack
from ubinascii import hexlify, unhexlify
from trezor.loop import Select, Syscall, READ, WRITE
from trezor import io
from trezor.loop import select, Syscall
from trezor.crypto import random
from trezor.utils import chunks
from trezor.wire import codec_v1
@ -39,7 +40,7 @@ def test_reader():
# open, expected one read
first_report = report_header + message[:rep_len - len(report_header)]
assert_async(reader.aopen(), [(None, Select(READ | interface_num)), (first_report, StopIteration()),])
assert_async(reader.aopen(), [(None, select(io.POLL_READ | interface_num)), (first_report, StopIteration()),])
assert_eq(reader.type, message_type)
assert_eq(reader.size, message_len)
@ -66,7 +67,7 @@ def test_reader():
next_report_header = bytearray(unhexlify('3f'))
next_report = next_report_header + message[rep_len - len(report_header):][:rep_len - len(next_report_header)]
onebyte_buffer = bytearray(1)
assert_async(reader.areadinto(onebyte_buffer), [(None, Select(READ | interface_num)), (next_report, StopIteration()),])
assert_async(reader.areadinto(onebyte_buffer), [(None, select(io.POLL_READ | interface_num)), (next_report, StopIteration()),])
assert_eq(onebyte_buffer, message[len(short_buffer):][len(aligned_buffer):][:len(onebyte_buffer)])
assert_eq(reader.size, message_len - len(short_buffer) - len(aligned_buffer) - len(onebyte_buffer))
@ -85,7 +86,7 @@ def test_reader():
expected_syscalls = []
for i, _ in enumerate(next_reports):
prev_report = next_reports[i - 1] if i > 0 else None
expected_syscalls.append((prev_report, Select(READ | interface_num)))
expected_syscalls.append((prev_report, select(io.POLL_READ | interface_num)))
expected_syscalls.append((next_reports[-1], StopIteration()))
assert_async(reader.areadinto(long_buffer), expected_syscalls)
assert_eq(long_buffer, message[-start_size:])
@ -128,7 +129,7 @@ def test_writer():
# aligned write, expected one report
start_size = writer.size
aligned_payload = bytearray(range(rep_len - len(report_header) - len(short_payload)))
assert_async(writer.awrite(aligned_payload), [(None, Select(WRITE | interface_num)), (None, StopIteration()),])
assert_async(writer.awrite(aligned_payload), [(None, select(io.POLL_WRITE | interface_num)), (None, StopIteration()),])
assert_eq(interface.data, [report_header
+ short_payload
+ aligned_payload
@ -154,7 +155,7 @@ def test_writer():
expected_reports[-1] += bytearray(bytes(1) * (rep_len - len(expected_reports[-1])))
# test write
expected_write_reports = expected_reports[:-1]
assert_async(writer.awrite(long_payload), len(expected_write_reports) * [(None, Select(WRITE | interface_num))] + [(None, StopIteration())])
assert_async(writer.awrite(long_payload), len(expected_write_reports) * [(None, select(io.POLL_WRITE | interface_num))] + [(None, StopIteration())])
assert_eq(interface.data, expected_write_reports)
assert_eq(writer.size, start_size - len(long_payload))
interface.data.clear()
@ -163,7 +164,7 @@ def test_writer():
assert_eq(interface.data, [])
# test close
expected_close_reports = expected_reports[-1:]
assert_async(writer.aclose(), len(expected_close_reports) * [(None, Select(WRITE | interface_num))] + [(None, StopIteration())])
assert_async(writer.aclose(), len(expected_close_reports) * [(None, select(io.POLL_WRITE | interface_num))] + [(None, StopIteration())])
assert_eq(interface.data, expected_close_reports)
assert_eq(writer.size, 0)

View File

@ -6,7 +6,8 @@ from utest import *
from ustruct import pack, unpack
from ubinascii import hexlify, unhexlify
from trezor.loop import Select, Syscall, READ, WRITE
from trezor import io
from trezor.loop import select, Syscall
from trezor.utils import chunks
from trezor.wire import codec_v2
@ -39,7 +40,7 @@ def test_reader():
# open, expected one read
first_report = report_header + message[:rep_len - len(report_header)]
assert_async(reader.aopen(), [(None, Select(READ | interface_num)), (first_report, StopIteration()),])
assert_async(reader.aopen(), [(None, select(io.POLL_READ | interface_num)), (first_report, StopIteration()),])
assert_eq(reader.type, message_type)
assert_eq(reader.size, message_len)
@ -66,7 +67,7 @@ def test_reader():
next_report_header = bytearray(unhexlify('021234567800000000'))
next_report = next_report_header + message[rep_len - len(report_header):][:rep_len - len(next_report_header)]
onebyte_buffer = bytearray(1)
assert_async(reader.areadinto(onebyte_buffer), [(None, Select(READ | interface_num)), (next_report, StopIteration()),])
assert_async(reader.areadinto(onebyte_buffer), [(None, select(io.POLL_READ | interface_num)), (next_report, StopIteration()),])
assert_eq(onebyte_buffer, message[len(short_buffer):][len(aligned_buffer):][:len(onebyte_buffer)])
assert_eq(reader.size, message_len - len(short_buffer) - len(aligned_buffer) - len(onebyte_buffer))
@ -85,7 +86,7 @@ def test_reader():
expected_syscalls = []
for i, _ in enumerate(next_reports):
prev_report = next_reports[i - 1] if i > 0 else None
expected_syscalls.append((prev_report, Select(READ | interface_num)))
expected_syscalls.append((prev_report, select(io.POLL_READ | interface_num)))
expected_syscalls.append((next_reports[-1], StopIteration()))
assert_async(reader.areadinto(long_buffer), expected_syscalls)
assert_eq(long_buffer, message[-start_size:])
@ -129,7 +130,7 @@ def test_writer():
# aligned write, expected one report
start_size = writer.size
aligned_payload = bytearray(range(rep_len - len(report_header) - len(short_payload)))
assert_async(writer.awrite(aligned_payload), [(None, Select(WRITE | interface_num)), (None, StopIteration()),])
assert_async(writer.awrite(aligned_payload), [(None, select(io.POLL_WRITE | interface_num)), (None, StopIteration()),])
assert_eq(interface.data, [report_header
+ short_payload
+ aligned_payload
@ -157,7 +158,7 @@ def test_writer():
expected_reports[-1] += bytearray(bytes(1) * (rep_len - len(expected_reports[-1])))
# test write
expected_write_reports = expected_reports[:-1]
assert_async(writer.awrite(long_payload), len(expected_write_reports) * [(None, Select(WRITE | interface_num))] + [(None, StopIteration())])
assert_async(writer.awrite(long_payload), len(expected_write_reports) * [(None, select(io.POLL_WRITE | interface_num))] + [(None, StopIteration())])
assert_eq(interface.data, expected_write_reports)
assert_eq(writer.size, start_size - len(long_payload))
interface.data.clear()
@ -166,7 +167,7 @@ def test_writer():
assert_eq(interface.data, [])
# test close
expected_close_reports = expected_reports[-1:]
assert_async(writer.aclose(), len(expected_close_reports) * [(None, Select(WRITE | interface_num))] + [(None, StopIteration())])
assert_async(writer.aclose(), len(expected_close_reports) * [(None, select(io.POLL_WRITE | interface_num))] + [(None, StopIteration())])
assert_eq(interface.data, expected_close_reports)
assert_eq(writer.size, 0)
interface.data.clear()