Files
ptouch-prnt/src/Usb.cpp

103 lines
2.9 KiB
C++

#include "Usb.hpp"
#include <spdlog/spdlog.h>
#include <iomanip>
#include <iostream>
#include <optional>
namespace ptprnt::driver {
Usb::Usb() {
spdlog::debug("Usb constructing");
libusb_init(NULL);
}
Usb::~Usb() {
spdlog::debug("Usb destructing");
}
std::optional<std::vector<UsbDevice>> Usb::getDevices() {
// TODO: wrap libUsbDevs in a smart pointer with custom destructor
// calling libusb_free_device_list
libusb_device** libUsbDevs;
libusb_device* libUsbDev;
struct libusb_device_descriptor libUsbDesc;
int ret, i = 0;
mDevices.clear();
if (0 == (ret = libusb_get_device_list(NULL, &libUsbDevs))) {
spdlog::error("Could not find any USB devices: {}",
libusb_error_name(ret));
return std::nullopt;
}
while ((libUsbDev = libUsbDevs[i++]) != NULL) {
UsbDevice newDev;
if ((ret = libusb_get_device_descriptor(libUsbDev, &libUsbDesc)) < 0) {
spdlog::error("failed to open device");
libusb_free_device_list(libUsbDevs, 1);
return std::nullopt;
}
newDev.vendorId = libUsbDesc.idVendor;
newDev.productId = libUsbDesc.idProduct;
newDev.device = libUsbDev;
newDev.hndl =
nullptr; // handle is only available after we opened the dev
mDevices.push_back(newDev);
}
libusb_free_device_list(libUsbDevs, 1);
return mDevices;
}
std::optional<UsbDevice> Usb::open(UsbDevice dev) {
libusb_device_handle* libUsbHandle = nullptr;
int ret = 0;
if ((ret = libusb_open(dev.device, &libUsbHandle) != 0)) {
spdlog::error("Could not open device {0:04X}:{1:04X}: {2}",
dev.vendorId, dev.productId, libusb_error_name(ret));
return std::nullopt;
}
// detach the device from the kernel if it is active
if ((ret = libusb_kernel_driver_active(libUsbHandle, 0)) == 1) {
if ((ret = libusb_detach_kernel_driver(libUsbHandle, 0)) != 0) {
spdlog::error(
"Could not detach kernel driver for device {0:04X}:{1:04X}: "
"{2}",
dev.vendorId, dev.productId, libusb_error_name(ret));
return std::nullopt;
}
}
// claim interface
if ((ret = libusb_claim_interface(libUsbHandle, 0)) != 0) {
spdlog::error(
"Could not claim interface {0:04X}:{1:04X}: "
"{2}",
dev.vendorId, dev.productId, libusb_error_name(ret));
}
dev.hndl = libUsbHandle;
return dev;
}
bool Usb::close(UsbDevice dev) {
int ret = 0;
if(0 != (ret = libusb_release_interface(dev.hndl, 0))) {
spdlog::error(
"Could not close USB device {0:04X}:{1:04X}: "
"{2}",
dev.vendorId, dev.productId, libusb_error_name(ret));
}
libusb_close(dev.hndl);
return true;
}
} // namespace ptprnt::driver