Skip to content

Commit 9bd222b

Browse files
committed
api/bluetooth: restart Bluetooth after firmware upgrade
This will disconnect any open Bluetooth connection and make the chip load the new upgraded firmware.
1 parent 2c11115 commit 9bd222b

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

src/rust/bitbox02-rust/src/async_usb.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ where
101101

102102
*state = UsbTaskState::Running(Some(task), WaitingForNextRequestState::Idle);
103103
}
104+
// This panic could happen e.g. if someone reconnects to the BitBox while a task is running,
105+
// before the 500ms timeout cancels the task. The proper way to handle would be to let the
106+
// host know we are busy so the host can re-retry after some time.
104107
_ => panic!("spawn: wrong state"),
105108
}
106109
}
@@ -149,7 +152,13 @@ pub fn spin() {
149152
_ => None,
150153
};
151154
if let Some(ref mut task) = popped_task {
152-
match spin_task(task) {
155+
let spin_result = spin_task(task);
156+
if matches!(*USB_TASK_STATE.0.borrow(), UsbTaskState::Nothing) {
157+
// The task was cancelled while it was running, so there is nothing to do with the
158+
// result.
159+
return;
160+
}
161+
match spin_result {
153162
Poll::Ready(result) => {
154163
*USB_TASK_STATE.0.borrow_mut() = UsbTaskState::ResultAvailable(result);
155164
}
@@ -208,6 +217,11 @@ pub fn copy_response(dst: &mut [u8]) -> Result<usize, CopyResponseErr> {
208217

209218
/// Cancel and drop a running task. Returns true if a task was cancelled, false if no task was
210219
/// running.
220+
///
221+
/// Call this inside a running task only if you expect that the host may not be able to read the
222+
/// result (e.g. when resetting the BLE chip as part of a task), so another task can spawn
223+
/// afterwards immediately (before the timeout auto-cancles it), which currently would run into a
224+
/// panic until the response was read and the current task concluded. See the comment in `spawn()`
211225
pub fn cancel() -> bool {
212226
let mut state = USB_TASK_STATE.0.borrow_mut();
213227
if let UsbTaskState::Running(_, _) = *state {

src/rust/bitbox02-rust/src/hww/api/bluetooth.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ async fn process_upgrade(
163163

164164
if response.is_ok() {
165165
hal.ui().status("Upgrade\nsuccessful", true).await;
166+
bitbox02::reset_ble();
167+
// Since the Bluetooth host will not be there anymore to read this response, this task will
168+
// not be cleared by the executor. We do it manually to make space for the next task upon
169+
// reconnection.
170+
crate::async_usb::cancel();
166171
} else {
167172
hal.ui().status("Upgrade failed", false).await;
168173
}

src/rust/bitbox02-sys/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ const ALLOWLIST_FNS: &[&str] = &[
120120
"random_mock_reset",
121121
"reboot_to_bootloader",
122122
"reset_reset",
123+
"reset_ble",
123124
"screen_print_debug",
124125
"screen_process",
125126
"screen_saver_disable",

src/rust/bitbox02/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ pub fn reset(status: bool) {
113113
unsafe { bitbox02_sys::reset_reset(status) }
114114
}
115115

116+
pub fn reset_ble() {
117+
unsafe { bitbox02_sys::reset_ble() }
118+
}
119+
116120
pub struct Tm {
117121
tm: bitbox02_sys::tm,
118122
}

0 commit comments

Comments
 (0)