#pragma once #include "ThreadLogging.h" #include "UsbContext.h" #include "UsbEndPoint.h" #include #include #include "UsbWriteTransfer.h" namespace Incart::Usb { template class UsbCmdWriter final: public UsbEndPoint { QMutex m_mutex; // только для m_data std::vector m_data; // сюда мы копируем данные для передачи std::vector m_transferBuffer; public: UsbCmdWriter(const QString& name, UsbContext* usbContext) : UsbEndPoint(name, usbContext, EP) { } bool readyData() { QMutexLocker locker(&m_mutex); return (m_data.size() > 0); } void setData(std::vector&& data) { QMutexLocker locker(&m_mutex); m_data = std::move(data); } std::vector getData() { QMutexLocker locker(&m_mutex); return m_data; } void clrData() { QMutexLocker locker(&m_mutex); m_data.clear(); // освобождаем данные } void transfer() { int32_t lastTransferStatus = m_usbContext->getLastTransferStatus(); if (lastTransferStatus != LIBUSB_TRANSFER_COMPLETED) { m_usbContext->logError(std::string(__PRETTY_FUNCTION__) + " " + m_name.toStdString() + " has error " + std::to_string(lastTransferStatus)); return; } if (getIsTransferred()) { m_usbContext->logError(std::string(__PRETTY_FUNCTION__) + " " + m_name.toStdString() + " is transfered"); m_usbContext->setLastTransferStatus(LIBUSB_ERROR_BUSY); return; } m_transferBuffer = getData(); // копируем данные clrData(); // освобождаем данные libusb_fill_bulk_transfer(m_transfer, m_usbContext->getDeviceHandle(), EP, &m_transferBuffer[0], static_cast(m_transferBuffer.size()), &UsbWriteTransfer>::callback , this, 250); int result = libusb_submit_transfer(m_transfer); if (result != LIBUSB_SUCCESS) { m_usbContext->logError(std::string(__PRETTY_FUNCTION__) + " " + m_name.toStdString() + " transfer error: " + std::to_string(result) + " " + libusb_strerror(result)); setIsTransferred(false); m_usbContext->setLastTransferStatus(result); } else { setIsTransferred(true); } } void restart() { clrData(); } bool exe() { if (readyData()) { transfer(); return true; } return false; } }; } // namespace Incart::Usb