Skip to content

Conversation

@NickeZ
Copy link
Collaborator

@NickeZ NickeZ commented Nov 17, 2025

This PR ports the main loop to rust. To keep it simple it tries to stick as much as possible to the c implementation. Rustification will happen later.

  • test U2F

@NickeZ NickeZ force-pushed the maint/rust-main-loop branch 10 times, most recently from ec75283 to 1d4efaa Compare November 18, 2025 15:03
@NickeZ NickeZ marked this pull request as ready for review November 18, 2025 16:03
@NickeZ NickeZ requested a review from benma November 18, 2025 16:03
@NickeZ NickeZ force-pushed the maint/rust-main-loop branch from 1d4efaa to 983b51d Compare November 18, 2025 16:07
@NickeZ NickeZ marked this pull request as draft November 18, 2025 16:14
@NickeZ NickeZ marked this pull request as ready for review November 24, 2025 23:29
@NickeZ NickeZ force-pushed the maint/rust-main-loop branch from 5beb172 to d5700b0 Compare November 26, 2025 08:26
@NickeZ NickeZ force-pushed the maint/rust-main-loop branch from d5700b0 to b287f43 Compare November 26, 2025 10:57
@NickeZ NickeZ force-pushed the maint/rust-main-loop branch from 4e671ce to e110364 Compare November 26, 2025 13:26
@NickeZ
Copy link
Collaborator Author

NickeZ commented Nov 26, 2025

@benma ready for review again

Copy link
Collaborator

@benma benma left a comment

Choose a reason for hiding this comment

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

Left another round of comments after reading through the new main_loop function line by line, not looked very closely at all the C wrappers yet.

Comment on lines +165 to +166
if let Some(ref mut task) = orientation_task {
if let Poll::Ready(_orientation) = util::bb02_async::spin(task) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just fyi, you can now add more conditions, like if let ... && let .... Above you also have some double nestings becaue of that, which you could flatten.

crate::workflow::orientation_screen::orientation_screen(),
));

let mut hww_data = None;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Helpful to annotate the type (: Option<[u8; 64]>) for clarity

) {
let (uart_read_buf, cap) = if let Some(uart_read_buf) = uart_read_buf {
(
uart_read_buf as *mut _ as *mut _,
Copy link
Collaborator

Choose a reason for hiding this comment

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

&mut [u8] can't be cast to *mut u8 in one go, wow. That's crazy.

Comment on lines +19 to +20
uart_read_buf: Option<&mut [u8]>,
uart_read_buf_len: Option<&mut u16>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

These should be inside of one Option, otherwise this function is not safe if you pass Some() for the buffer but None for the len.

}
crate::async_usb::spin();

if let Some(ref mut task) = orientation_task {
Copy link
Collaborator

Choose a reason for hiding this comment

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

in the PR where you added this in the C mainloop I asked you to move this into a separate function to keep the mainloop smaller 😄 Same here please, move it to a local fn orientation_screen_poll?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no problem, but you really think that is more readable? jumping to another function for like 5 lines of code?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, a function also has the benefit that it does not have the full mainloop function body in its scope. Not a very strong opinion though.

// See the License for the specific language governing permissions and
// limitations under the License.

pub fn product() -> (&'static str, u16) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

you don't need to return the size, the resulting str type contains it and you can call .len() on it if needed.

the callsite however just passes it on to set_product(), but that function also takes the string and also does not need the extra len param.

}
}

pub fn set_product(product: &'static str, len: u16) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

len param not needed, product.len() is the same

#[test]
fn ble_disable_disables_ble() {
unsafe {
bitbox02_sys::fake_memory_factoryreset();
Copy link
Collaborator

@benma benma Nov 27, 2025

Choose a reason for hiding this comment

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

Use crate::memory::fake_memory_factoryreset(), which already exists

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants