Implement open() and close() for Usb class, added a lot of TODO's
This commit is contained in:
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
@@ -1,9 +1,7 @@
|
|||||||
{
|
{
|
||||||
"clangd.arguments": [ "-log=verbose",
|
"C_Cpp.codeAnalysis.clangTidy.args":[
|
||||||
"-pretty",
|
"-extra-arg=-std=c++17"
|
||||||
"--background-index",
|
],
|
||||||
"--compile-commands-dir=${workspaceFolder}/builddir"
|
|
||||||
],
|
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"cctype": "cpp",
|
"cctype": "cpp",
|
||||||
"clocale": "cpp",
|
"clocale": "cpp",
|
||||||
@@ -82,6 +80,7 @@
|
|||||||
"any": "cpp",
|
"any": "cpp",
|
||||||
"regex": "cpp",
|
"regex": "cpp",
|
||||||
"future": "cpp",
|
"future": "cpp",
|
||||||
"charconv": "cpp"
|
"charconv": "cpp",
|
||||||
|
"*.ipp": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -7,6 +7,8 @@ namespace ptprnt::driver {
|
|||||||
struct info {
|
struct info {
|
||||||
std::string name{""};
|
std::string name{""};
|
||||||
std::string version{""};
|
std::string version{""};
|
||||||
|
uint32_t busNo{0};
|
||||||
|
uint32_t flags{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ptprnt::driver
|
} // namespace ptprnt::driver
|
@@ -12,6 +12,8 @@ class IUsb {
|
|||||||
virtual ~IUsb() = default;
|
virtual ~IUsb() = default;
|
||||||
|
|
||||||
virtual std::optional<std::vector<UsbDevice>> getDevices() = 0;
|
virtual std::optional<std::vector<UsbDevice>> getDevices() = 0;
|
||||||
|
virtual std::optional<UsbDevice> open(UsbDevice) = 0;
|
||||||
|
virtual bool close(UsbDevice) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ptprnt::driver
|
} // namespace ptprnt::driver
|
@@ -23,6 +23,7 @@ class P700Driver : public IDriver {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<Usb> mUsbDriver{0};
|
std::shared_ptr<Usb> mUsbDriver{0};
|
||||||
UsbDevice mUsbDev{0};
|
UsbDevice mUsbDev{0};
|
||||||
|
driver::info mInfo{};
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
};
|
};
|
||||||
|
@@ -10,7 +10,7 @@ namespace ptprnt::printer {
|
|||||||
|
|
||||||
class P700Printer : public IPrinter {
|
class P700Printer : public IPrinter {
|
||||||
public:
|
public:
|
||||||
P700Printer(std::unique_ptr<driver::P700Driver> driver);
|
P700Printer(std::shared_ptr<driver::P700Driver> driver);
|
||||||
~P700Printer() override;
|
~P700Printer() override;
|
||||||
|
|
||||||
printer::info getInfo() override;
|
printer::info getInfo() override;
|
||||||
@@ -19,7 +19,7 @@ class P700Printer : public IPrinter {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static info mPrinterInfo;
|
static info mPrinterInfo;
|
||||||
std::unique_ptr<driver::P700Driver> mDriver;
|
std::shared_ptr<driver::P700Driver> mDriver;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ptprnt::printer
|
} // namespace ptprnt::printer
|
@@ -1,8 +1,6 @@
|
|||||||
#include "IUsb.hpp"
|
#include "IUsb.hpp"
|
||||||
#include "UsbTypes.hpp"
|
#include "UsbTypes.hpp"
|
||||||
|
|
||||||
#include <libusb-1.0/libusb.h>
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace ptprnt::driver {
|
namespace ptprnt::driver {
|
||||||
@@ -13,9 +11,12 @@ class Usb : public IUsb {
|
|||||||
~Usb() override;
|
~Usb() override;
|
||||||
|
|
||||||
std::optional<std::vector<UsbDevice>> getDevices() override;
|
std::optional<std::vector<UsbDevice>> getDevices() override;
|
||||||
|
std::optional<UsbDevice> open(UsbDevice) override;
|
||||||
|
bool close(UsbDevice) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// TODO: This should be a std::map with handles & locking on access
|
||||||
std::vector<UsbDevice> mDevices{};
|
std::vector<UsbDevice> mDevices{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ptprnt::driver
|
} // namespace ptprnt::driver
|
||||||
|
@@ -8,7 +8,7 @@ namespace ptprnt::driver {
|
|||||||
struct UsbDevice {
|
struct UsbDevice {
|
||||||
uint16_t vendorId{0};
|
uint16_t vendorId{0};
|
||||||
uint16_t productId{0};
|
uint16_t productId{0};
|
||||||
libusb_device* dev{nullptr};
|
libusb_device* device{nullptr};
|
||||||
libusb_device_handle* hndl{nullptr};
|
libusb_device_handle* hndl{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -26,15 +26,24 @@ P700Driver::~P700Driver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
driver::info P700Driver::getInfo() {
|
driver::info P700Driver::getInfo() {
|
||||||
return driver::info{};
|
return mInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool P700Driver::open() {
|
bool P700Driver::open() {
|
||||||
return false;
|
auto maybeUsbDev = mUsbDriver->open(mUsbDev);
|
||||||
|
if(!maybeUsbDev.has_value()) {
|
||||||
|
spdlog::error("Can't open P700 printer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mUsbDev = maybeUsbDev.value();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool P700Driver::close() {
|
bool P700Driver::close() {
|
||||||
return false;
|
if(!mUsbDriver->close(mUsbDev)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool P700Driver::command() {
|
bool P700Driver::command() {
|
||||||
@@ -49,6 +58,8 @@ bool P700Driver::init() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: There is the possibility, that two printers with the same ID are connected
|
||||||
|
// We have to take that into account
|
||||||
auto devIt =
|
auto devIt =
|
||||||
std::find_if(devs.value().begin(), devs.value().end(), [=](auto dev) {
|
std::find_if(devs.value().begin(), devs.value().end(), [=](auto dev) {
|
||||||
return mUsbDev.vendorId == dev.vendorId &&
|
return mUsbDev.vendorId == dev.vendorId &&
|
||||||
|
@@ -5,8 +5,9 @@
|
|||||||
|
|
||||||
namespace ptprnt::printer {
|
namespace ptprnt::printer {
|
||||||
|
|
||||||
P700Printer::P700Printer(std::unique_ptr<driver::P700Driver> driver) {
|
P700Printer::P700Printer(std::shared_ptr<driver::P700Driver> driver) {
|
||||||
if (!driver->open()) {
|
mDriver = std::move(driver);
|
||||||
|
if (!mDriver->open()) {
|
||||||
throw std::invalid_argument("Could not open driver!");
|
throw std::invalid_argument("Could not open driver!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
78
src/Usb.cpp
78
src/Usb.cpp
@@ -17,31 +17,87 @@ Usb::~Usb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<UsbDevice>> Usb::getDevices() {
|
std::optional<std::vector<UsbDevice>> Usb::getDevices() {
|
||||||
libusb_device** devs;
|
// TODO: wrap libUsbDevs in a smart pointer with custom destructor
|
||||||
libusb_device* dev;
|
// calling libusb_free_device_list
|
||||||
struct libusb_device_descriptor desc;
|
libusb_device** libUsbDevs;
|
||||||
int r, i = 0;
|
libusb_device* libUsbDev;
|
||||||
|
struct libusb_device_descriptor libUsbDesc;
|
||||||
|
int ret, i = 0;
|
||||||
|
|
||||||
mDevices.clear();
|
mDevices.clear();
|
||||||
|
|
||||||
libusb_get_device_list(NULL, &devs);
|
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 ((dev = devs[i++]) != NULL) {
|
while ((libUsbDev = libUsbDevs[i++]) != NULL) {
|
||||||
UsbDevice newDev;
|
UsbDevice newDev;
|
||||||
|
|
||||||
if ((r = libusb_get_device_descriptor(dev, &desc)) < 0) {
|
if ((ret = libusb_get_device_descriptor(libUsbDev, &libUsbDesc)) < 0) {
|
||||||
spdlog::error("failed to open device");
|
spdlog::error("failed to open device");
|
||||||
libusb_free_device_list(devs, 1);
|
libusb_free_device_list(libUsbDevs, 1);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
newDev.vendorId = desc.idVendor;
|
newDev.vendorId = libUsbDesc.idVendor;
|
||||||
newDev.productId = desc.idProduct;
|
newDev.productId = libUsbDesc.idProduct;
|
||||||
|
newDev.device = libUsbDev;
|
||||||
|
newDev.hndl =
|
||||||
|
nullptr; // handle is only available after we opened the dev
|
||||||
mDevices.push_back(newDev);
|
mDevices.push_back(newDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libusb_free_device_list(libUsbDevs, 1);
|
||||||
return mDevices;
|
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
|
} // namespace ptprnt::driver
|
@@ -25,8 +25,8 @@ int main(int argc, char** argv) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto driver = std::make_unique<driver::P700Driver>(usb);
|
auto driver = std::make_shared<driver::P700Driver>(usb);
|
||||||
//auto printer = std::make_unique<printer::P700Printer>(std::move(driver));
|
auto printer = std::make_unique<printer::P700Printer>(std::move(driver));
|
||||||
//printer::info info = printer->getInfo();
|
//printer::info info = printer->getInfo();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user