diff options
author | Szczepan Zalega <szczepan@nitrokey.com> | 2017-02-04 16:13:02 +0100 |
---|---|---|
committer | Szczepan Zalega <szczepan@nitrokey.com> | 2017-03-11 15:41:42 +0100 |
commit | 3fcbb90176fb02816cc47ad7172b7b89bf6cb67d (patch) | |
tree | 86bc483b94dfb135c497abee8e7f1c96ce1508a3 | |
parent | db76ae5299f3650385f66e4c596b18fd54250d38 (diff) | |
download | libnitrokey-3fcbb90176fb02816cc47ad7172b7b89bf6cb67d.tar.gz libnitrokey-3fcbb90176fb02816cc47ad7172b7b89bf6cb67d.tar.bz2 |
Make statistics about device's connection
Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
-rw-r--r-- | device.cc | 24 | ||||
-rw-r--r-- | include/device.h | 22 | ||||
-rw-r--r-- | include/device_proto.h | 18 |
3 files changed, 59 insertions, 5 deletions
@@ -101,6 +101,9 @@ int Device::recv(void *packet) { Log::instance()( "Maximum retry count reached" + std::to_string(retry_count), Loglevel::WARNING); + Log::instance()( + std::string("Counter stats") + m_counters.get_as_string(), + Loglevel::DEBUG); break; } Log::instance()("Retrying... " + std::to_string(retry_count), @@ -129,6 +132,11 @@ bool Device::is_connected() { // return hid_read_timeout(mp_devhandle, buf, sizeof(buf), 20) != -1; } +void Device::show_stats() { + auto s = m_counters.get_as_string(); + Log::instance()(s, Loglevel::DEBUG_L2); +} + Stick10::Stick10(): Device(0x20a0, 0x4108, DeviceModel::PRO, 100ms, 20, 100ms) {} @@ -137,3 +145,19 @@ Stick10::Stick10(): Stick20::Stick20(): Device(0x20a0, 0x4109, DeviceModel::STORAGE, 200ms, 40, 200ms) {} + +#include <sstream> +#define p(x) ss << #x << " " << x << ", "; +std::string Device::ErrorCounters::get_as_string() { + std::stringstream ss; + p(wrong_CRC); + p(CRC_other_than_awaited); + p(busy); + p(total_retries); + p(sending_error); + p(receiving_error); + p(total_comm_runs); + p(storage_commands); + p(successful ); + return ss.str(); +} diff --git a/include/device.h b/include/device.h index 5965f99..a23e1b3 100644 --- a/include/device.h +++ b/include/device.h @@ -2,7 +2,8 @@ #define DEVICE_H #include <chrono> #include <hidapi/hidapi.h> -#include <stdint.h> +#include <cstdint> +#include <string> #define HID_REPORT_SIZE 65 @@ -30,11 +31,26 @@ enum class DeviceModel{ class Device { public: + + struct ErrorCounters{ + int wrong_CRC; + int CRC_other_than_awaited; + int busy; + int total_retries; + int sending_error; + int receiving_error; + int total_comm_runs; + int storage_commands; + int successful; + std::string get_as_string(); + } m_counters = {}; + + Device(const uint16_t vid, const uint16_t pid, const DeviceModel model, const milliseconds send_receive_delay, const int retry_receiving_count, const milliseconds retry_timeout); - virtual ~Device(){disconnect();} + virtual ~Device(){show_stats(); disconnect();} // lack of device is not actually an error, // so it doesn't throw @@ -54,6 +70,8 @@ public: bool is_connected(); + void show_stats(); + ErrorCounters get_stats(){ return m_counters; } int get_retry_receiving_count() const { return m_retry_receiving_count; }; int get_retry_sending_count() const { return m_retry_sending_count; }; std::chrono::milliseconds get_retry_timeout() const { return m_retry_timeout; }; diff --git a/include/device_proto.h b/include/device_proto.h index 1e07277..e3a217d 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -221,6 +221,7 @@ namespace nitrokey { if (dev == nullptr){ throw DeviceNotConnected("Device not initialized"); } + dev->m_counters.total_comm_runs++; int status; OutgoingPacket outp; @@ -246,6 +247,7 @@ namespace nitrokey { if (status <= 0){ Log::instance()("Encountered communication error, disconnecting device", Loglevel::DEBUG_L2); dev->disconnect(); + dev->m_counters.sending_error++; throw DeviceSendingFailure( std::string("Device error while sending command ") + std::to_string(status)); @@ -263,6 +265,7 @@ namespace nitrokey { resp.command_id < stick20::CMD_END_VALUE ) { Log::instance()(std::string("Detected storage device cmd, status: ") + std::to_string(resp.storage_status.device_status), Loglevel::DEBUG_L2); + dev->m_counters.storage_commands++; resp.last_command_status = static_cast<uint8_t>(stick10::command_status::ok); switch (static_cast<stick20::device_status>(resp.storage_status.device_status)) { @@ -288,8 +291,9 @@ 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; + auto CRC_equal_awaited = resp.last_command_crc == outp.crc; if (resp.device_status == static_cast<uint8_t>(stick10::device_status::ok) && - resp.last_command_crc == outp.crc && resp.isValid()){ + CRC_equal_awaited && resp.isValid()){ successful_communication = true; break; } @@ -306,14 +310,19 @@ namespace nitrokey { } Log::instance()(std::string("Retry status - dev status, awaited cmd crc, correct packet CRC: ") + std::to_string(resp.device_status) + " " + - std::to_string(resp.last_command_crc == outp.crc) + + std::to_string(CRC_equal_awaited) + " " + std::to_string(resp.isCRCcorrect()), Loglevel::DEBUG_L2); + if (!resp.isCRCcorrect()) dev->m_counters.wrong_CRC++; + if (!CRC_equal_awaited) dev->m_counters.CRC_other_than_awaited++; + + Log::instance()( "Device is not ready or received packet's last CRC is not equal to sent CRC packet, retrying...", Loglevel::DEBUG); Log::instance()("Invalid incoming HID packet:", Loglevel::DEBUG_L2); Log::instance()(static_cast<std::string>(resp), Loglevel::DEBUG_L2); + dev->m_counters.total_retries++; std::this_thread::sleep_for(dev->get_retry_timeout()); continue; } @@ -327,10 +336,12 @@ namespace nitrokey { clear_packet(outp); - if (status <= 0) + if (status <= 0) { + dev->m_counters.receiving_error++; throw DeviceReceivingFailure( //FIXME replace with CriticalErrorException std::string("Device error while executing command ") + std::to_string(status)); + } Log::instance()("Incoming HID packet:", Loglevel::DEBUG); Log::instance()(static_cast<std::string>(resp), Loglevel::DEBUG); @@ -351,6 +362,7 @@ namespace nitrokey { if (resp.last_command_status != static_cast<uint8_t>(stick10::command_status::ok)) throw CommandFailedException(resp.command_id, resp.last_command_status); + dev->m_counters.successful++; // See: DeviceResponse return resp; |