diff options
| -rw-r--r-- | device.cc | 32 | ||||
| -rw-r--r-- | include/device.h | 5 | ||||
| -rw-r--r-- | include/device_proto.h | 14 | 
3 files changed, 43 insertions, 8 deletions
| @@ -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 ") + | 
