From f66b89b493fd282d4170617f85c29c47fca75cf4 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Sun, 6 Mar 2016 19:51:16 +0100 Subject: Checking device status after completion of get_feature report and retrying receiving if device status!=0, added FIXME notes of further work --- device.cc | 32 +++++++++++++++++++++++++------- include/device.h | 5 +++++ include/device_proto.h | 14 +++++++++++++- 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 +#include #include #include #include @@ -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 ") + -- cgit v1.2.3