From 385d33bb4c8bb7fe604f5e0acc8aeca5f2146fae Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 25 Oct 2016 18:40:30 +0200 Subject: Handle busy_progressbar device status Signed-off-by: Szczepan Zalega --- CMakeLists.txt | 1 + include/LongOperationInProgressException.h | 28 ++++++++++++++++++++++++++++ include/device_proto.h | 21 +++++++++++++++++++-- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 include/LongOperationInProgressException.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f57fa7..e9cd54f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ set(SOURCE_FILES unittest/test_C_API.cpp unittest/catch_main.cpp unittest/test2.cc + include/LongOperationInProgressException.h ) add_executable(libnitrokey ${SOURCE_FILES}) \ No newline at end of file diff --git a/include/LongOperationInProgressException.h b/include/LongOperationInProgressException.h new file mode 100644 index 0000000..673a218 --- /dev/null +++ b/include/LongOperationInProgressException.h @@ -0,0 +1,28 @@ +// +// Created by sz on 24.10.16. +// + +#ifndef LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H +#define LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H + + +class LongOperationInProgressException : public std::exception { + +public: + unsigned char progress_bar_value; + unsigned char command_id; + + LongOperationInProgressException(unsigned char _command_id, unsigned char _progress_bar_value) { + command_id = _command_id; + progress_bar_value = _progress_bar_value; + nitrokey::log::Log::instance()( + std::string("LongOperationInProgressException, progress bar status: ")+ + std::to_string(progress_bar_value), nitrokey::log::Loglevel::DEBUG); + } + virtual const char *what() const throw() { + return "Device returned busy status with long operation in progress"; + } +}; + + +#endif //LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H diff --git a/include/device_proto.h b/include/device_proto.h index cde1d51..037451a 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -16,6 +16,7 @@ #include "command_id.h" #include "dissect.h" #include "CommandFailedException.h" +#include "LongOperationInProgressException.h" #define STICK20_UPDATE_MODE_VID 0x03EB #define STICK20_UPDATE_MODE_PID 0x2FF1 @@ -216,6 +217,7 @@ namespace nitrokey { if (!outp.isValid()) throw std::runtime_error("Invalid outgoing packet"); + bool successful_communication = false; int receiving_retry_counter = 0; int sending_retry_counter = dev.get_retry_sending_count(); while (sending_retry_counter-- > 0) { @@ -263,12 +265,21 @@ namespace nitrokey { //SENDPASSWORD gives wrong CRC , for now rely on !=0 (TODO report) // if (resp.device_status == 0 && resp.last_command_crc == outp.crc && resp.isCRCcorrect()) break; if (resp.device_status == static_cast(stick10::device_status::ok) && - resp.last_command_crc == outp.crc && resp.isValid()) break; + resp.last_command_crc == outp.crc && resp.isValid()){ + successful_communication = true; + break; + } if (resp.device_status == static_cast(stick10::device_status::busy)) { receiving_retry_counter++; Log::instance()("Status busy, not decresing receiving_retry_counter counter: " + std::to_string(receiving_retry_counter), Loglevel::DEBUG_L2); } + if (resp.device_status == static_cast(stick10::device_status::busy) && + static_cast(resp.storage_status.device_status) + == stick20::device_status::busy_progressbar){ + successful_communication = true; + break; + } Log::instance()(std::string("Retry status - dev status, equal crc, correct CRC: ") + std::to_string(resp.device_status) + " " + std::to_string(resp.last_command_crc == outp.crc) + @@ -282,7 +293,7 @@ namespace nitrokey { std::this_thread::sleep_for(dev.get_retry_timeout()); continue; } - if (resp.device_status == 0 && resp.last_command_crc == outp.crc) break; + if (successful_communication) break; Log::instance()(std::string("Resending (outer loop) "), Loglevel::DEBUG_L2); Log::instance()(std::string("sending_retry_counter count: ") + std::to_string(sending_retry_counter), Loglevel::DEBUG); @@ -297,6 +308,12 @@ namespace nitrokey { std::string("Device error while executing command ") + std::to_string(status)); + if (resp.device_status == static_cast(stick10::device_status::busy) && + static_cast(resp.storage_status.device_status) + == stick20::device_status::busy_progressbar){ + throw LongOperationInProgressException(resp.command_id, resp.storage_status.progress_bar_value); + } + Log::instance()("Incoming HID packet:", Loglevel::DEBUG); Log::instance()(static_cast(resp), Loglevel::DEBUG); Log::instance()(std::string("receiving_retry_counter count: ") + std::to_string(receiving_retry_counter), -- cgit v1.2.1