aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzczepan Zalega <szczepan@nitrokey.com>2017-02-04 16:13:02 +0100
committerSzczepan Zalega <szczepan@nitrokey.com>2017-03-11 15:41:42 +0100
commit3fcbb90176fb02816cc47ad7172b7b89bf6cb67d (patch)
tree86bc483b94dfb135c497abee8e7f1c96ce1508a3
parentdb76ae5299f3650385f66e4c596b18fd54250d38 (diff)
downloadlibnitrokey-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.cc24
-rw-r--r--include/device.h22
-rw-r--r--include/device_proto.h18
3 files changed, 59 insertions, 5 deletions
diff --git a/device.cc b/device.cc
index ce1eeb6..d904fd9 100644
--- a/device.cc
+++ b/device.cc
@@ -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;