usb: support specifying device path (e.g. /dev/hidrawX)

This commit is contained in:
Evgeny Zinoviev 2023-01-12 02:01:36 +03:00
parent f95f3fe3d0
commit 5d9e828903
5 changed files with 48 additions and 7 deletions

View File

@ -24,6 +24,7 @@ enum {
LO_DEVICE_ERROR_LIMIT,
LO_USB_VENDOR_ID,
LO_USB_DEVICE_ID,
LO_USB_PATH,
LO_SERIAL_NAME,
LO_SERIAL_BAUD_RATE,
LO_SERIAL_DATA_BITS,

View File

@ -78,6 +78,9 @@ static void usage(const char* progname) {
"USB device options:\n"
" --usb-vendor-id <ID>: Vendor ID (default: " << std::setw(4) << voltronic::USBDevice::VENDOR_ID << ")\n"
" --usb-device-id <ID>: Device ID (default: " << std::setw(4) << voltronic::USBDevice::PRODUCT_ID << ")\n"
"\n"
" Alternatively, you can specify device path (e.g., /dev/hidraw0):\n"
" --usb-path <PATH>: Device path\n"
"\n";
std::cout.flags(f);
std::cout <<
@ -262,6 +265,7 @@ int main(int argc, char *argv[]) {
u16 usbVendorId = voltronic::USBDevice::VENDOR_ID;
u16 usbDeviceId = voltronic::USBDevice::PRODUCT_ID;
std::string usbDevicePath {};
std::string serialDeviceName(voltronic::SerialDevice::DEVICE_NAME);
voltronic::SerialBaudRate serialBaudRate = voltronic::SerialDevice::BAUD_RATE;
@ -280,6 +284,7 @@ int main(int argc, char *argv[]) {
{"device", required_argument, nullptr, LO_DEVICE},
{"usb-vendor-id", required_argument, nullptr, LO_USB_VENDOR_ID},
{"usb-device-id", required_argument, nullptr, LO_USB_DEVICE_ID},
{"usb-path", required_argument, nullptr, LO_USB_PATH},
{"serial-name", required_argument, nullptr, LO_SERIAL_NAME},
{"serial-baud-rate", required_argument, nullptr, LO_SERIAL_BAUD_RATE},
{"serial-data-bits", required_argument, nullptr, LO_SERIAL_DATA_BITS},
@ -357,6 +362,10 @@ int main(int argc, char *argv[]) {
}
break;
case LO_USB_PATH:
usbDevicePath = arg;
break;
case LO_SERIAL_NAME:
serialDeviceName = arg;
break;
@ -442,8 +451,12 @@ int main(int argc, char *argv[]) {
std::shared_ptr<voltronic::Device> dev;
switch (deviceType) {
case DeviceType::USB:
if (usbDevicePath.empty()) {
dev = std::shared_ptr<voltronic::Device>(new voltronic::USBDevice(usbVendorId,
usbDeviceId));
} else {
dev = std::shared_ptr<voltronic::Device>(new voltronic::USBDevice(usbDevicePath));
}
break;
case DeviceType::Pseudo:

View File

@ -42,7 +42,10 @@ static void usage(const char* progname) {
std::cout << std::hex << std::setfill('0') <<
"USB device options:\n"
" --usb-vendor-id <ID>: Vendor ID (default: " << std::setw(4) << voltronic::USBDevice::VENDOR_ID << ")\n"
" --usb-device-id <ID>: Device ID (default: " << std::setw(4) << voltronic::USBDevice::PRODUCT_ID << ")\n";
" --usb-device-id <ID>: Device ID (default: " << std::setw(4) << voltronic::USBDevice::PRODUCT_ID << ")\n"
"\n"
" Alternatively, you can specify device path (e.g., /dev/hidraw0):\n"
" --usb-path <PATH>: Device path\n";
std::cout.flags(f);
std::cout << "\n"
@ -73,6 +76,7 @@ int main(int argc, char *argv[]) {
unsigned short usbVendorId = voltronic::USBDevice::VENDOR_ID;
unsigned short usbDeviceId = voltronic::USBDevice::PRODUCT_ID;
std::string usbDevicePath {};
std::string serialDeviceName(voltronic::SerialDevice::DEVICE_NAME);
voltronic::SerialBaudRate serialBaudRate = voltronic::SerialDevice::BAUD_RATE;
@ -92,6 +96,7 @@ int main(int argc, char *argv[]) {
{"device-error-limit", required_argument, nullptr, LO_DEVICE_ERROR_LIMIT},
{"usb-vendor-id", required_argument, nullptr, LO_USB_VENDOR_ID},
{"usb-device-id", required_argument, nullptr, LO_USB_DEVICE_ID},
{"usb-path", required_argument, nullptr, LO_USB_PATH},
{"serial-name", required_argument, nullptr, LO_SERIAL_NAME},
{"serial-baud-rate", required_argument, nullptr, LO_SERIAL_BAUD_RATE},
{"serial-data-bits", required_argument, nullptr, LO_SERIAL_DATA_BITS},
@ -176,6 +181,10 @@ int main(int argc, char *argv[]) {
}
break;
case LO_USB_PATH:
usbDevicePath = arg;
break;
case LO_SERIAL_NAME:
serialDeviceName = arg;
break;
@ -243,7 +252,12 @@ int main(int argc, char *argv[]) {
try {
switch (deviceType) {
case DeviceType::USB:
dev = std::shared_ptr<voltronic::Device>(new voltronic::USBDevice(usbVendorId, usbDeviceId));
if (usbDevicePath.empty()) {
dev = std::shared_ptr<voltronic::Device>(new voltronic::USBDevice(usbVendorId,
usbDeviceId));
} else {
dev = std::shared_ptr<voltronic::Device>(new voltronic::USBDevice(usbDevicePath));
}
break;
case DeviceType::Pseudo:

View File

@ -72,8 +72,11 @@ public:
static u16 GET_HID_REPORT_SIZE(size_t size);
USBDevice(u16 vendorId, u16 productId);
explicit USBDevice(const std::string& path);
~USBDevice();
static inline void init();
size_t read(u8* buf, size_t bufSize) override;
size_t write(const u8* data, size_t dataSize) override;
};

View File

@ -12,14 +12,24 @@
namespace voltronic {
USBDevice::USBDevice(u16 vendorId, u16 productId) {
if (hid_init() != 0)
throw DeviceError("hidapi initialization failure");
init();
device_ = hid_open(vendorId, productId, nullptr);
if (!device_)
throw DeviceError("failed to create hidapi device");
}
USBDevice::USBDevice(const std::string& path) {
init();
device_ = hid_open_path(path.c_str());
if (!device_)
throw DeviceError("failed to create hidapi device");
}
void USBDevice::init() {
if (hid_init() != 0)
throw DeviceError("hidapi initialization failure");
}
USBDevice::~USBDevice() {
if (device_)
hid_close(device_);