aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzczepan Zalega <szczepan.zalega@gmail.com>2016-03-06 19:51:16 +0100
committerSzczepan Zalega <szczepan.zalega@gmail.com>2016-03-06 19:51:16 +0100
commitf66b89b493fd282d4170617f85c29c47fca75cf4 (patch)
tree3aa49a562bcd7a81d6dca3340ffe5ae9d845b430
parent85506009d3323e977b6de63b9b9c31760a2200fc (diff)
downloadlibnitrokey-f66b89b493fd282d4170617f85c29c47fca75cf4.tar.gz
libnitrokey-f66b89b493fd282d4170617f85c29c47fca75cf4.tar.bz2
Checking device status after completion of get_feature report and retrying receiving if device status!=0, added FIXME notes of further work
-rw-r--r--device.cc32
-rw-r--r--include/device.h5
-rw-r--r--include/device_proto.h14
3 files changed, 43 insertions, 8 deletions
diff --git a/device.cc b/device.cc
index f957223..fc8f6b8 100644
--- a/device.cc
+++ b/device.cc
@@ -44,24 +44,42 @@ CommError Device::send(const void *packet) {
}
CommError Device::recv(void *packet) {
- CommError status;
+ // FIXME change CommError return value to int (return value of
+ // hid_get_feature_report)
+ int status;
int retry_count = 0;
Log::instance()(__PRETTY_FUNCTION__, Loglevel::DEBUG_L2);
- std::this_thread::sleep_for(std::chrono::milliseconds(
- 5000)); // FIXME remove timeout in favor of sync communication
if (mp_devhandle == NULL)
throw std::runtime_error("Attempted HID receive on an invalid descriptor.");
+ // FIXME extract error handling and repeating to parent function in
+ // device_proto:192
for (;;) {
- status = (CommError)(hid_get_feature_report(
- mp_devhandle, (unsigned char *)(packet), HID_REPORT_SIZE));
- if ((int)status > 0 || retry_count++ >= m_retry_count) break;
+ status = (hid_get_feature_report(mp_devhandle, (unsigned char *)(packet),
+ HID_REPORT_SIZE));
+
+ // FIXME handle getting libhid error message somewhere else
+ auto pwherr = hid_error(mp_devhandle);
+ std::wstring wherr = (pwherr != NULL) ? pwherr : L"No error message";
+ std::string herr(wherr.begin(), wherr.end());
+ Log::instance()(std::string("libhid error message: ") + herr,
+ Loglevel::DEBUG_L2);
+
+ if (status > 0) break; // success
+ if (retry_count++ >= m_retry_count) {
+ Log::instance()(
+ "Maximum retry count reached" + std::to_string(retry_count),
+ Loglevel::WARNING);
+ break;
+ }
+ Log::instance()("Retrying... " + std::to_string(retry_count),
+ Loglevel::DEBUG);
std::this_thread::sleep_for(m_retry_timeout);
}
- return status;
+ return (CommError)status;
}
Stick10::Stick10() {
diff --git a/include/device.h b/include/device.h
index 768ac32..dc7832d 100644
--- a/include/device.h
+++ b/include/device.h
@@ -39,6 +39,11 @@ class Device {
*/
virtual CommError recv(void *packet);
+ int get_retry_count() { return m_retry_count; }
+ const;
+ std::chrono::milliseconds get_retry_timeout() { return m_retry_timeout; }
+ const;
+
protected:
uint16_t m_vid;
uint16_t m_pid;
diff --git a/include/device_proto.h b/include/device_proto.h
index 142b45b..f2ed84d 100644
--- a/include/device_proto.h
+++ b/include/device_proto.h
@@ -1,6 +1,7 @@
#ifndef DEVICE_PROTO_H
#define DEVICE_PROTO_H
#include <utility>
+#include <thread>
#include <type_traits>
#include <stdexcept>
#include <string>
@@ -179,7 +180,18 @@ class Transaction : semantics::non_constructible {
std::string("Device error while sending command ") +
std::to_string((int)(status)));
- status = dev.recv(&resp);
+ // FIXME make checks done in device:recv here
+ int retry = dev.get_retry_count();
+ while (retry-- > 0) {
+ status = dev.recv(&resp);
+ if (resp.device_status == 0) break;
+ Log::instance()("Device status is not ready (CRC error?) retrying..",
+ Loglevel::DEBUG); // FIXME translate device_status to log
+ Log::instance()("Invalid incoming HID packet:", Loglevel::DEBUG_L2);
+ Log::instance()((std::string)(resp), Loglevel::DEBUG_L2);
+ std::this_thread::sleep_for(dev.get_retry_timeout());
+ continue;
+ }
if ((int)(status) < 0 && status != CommError::ERR_NO_ERROR)
throw std::runtime_error(
std::string("Device error while executing command ") +