From f266ea63039c87886f871b068ef3dcdf851a1eca Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 14 Jan 2020 13:48:56 +0100 Subject: Add the get_operation_status function to the Storage struct This patch adds support for the NK_get_progress_bar_value function: It adds the OperationStatus enum that stores the return value of this command and adds the get_operation_status function to the Storage struct that executes the command. --- CHANGELOG.md | 2 ++ TODO.md | 1 - src/device/mod.rs | 3 ++- src/device/storage.rs | 35 ++++++++++++++++++++++++++++++++++- src/lib.rs | 2 +- tests/device.rs | 9 +++++++-- 6 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cebe8cb..419a942 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ SPDX-License-Identifier: CC0-1.0 - Add the `get_status` function to the `Device` trait. - Rename `Status::get_status` to `get_storage_status`. - Add the `get_sd_card_usage` function to the `Storage` struct. +- Add the `OperationStatus` enum and the `get_operation_status` function for + the `Storage` struct. # v0.4.0 (2020-01-02) - Remove the `test-pro` and `test-storage` features. diff --git a/TODO.md b/TODO.md index 79a68e4..8f9b898 100644 --- a/TODO.md +++ b/TODO.md @@ -5,7 +5,6 @@ SPDX-License-Identifier: CC0-1.0 - Add support for the currently unsupported commands: - `NK_fill_SD_card_with_random_data` - - `NK_get_progress_bar_value` - Clear passwords from memory. - Lock password safe in `PasswordSafe::drop()` (see [nitrokey-storage-firmware issue 65][]). diff --git a/src/device/mod.rs b/src/device/mod.rs index 8b7f1c6..16d6b11 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -25,7 +25,8 @@ use crate::util::{ pub use pro::Pro; pub use storage::{ - SdCardData, Storage, StorageProductionInfo, StorageStatus, VolumeMode, VolumeStatus, + OperationStatus, SdCardData, Storage, StorageProductionInfo, StorageStatus, VolumeMode, + VolumeStatus, }; pub use wrapper::DeviceWrapper; diff --git a/src/device/storage.rs b/src/device/storage.rs index a2c598b..8d45763 100644 --- a/src/device/storage.rs +++ b/src/device/storage.rs @@ -1,6 +1,7 @@ // Copyright (C) 2019-2020 Robin Krahl // SPDX-License-Identifier: MIT +use std::convert::TryFrom as _; use std::fmt; use std::ops; @@ -9,7 +10,7 @@ use nitrokey_sys; use crate::device::{Device, FirmwareVersion, Model, Status}; use crate::error::Error; use crate::otp::GenerateOtp; -use crate::util::{get_command_result, get_cstring}; +use crate::util::{get_command_result, get_cstring, get_last_error}; /// A Nitrokey Storage device without user or admin authentication. /// @@ -142,6 +143,20 @@ pub struct StorageStatus { pub stick_initialized: bool, } +/// The progress of a background operation on the Nitrokey. +/// +/// Some commands may start a background operation during which no other commands can be executed. +/// This enum stores the status of a background operation: Ongoing with a relative progress (up to +/// 100), or idle, i. e. no background operation has been started or the last one has been +/// finished. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum OperationStatus { + /// A background operation with its progress value (less than or equal to 100). + Ongoing(u8), + /// No backgrund operation. + Idle, +} + impl<'a> Storage<'a> { pub(crate) fn new(manager: &'a mut crate::Manager) -> Storage<'a> { Storage { @@ -680,6 +695,24 @@ impl<'a> Storage<'a> { get_command_result(unsafe { nitrokey_sys::NK_wink() }) } + /// Returns the status of an ongoing background operation on the Nitrokey Storage. + /// + /// Some commands may start a background operation during which no other commands can be + /// executed. This method can be used to check whether such an operation is ongoing. + /// + /// Currently, this is only used by the `fill_sd_card` method. + pub fn get_operation_status(&self) -> Result { + let status = unsafe { nitrokey_sys::NK_get_progress_bar_value() }; + match status { + 0..=100 => u8::try_from(status) + .map(OperationStatus::Ongoing) + .map_err(|_| Error::UnexpectedError), + -1 => Ok(OperationStatus::Idle), + -2 => Err(get_last_error()), + _ => Err(Error::UnexpectedError), + } + } + /// Exports the firmware to the unencrypted volume. /// /// This command requires the admin PIN. The unencrypted volume must be in read-write mode diff --git a/src/lib.rs b/src/lib.rs index 41c99c5..c6c3ff5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,7 +126,7 @@ use nitrokey_sys; pub use crate::auth::{Admin, Authenticate, User}; pub use crate::config::Config; pub use crate::device::{ - Device, DeviceInfo, DeviceWrapper, Model, Pro, SdCardData, Status, Storage, + Device, DeviceInfo, DeviceWrapper, Model, OperationStatus, Pro, SdCardData, Status, Storage, StorageProductionInfo, StorageStatus, VolumeMode, VolumeStatus, }; pub use crate::error::{CommandError, CommunicationError, Error, LibraryError}; diff --git a/tests/device.rs b/tests/device.rs index 070f3c1..7296372 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -9,8 +9,8 @@ use std::{thread, time}; use nitrokey::{ Authenticate, CommandError, CommunicationError, Config, ConfigureOtp, Device, DeviceInfo, - Error, GenerateOtp, GetPasswordSafe, LibraryError, OtpMode, OtpSlotData, Storage, VolumeMode, - DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN, + Error, GenerateOtp, GetPasswordSafe, LibraryError, OperationStatus, OtpMode, OtpSlotData, + Storage, VolumeMode, DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN, }; use nitrokey_test::test as test_device; @@ -647,6 +647,11 @@ fn get_sd_card_usage(device: Storage) { assert!(range.end <= 100); } +#[test_device] +fn get_operation_status(device: Storage) { + assert_ok!(OperationStatus::Idle, device.get_operation_status()); +} + #[test_device] fn export_firmware(device: Storage) { let mut device = device; -- cgit v1.2.1