diff --git a/src/controllers/bulk/bulkcontroller.cpp b/src/controllers/bulk/bulkcontroller.cpp index 4dd814b7e52..0e44462299f 100644 --- a/src/controllers/bulk/bulkcontroller.cpp +++ b/src/controllers/bulk/bulkcontroller.cpp @@ -172,6 +172,12 @@ int BulkController::open() { if (m_pReader != nullptr) { qCWarning(m_logBase) << "BulkReader already present for" << getName(); + } else if (m_pMapping && + !(m_pMapping->getDeviceDirection() & + LegacyControllerMapping::DeviceDirection::Incoming)) { + qDebug() << "The mapping for the bulk device" << getName() + << "doesn't require reading the data. Ignoring BulkReader " + "setup."; } else { m_pReader = new BulkReader(m_phandle, in_epaddr); m_pReader->setObjectName(QString("BulkReader %1").arg(getName())); @@ -195,10 +201,12 @@ int BulkController::close() { qCInfo(m_logBase) << "Shutting down USB Bulk device" << getName(); // Stop the reading thread - if (m_pReader == nullptr) { + if (m_pReader == nullptr && + m_pMapping->getDeviceDirection() & + LegacyControllerMapping::DeviceDirection::Incoming) { qCWarning(m_logBase) << "BulkReader not present for" << getName() << "yet the device is open!"; - } else { + } else if (m_pReader) { disconnect(m_pReader, &BulkReader::incomingData, this, &BulkController::receive); m_pReader->stop(); qCInfo(m_logBase) << " Waiting on reader to finish"; @@ -230,6 +238,14 @@ void BulkController::send(const QList& data, unsigned int length) { } void BulkController::sendBytes(const QByteArray& data) { + VERIFY_OR_DEBUG_ASSERT(!m_pMapping || + m_pMapping->getDeviceDirection() & + LegacyControllerMapping::DeviceDirection::Outgoing) { + qDebug() << "The mapping for the bulk device" << getName() + << "doesn't require sending data. Ignoring sending request."; + return; + } + int ret; int transferred; diff --git a/src/controllers/legacycontrollermapping.h b/src/controllers/legacycontrollermapping.h index ca0e369b96c..b0a18ffd8e9 100644 --- a/src/controllers/legacycontrollermapping.h +++ b/src/controllers/legacycontrollermapping.h @@ -15,7 +15,8 @@ class LegacyControllerMapping { public: LegacyControllerMapping() - : m_bDirty(false) { + : m_bDirty(false), + m_deviceDirection(DeviceDirection::Bidirectionnal) { } virtual ~LegacyControllerMapping() = default; @@ -32,6 +33,19 @@ class LegacyControllerMapping { bool builtin; }; + // TODO (xxx): this is a temporary solution to address devices that don't + // support and need bidirectional communication and lead to + // polling/performance issues. The proper solution would involve refactoring + // the bulk integration to perform a better endpoint capability discovery + // and let Mixxx decide communication direction depending of the hardware + // capabilities + enum class DeviceDirection : uint8_t { + Outgoing = 0x1, + Incoming = 0x2, + Bidirectionnal = 0x3 + }; + Q_DECLARE_FLAGS(DeviceDirections, DeviceDirection) + /// Adds a script file to the list of controller scripts for this mapping. /// @param filename Name of the script file to add /// @param functionprefix The script's function prefix (or empty string) @@ -54,6 +68,14 @@ class LegacyControllerMapping { return m_scripts; } + inline void setDeviceDirection(DeviceDirections aDeviceDirection) { + m_deviceDirection = aDeviceDirection; + } + + inline DeviceDirections getDeviceDirection() const { + return m_deviceDirection; + } + inline void setDirty(bool bDirty) { m_bDirty = bDirty; } @@ -192,4 +214,5 @@ class LegacyControllerMapping { QString m_mixxxVersion; QList m_scripts; + DeviceDirections m_deviceDirection; }; diff --git a/src/controllers/legacycontrollermappingfilehandler.cpp b/src/controllers/legacycontrollermappingfilehandler.cpp index 754c972ba78..c3e9868d665 100644 --- a/src/controllers/legacycontrollermappingfilehandler.cpp +++ b/src/controllers/legacycontrollermappingfilehandler.cpp @@ -131,6 +131,17 @@ void LegacyControllerMappingFileHandler::addScriptFilesToMapping( QString deviceId = controller.attribute("id", ""); mapping->setDeviceId(deviceId); + // See TODO in LegacyControllerMapping::DeviceDirection - `direction` should + // only be used as a workaround till the bulk integration gets refactored + QString deviceDirection = controller.attribute("direction", "").toLower(); + if (deviceDirection == "in") { + mapping->setDeviceDirection(LegacyControllerMapping::DeviceDirection::Incoming); + } else if (deviceDirection == "out") { + mapping->setDeviceDirection(LegacyControllerMapping::DeviceDirection::Outgoing); + } else { + mapping->setDeviceDirection(LegacyControllerMapping::DeviceDirection::Bidirectionnal); + } + // Build a list of script files to load QDomElement scriptFile = controller.firstChildElement("scriptfiles") .firstChildElement("file");