// SPDX-License-Identifier: BSD-3-Clause #include #include #include #include "../logging.h" #include "device.h" #include "exceptions.h" #include "hexdump/hexdump.h" namespace voltronic { USBDevice::USBDevice(u16 vendorId, u16 productId) { if (hid_init() != 0) throw DeviceError("hidapi initialization failure"); device_ = hid_open(vendorId, productId, nullptr); if (!device_) throw DeviceError("failed to create hidapi device"); } USBDevice::~USBDevice() { if (device_) hid_close(device_); hid_exit(); } size_t USBDevice::read(u8* buf, size_t bufSize) { int timeout = !timeout_ ? -1 : static_cast(getTimeLeft()); const int bytesRead = hid_read_timeout(device_, buf, GET_HID_REPORT_SIZE(bufSize), timeout); if (bytesRead == -1) throw DeviceError("hidapi_read_timeout() failed"); return bytesRead; } size_t USBDevice::write(const u8* data, size_t dataSize) { const size_t writeSize = GET_HID_REPORT_SIZE(dataSize); if (verbose_) { myerr << "dataSize=" << dataSize << ", writeSize=" << writeSize; std::cerr << hexdump((void*)data, dataSize); } u8 writeBuffer[HID_REPORT_SIZE+1]{0}; memcpy(&writeBuffer[1], data, writeSize); const int bytesWritten = hid_write(device_, writeBuffer, HID_REPORT_SIZE + 1); if (bytesWritten == -1) throw DeviceError("hidapi_write() failed"); return GET_HID_REPORT_SIZE(bytesWritten); } u16 USBDevice::GET_HID_REPORT_SIZE(size_t size) { return size > HID_REPORT_SIZE ? HID_REPORT_SIZE : size; } }