Skip to content

Commit c5253cd

Browse files
committed
Merge branch 'sd-yield'
2 parents 1d5d349 + 89a8a6d commit c5253cd

File tree

7 files changed

+153
-81
lines changed

7 files changed

+153
-81
lines changed

src/rust/bitbox02-rust/src/backup.rs

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,18 @@ fn bitwise_recovery(buf1: &[u8], buf2: &[u8], buf3: &[u8]) -> Result<Zeroizing<V
158158
Ok(recovered_contents)
159159
}
160160

161-
pub fn load(
161+
pub async fn load(
162162
hal: &mut impl crate::hal::Hal,
163163
dir: &str,
164164
) -> Result<(Zeroizing<BackupData>, pb_backup::BackupMetaData), ()> {
165-
let files = hal.sd().list_subdir(Some(dir))?;
165+
let files = hal.sd().list_subdir(Some(dir)).await?;
166166
if files.len() != 3 {
167167
return Err(());
168168
}
169169
let file_contents: [Zeroizing<Vec<u8>>; 3] = [
170-
hal.sd().load_bin(&files[0], dir)?,
171-
hal.sd().load_bin(&files[1], dir)?,
172-
hal.sd().load_bin(&files[2], dir)?,
170+
hal.sd().load_bin(&files[0], dir).await?,
171+
hal.sd().load_bin(&files[1], dir).await?,
172+
hal.sd().load_bin(&files[2], dir).await?,
173173
];
174174
for contents in file_contents.iter() {
175175
if let o @ Ok(_) = load_from_buffer(contents) {
@@ -186,7 +186,7 @@ pub fn load(
186186
)?)
187187
}
188188

189-
pub fn create(
189+
pub async fn create(
190190
hal: &mut impl crate::hal::Hal,
191191
seed: &[u8],
192192
name: &str,
@@ -232,7 +232,11 @@ pub fn create(
232232
};
233233
let backup_encoded = backup.encode_to_vec();
234234
let dir = id(seed);
235-
let files = hal.sd().list_subdir(Some(&dir)).or(Err(Error::SdList))?;
235+
let files = hal
236+
.sd()
237+
.list_subdir(Some(&dir))
238+
.await
239+
.or(Err(Error::SdList))?;
236240

237241
let filename_datetime = {
238242
let tm = bitbox02::get_datetime(backup_create_timestamp).map_err(|_| Error::Generic)?;
@@ -255,10 +259,12 @@ pub fn create(
255259
}
256260
hal.sd()
257261
.write_bin(&filename, &dir, &backup_encoded)
262+
.await
258263
.or(Err(Error::SdWrite))?;
259264
if hal
260265
.sd()
261266
.load_bin(&filename, &dir)
267+
.await
262268
.or(Err(Error::SdRead))?
263269
.as_slice()
264270
!= backup_encoded.as_slice()
@@ -268,7 +274,7 @@ pub fn create(
268274
}
269275
let mut stale = false;
270276
for file in files {
271-
if hal.sd().erase_file_in_subdir(&file, &dir).is_err() {
277+
if hal.sd().erase_file_in_subdir(&file, &dir).await.is_err() {
272278
stale = true
273279
}
274280
}
@@ -285,6 +291,8 @@ mod tests {
285291
use crate::hal::testing::TestingHal;
286292
use core::convert::TryInto;
287293

294+
use util::bb02_async::block_on;
295+
288296
#[test]
289297
fn test_id() {
290298
// Seeds of different lengths (16, 24, 32 bytes)
@@ -307,11 +315,23 @@ mod tests {
307315
let mut mock_hal = TestingHal::new();
308316
let timestamp = 1601281809;
309317
let birthdate = timestamp - 32400;
310-
assert!(create(&mut mock_hal, seed, "test name", timestamp, birthdate).is_ok());
318+
assert!(
319+
block_on(create(
320+
&mut mock_hal,
321+
seed,
322+
"test name",
323+
timestamp,
324+
birthdate
325+
))
326+
.is_ok()
327+
);
311328
let dir = id(seed);
312-
assert_eq!(mock_hal.sd.list_subdir(None), Ok(vec![dir.clone()]));
313329
assert_eq!(
314-
mock_hal.sd.list_subdir(Some(&dir)),
330+
block_on(mock_hal.sd.list_subdir(None)),
331+
Ok(vec![dir.clone()])
332+
);
333+
assert_eq!(
334+
block_on(mock_hal.sd.list_subdir(Some(&dir))),
315335
Ok(vec![
316336
"backup_Mon_2020-09-28T08-30-09Z_0.bin".into(),
317337
"backup_Mon_2020-09-28T08-30-09Z_1.bin".into(),
@@ -320,42 +340,59 @@ mod tests {
320340
);
321341

322342
// Recreating using same timestamp is not allowed and doesn't change the backups.
323-
assert!(create(&mut mock_hal, seed, "new name", timestamp, birthdate).is_err());
343+
assert!(
344+
block_on(create(
345+
&mut mock_hal,
346+
seed,
347+
"new name",
348+
timestamp,
349+
birthdate
350+
))
351+
.is_err()
352+
);
324353
assert_eq!(
325-
mock_hal.sd.list_subdir(Some(&dir)),
354+
block_on(mock_hal.sd.list_subdir(Some(&dir))),
326355
Ok(vec![
327356
"backup_Mon_2020-09-28T08-30-09Z_0.bin".into(),
328357
"backup_Mon_2020-09-28T08-30-09Z_1.bin".into(),
329358
"backup_Mon_2020-09-28T08-30-09Z_2.bin".into()
330359
])
331360
);
332361

333-
let contents: [zeroize::Zeroizing<Vec<u8>>; 3] = mock_hal
334-
.sd
335-
.list_subdir(Some(&dir))
336-
.unwrap()
337-
.iter()
338-
.map(|file| mock_hal.sd.load_bin(file, &dir).unwrap())
339-
.collect::<Vec<_>>()
340-
.try_into()
341-
.unwrap();
362+
let contents: [zeroize::Zeroizing<Vec<u8>>; 3] =
363+
block_on(mock_hal.sd.list_subdir(Some(&dir)))
364+
.unwrap()
365+
.iter()
366+
.map(|file| block_on(mock_hal.sd.load_bin(file, &dir)).unwrap())
367+
.collect::<Vec<_>>()
368+
.try_into()
369+
.unwrap();
342370
assert!(
343371
contents[0].as_slice() == contents[1].as_slice()
344372
&& contents[0].as_slice() == contents[2].as_slice()
345373
);
346374

347375
// Recreating the backup removes the previous files.
348-
assert!(create(&mut mock_hal, seed, "new name", timestamp + 1, birthdate).is_ok());
376+
assert!(
377+
block_on(create(
378+
&mut mock_hal,
379+
seed,
380+
"new name",
381+
timestamp + 1,
382+
birthdate
383+
))
384+
.is_ok()
385+
);
349386
assert_eq!(
350-
mock_hal.sd.list_subdir(Some(&dir)),
387+
block_on(mock_hal.sd.list_subdir(Some(&dir))),
351388
Ok(vec![
352389
"backup_Mon_2020-09-28T08-30-10Z_0.bin".into(),
353390
"backup_Mon_2020-09-28T08-30-10Z_1.bin".into(),
354391
"backup_Mon_2020-09-28T08-30-10Z_2.bin".into()
355392
])
356393
);
357394

358-
let (backup_data, metadata) = load(&mut mock_hal, &dir).unwrap();
395+
let (backup_data, metadata) = block_on(load(&mut mock_hal, &dir)).unwrap();
359396
assert_eq!(backup_data.get_seed(), seed);
360397
assert_eq!(backup_data.0.birthdate, birthdate);
361398
assert_eq!(metadata.name.as_str(), "new name");

src/rust/bitbox02-rust/src/hal.rs

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,19 @@ pub use crate::workflow::Workflows as Ui;
1818
use alloc::string::String;
1919
use alloc::vec::Vec;
2020

21+
use futures_lite::future::yield_now;
22+
23+
#[allow(async_fn_in_trait)]
2124
pub trait Sd {
22-
fn sdcard_inserted(&mut self) -> bool;
23-
fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()>;
24-
fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()>;
25-
fn load_bin(&mut self, filename: &str, dir: &str) -> Result<zeroize::Zeroizing<Vec<u8>>, ()>;
26-
fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()>;
25+
async fn sdcard_inserted(&mut self) -> bool;
26+
async fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()>;
27+
async fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()>;
28+
async fn load_bin(
29+
&mut self,
30+
filename: &str,
31+
dir: &str,
32+
) -> Result<zeroize::Zeroizing<Vec<u8>>, ()>;
33+
async fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()>;
2734
}
2835

2936
/// Hardware abstraction layer for BitBox devices.
@@ -36,28 +43,42 @@ pub struct BitBox02Sd;
3643

3744
impl Sd for BitBox02Sd {
3845
#[inline(always)]
39-
fn sdcard_inserted(&mut self) -> bool {
40-
bitbox02::sd::sdcard_inserted()
46+
async fn sdcard_inserted(&mut self) -> bool {
47+
let result = bitbox02::sd::sdcard_inserted();
48+
yield_now().await;
49+
result
4150
}
4251

4352
#[inline(always)]
44-
fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()> {
45-
bitbox02::sd::list_subdir(subdir)
53+
async fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()> {
54+
let result = bitbox02::sd::list_subdir(subdir);
55+
yield_now().await;
56+
result
4657
}
4758

4859
#[inline(always)]
49-
fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()> {
50-
bitbox02::sd::erase_file_in_subdir(filename, dir)
60+
async fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()> {
61+
let result = bitbox02::sd::erase_file_in_subdir(filename, dir);
62+
yield_now().await;
63+
result
5164
}
5265

5366
#[inline(always)]
54-
fn load_bin(&mut self, filename: &str, dir: &str) -> Result<zeroize::Zeroizing<Vec<u8>>, ()> {
55-
bitbox02::sd::load_bin(filename, dir)
67+
async fn load_bin(
68+
&mut self,
69+
filename: &str,
70+
dir: &str,
71+
) -> Result<zeroize::Zeroizing<Vec<u8>>, ()> {
72+
let result = bitbox02::sd::load_bin(filename, dir);
73+
yield_now().await;
74+
result
5675
}
5776

5877
#[inline(always)]
59-
fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()> {
60-
bitbox02::sd::write_bin(filename, dir, data)
78+
async fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()> {
79+
let result = bitbox02::sd::write_bin(filename, dir, data);
80+
yield_now().await;
81+
result
6182
}
6283
}
6384

@@ -105,11 +126,11 @@ pub mod testing {
105126
}
106127

107128
impl super::Sd for TestingSd {
108-
fn sdcard_inserted(&mut self) -> bool {
129+
async fn sdcard_inserted(&mut self) -> bool {
109130
self.inserted.unwrap()
110131
}
111132

112-
fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()> {
133+
async fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()> {
113134
match subdir {
114135
Some(key) => Ok(self
115136
.files
@@ -120,14 +141,14 @@ pub mod testing {
120141
}
121142
}
122143

123-
fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()> {
144+
async fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()> {
124145
self.files
125146
.get_mut(dir)
126147
.and_then(|files| files.remove(filename).map(|_| ()))
127148
.ok_or(())
128149
}
129150

130-
fn load_bin(
151+
async fn load_bin(
131152
&mut self,
132153
filename: &str,
133154
dir: &str,
@@ -139,7 +160,7 @@ pub mod testing {
139160
.ok_or(())
140161
}
141162

142-
fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()> {
163+
async fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()> {
143164
self.files
144165
.entry(dir.into())
145166
.or_default()
@@ -176,29 +197,38 @@ pub mod testing {
176197
use super::*;
177198
use crate::hal::Sd;
178199

200+
use util::bb02_async::block_on;
201+
179202
// Quick check if our mock TestingSd implementation makes sense.
180203
#[test]
181204
fn test_sd_list_write_read_erase() {
182205
let mut sd = TestingSd::new();
183-
assert_eq!(sd.list_subdir(None), Ok(vec![]));
184-
assert_eq!(sd.list_subdir(Some("dir1")), Ok(vec![]));
206+
assert_eq!(block_on(sd.list_subdir(None)), Ok(vec![]));
207+
assert_eq!(block_on(sd.list_subdir(Some("dir1"))), Ok(vec![]));
185208

186-
assert!(sd.load_bin("file1.txt", "dir1").is_err());
187-
assert!(sd.write_bin("file1.txt", "dir1", b"data").is_ok());
188-
assert_eq!(sd.list_subdir(None), Ok(vec!["dir1".into()]));
189-
assert_eq!(sd.list_subdir(Some("dir1")), Ok(vec!["file1.txt".into()]));
209+
assert!(block_on(sd.load_bin("file1.txt", "dir1")).is_err());
210+
assert!(block_on(sd.write_bin("file1.txt", "dir1", b"data")).is_ok());
211+
assert_eq!(block_on(sd.list_subdir(None)), Ok(vec!["dir1".into()]));
212+
assert_eq!(
213+
block_on(sd.list_subdir(Some("dir1"))),
214+
Ok(vec!["file1.txt".into()])
215+
);
190216
assert_eq!(
191-
sd.load_bin("file1.txt", "dir1").unwrap().as_slice(),
217+
block_on(sd.load_bin("file1.txt", "dir1"))
218+
.unwrap()
219+
.as_slice(),
192220
b"data"
193221
);
194-
assert!(sd.write_bin("file1.txt", "dir1", b"replaced data").is_ok());
222+
assert!(block_on(sd.write_bin("file1.txt", "dir1", b"replaced data")).is_ok());
195223
assert_eq!(
196-
sd.load_bin("file1.txt", "dir1").unwrap().as_slice(),
224+
block_on(sd.load_bin("file1.txt", "dir1"))
225+
.unwrap()
226+
.as_slice(),
197227
b"replaced data"
198228
);
199-
assert!(sd.erase_file_in_subdir("doesnt-exist.txt", "dir1").is_err());
200-
assert!(sd.erase_file_in_subdir("file1.txt", "dir1").is_ok());
201-
assert_eq!(sd.list_subdir(Some("dir1")), Ok(vec![]));
229+
assert!(block_on(sd.erase_file_in_subdir("doesnt-exist.txt", "dir1")).is_err());
230+
assert!(block_on(sd.erase_file_in_subdir("file1.txt", "dir1")).is_ok());
231+
assert_eq!(block_on(sd.list_subdir(Some("dir1"))), Ok(vec![]));
202232
}
203233
}
204234
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ async fn process_api(hal: &mut impl crate::hal::Hal, request: &Request) -> Resul
172172
set_mnemonic_passphrase_enabled::process(hal, request).await
173173
}
174174
Request::InsertRemoveSdcard(request) => sdcard::process(hal, request).await,
175-
Request::ListBackups(_) => backup::list(hal),
175+
Request::ListBackups(_) => backup::list(hal).await,
176176
Request::CheckSdcard(_) => Ok(Response::CheckSdcard(pb::CheckSdCardResponse {
177-
inserted: hal.sd().sdcard_inserted(),
177+
inserted: hal.sd().sdcard_inserted().await,
178178
})),
179179
Request::CheckBackup(request) => backup::check(hal, request).await,
180180
Request::CreateBackup(request) => backup::create(hal, request).await,

0 commit comments

Comments
 (0)