/* ptrnt - print labels on linux Copyright (C) 2023 Moritz Martinius This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libusbwrap/UsbDeviceFactory.hpp" #include #include #include #include #include #include "libusb.h" #include "libusbwrap/UsbDevice.hpp" #include "libusbwrap/interface/IUsbDevice.hpp" namespace libusbwrap { UsbDeviceFactory::~UsbDeviceFactory() { if (mLibusbCtx) { libusb_exit(mLibusbCtx); } }; std::vector> UsbDeviceFactory::findAllDevices() { refreshDeviceList(); return buildMaskedDeviceVector(0x0, 0x0, 0x0, 0x0); } std::vector> UsbDeviceFactory::findDevices(uint16_t vid, uint16_t pid) { refreshDeviceList(); return buildMaskedDeviceVector(LIBUSB_BITMASK_ALL, LIBUSB_BITMASK_ALL, vid, pid); } ssize_t UsbDeviceFactory::refreshDeviceList() { libusb_device** list{nullptr}; ssize_t ret = libusb_get_device_list(mLibusbCtx, &list); mLibusbDeviceList.clear(); if (ret < 0) { spdlog::error("Error enumarating USB devices"); } else if (ret == 0) { spdlog::warn("No USB devices found"); } for (ssize_t i = 0; i < ret; i++) { mLibusbDeviceList.emplace_back(list[i]); } libusb_free_device_list(list, false); return ret; } std::vector> UsbDeviceFactory::buildMaskedDeviceVector(uint16_t vidMask, uint16_t pidMask, uint16_t vid, uint16_t pid) { std::vector> matchedDevices; // see libusb/examples/listdevs.c for (auto& currDev : mLibusbDeviceList) { struct libusb_device_descriptor currDevDesc {}; int ret = libusb_get_device_descriptor(currDev.get(), &currDevDesc); if (ret < 0) { continue; } if (((currDevDesc.idVendor & vidMask) == vid) && ((currDevDesc.idProduct & pidMask) == pid)) { matchedDevices.push_back(std::make_unique(mLibusbCtx, std::move(currDev))); } } return matchedDevices; } bool UsbDeviceFactory::init() { auto err = libusb_init(&mLibusbCtx); if (err != (int)Error::SUCCESS) { spdlog::error("Could not intialize libusb"); return false; } return true; } } // namespace libusbwrap