summaryrefslogtreecommitdiff
path: root/include/device_proto.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/device_proto.h')
-rw-r--r--include/device_proto.h44
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(