diff options
Diffstat (limited to 'include/device_proto.h')
-rw-r--r-- | include/device_proto.h | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/include/device_proto.h b/include/device_proto.h index cde1d51..0953566 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 @@ -89,24 +90,38 @@ namespace nitrokey { * command_id member in incoming HIDReport structure carries the command * type last used. */ + namespace DeviceResponseConstants{ + //magic numbers from firmware + static constexpr auto storage_status_absolute_address = 21; + static constexpr auto storage_data_absolute_address = storage_status_absolute_address + 5; + static constexpr auto header_size = 8; //from _zero to last_command_status inclusive + static constexpr auto footer_size = 4; //crc + static constexpr auto wrapping_size = header_size + footer_size; + } + template<CommandID cmd_id, typename ResponsePayload> struct DeviceResponse { + static constexpr auto storage_status_padding_size = + DeviceResponseConstants::storage_status_absolute_address - DeviceResponseConstants::header_size; + uint8_t _zero; uint8_t device_status; uint8_t command_id; // originally last_command_type uint32_t last_command_crc; uint8_t last_command_status; + union { - uint8_t _padding[HID_REPORT_SIZE - 12]; + uint8_t _padding[HID_REPORT_SIZE - DeviceResponseConstants::wrapping_size]; ResponsePayload payload; struct { - uint8_t _storage_status_padding[20 - 8 + 1]; //starts on 20th byte minus already 8 used + zero byte + uint8_t _storage_status_padding[storage_status_padding_size]; uint8_t command_counter; uint8_t command_id; uint8_t device_status; //@see stick20::device_status uint8_t progress_bar_value; } __packed storage_status; } __packed; + uint32_t crc; void initialize() { bzero(this, sizeof *this); } @@ -119,9 +134,7 @@ namespace nitrokey { } void update_CRC() { crc = calculate_CRC(); } - bool isCRCcorrect() const { return crc == calculate_CRC(); } - bool isValid() const { // return !_zero && payload.isValid() && isCRCcorrect() && // command_id == (uint8_t)(cmd_id); @@ -216,6 +229,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 +277,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<uint8_t>(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<uint8_t>(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<uint8_t>(stick10::device_status::busy) && + static_cast<stick20::device_status>(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 +305,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); @@ -293,7 +316,7 @@ namespace nitrokey { clear_packet(outp); if (status <= 0) - throw std::runtime_error( + throw std::runtime_error( //FIXME replace with CriticalErrorException std::string("Device error while executing command ") + std::to_string(status)); @@ -302,6 +325,13 @@ namespace nitrokey { Log::instance()(std::string("receiving_retry_counter count: ") + std::to_string(receiving_retry_counter), Loglevel::DEBUG); + if (resp.device_status == static_cast<uint8_t>(stick10::device_status::busy) && + static_cast<stick20::device_status>(resp.storage_status.device_status) + == stick20::device_status::busy_progressbar){ + throw LongOperationInProgressException( + resp.command_id, resp.device_status, resp.storage_status.progress_bar_value); + } + if (!resp.isValid()) throw std::runtime_error("Invalid incoming packet"); if (receiving_retry_counter <= 0) throw std::runtime_error( |