Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

split polling can_read and reading from USB #4419

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

TychoVrahe
Copy link
Contributor

@TychoVrahe TychoVrahe commented Dec 3, 2024

This PR changes the way reading from USB works: the polling mechanism is only used to detect if there is a new message, the reading itself is done separately.

The emulator implementation is modified a bit, since there is a need to do the PING-PONG and it is undesirable to emit a CAN_READ event due to this- therefore the message is read into buffer during polling, and the read from the buffer upon read.

This should enable some optimized usage of the message buffer, but this is not done in this PR.

@TychoVrahe TychoVrahe self-assigned this Dec 3, 2024
Copy link

github-actions bot commented Dec 3, 2024

core UI changes device test click test persistence test
T2T1 Model T test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3B1 Safe 3 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3T1 Safe 5 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
All main(screens)

@TychoVrahe TychoVrahe force-pushed the tychovrahe/refactor/usb_split branch from 86f3140 to e942f8e Compare December 3, 2024 20:32
@prusnak
Copy link
Member

prusnak commented Dec 3, 2024

Tangential: do we still use HID anywhere in Core? Maybe it is time to remove it (in different PR)?

@matejcik
Copy link
Contributor

matejcik commented Dec 4, 2024

Tangential: do we still use HID anywhere in Core? Maybe it is time to remove it (in different PR)?

FIDO runs over HID

@@ -127,10 +127,25 @@ STATIC mp_obj_t mod_trezorio_WebUSB_write(mp_obj_t self, mp_obj_t msg) {
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_WebUSB_write_obj,
mod_trezorio_WebUSB_write);

/// def read(self, buf: bytes) -> int:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want the following signature:

Suggested change
/// def read(self, buf: bytes) -> int:
/// def read(self, buf: bytes, offset: int = 0, limit: int | None = None) -> int:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 34559a4 and 51556ef

Copy link
Member

@prusnak prusnak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpicks

core/mocks/generated/trezorio/__init__.pyi Outdated Show resolved Hide resolved
core/mocks/generated/trezorio/__init__.pyi Outdated Show resolved Hide resolved
core/embed/upymod/modtrezorio/modtrezorio-webusb.h Outdated Show resolved Hide resolved
core/embed/upymod/modtrezorio/modtrezorio-hid.h Outdated Show resolved Hide resolved
@TychoVrahe TychoVrahe marked this pull request as ready for review December 4, 2024 13:29
@TychoVrahe TychoVrahe removed the request for review from andrewkozlik December 4, 2024 13:30
@prusnak prusnak self-requested a review December 4, 2024 13:30
@TychoVrahe TychoVrahe requested review from prusnak and matejcik and removed request for prusnak December 4, 2024 13:51
}

ssize_t r =
usb_hid_read(o->info.iface_num, &((uint8_t *)buf.buf)[offset], limit);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need to check that offset and limit are valid for the buf
(and ideally raise a ValueError they exceed)
dtto webusb

Copy link
Contributor Author

@TychoVrahe TychoVrahe Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solved as part of 7d9a53c, see below

msg_len = await read
report = bytearray(msg_len)
read_len = iface.read(report, 0, msg_len)
if read_len != msg_len:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these checks are kind of annoying... could we get rid of them somehow?
on usb we don't really need to know msg_len because it is fixed, so i'm guessing this is for BT with variable length packets?
perhaps read() should guarantee that it reads full limit (or buffer size) and exception out otherwise?
or, can we guarantee that if we got msg_len out of await read, the next read must return that many bytes? (i mean we could always do the full read into a buffer like we do on unix, i suppose...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about this: 7d9a53c

  • the guarantee that msg_len is equal to real read data is implemented
  • exception if buffer space is insufficient
  • exception if for any reason the underlying USB implementation reads message of different length, but modification of the buffer is allowed under such circumstances
  • limit is removed, assumed that you always read the whole message of the msg_len size. (or do we ever want to allow reading partials, even if it means losing the rest of the data?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🔎 Needs review
Development

Successfully merging this pull request may close these issues.

3 participants