From c9300f4d865968d017626c3617350965e01ad465 Mon Sep 17 00:00:00 2001 From: M0VSE Date: Tue, 11 Apr 2023 20:25:29 +0100 Subject: [PATCH] Add linux USB hotplug --- usbcontroller.cpp | 4 +-- wfmain.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++---- wfmain.h | 21 ++++++++++++++-- wfview.pro | 2 +- 4 files changed, 79 insertions(+), 10 deletions(-) diff --git a/usbcontroller.cpp b/usbcontroller.cpp index 6a2abb5..92d5061 100644 --- a/usbcontroller.cpp +++ b/usbcontroller.cpp @@ -140,7 +140,7 @@ void usbController::run() return; } -#ifdef Q_OS_WIN +#ifdef USB_HOTPLUG qDebug(logUsbControl()) << "Re-enumerating USB devices due to program startup or hotplug event"; #endif @@ -452,7 +452,7 @@ void usbController::run() dataTimer->start(25); } -#ifndef Q_OS_WIN +#ifndef USB_HOTPLUG // Run the periodic timer to check for new devices QTimer::singleShot(2000, this, SLOT(run())); #endif diff --git a/wfmain.cpp b/wfmain.cpp index 6ef291a..2d62466 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -84,6 +84,7 @@ wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); haveRigCaps = false; @@ -169,17 +170,38 @@ wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode amTransmitting = false; + connect(ui->txPowerSlider, &QSlider::sliderMoved, + [&](int value) { + QToolTip::showText(QCursor::pos(), QString("%1").arg(value*100/255), nullptr); + }); + #if !defined(USB_CONTROLLER) ui->enableUsbChk->setVisible(false); ui->usbControllerBtn->setVisible(false); ui->usbControllersResetBtn->setVisible(false); ui->usbResetLbl->setVisible(false); +#else + #if defined(USB_HOTPLUG) && defined(Q_OS_LINUX) + uDev = udev_new(); + if (!uDev) + { + qInfo(logUsbControl()) << "Cannot register udev, hotplug of USB devices is not available"; + return; + } + uDevMonitor = udev_monitor_new_from_netlink(uDev, "udev"); + if (!uDevMonitor) + { + qInfo(logUsbControl()) << "Cannot register udev_monitor, hotplug of USB devices is not available"; + return; + } + int fd = udev_monitor_get_fd(uDevMonitor); + uDevNotifier = new QSocketNotifier(fd, QSocketNotifier::Read,this); + connect(uDevNotifier, SIGNAL(activated(int)), this, SLOT(uDevEvent())); + udev_monitor_enable_receiving(uDevMonitor); + #endif #endif - connect(ui->txPowerSlider, &QSlider::sliderMoved, - [&](int value) { - QToolTip::showText(QCursor::pos(), QString("%1").arg(value*100/255), nullptr); - }); + } @@ -214,6 +236,13 @@ wfmain::~wfmain() usbControllerThread->quit(); usbControllerThread->wait(); } + + if (uDevMonitor) + { + udev_monitor_unref(uDevMonitor); + udev_unref(uDev); + delete uDevNotifier; + } #endif } @@ -9569,12 +9598,15 @@ void wfmain::on_cwButton_clicked() } #ifdef USB_HOTPLUG + + +#ifdef Q_OS_WINDOWS bool wfmain::nativeEvent(const QByteArray& eventType, void* message, qintptr* result) { Q_UNUSED(eventType); Q_UNUSED(result); - if (prefs.enableUSBControllers) + if (QDateTime::currentMSecsSinceEpoch() > lastUsbNotify + 10) { static bool created = false; @@ -9602,6 +9634,7 @@ bool wfmain::nativeEvent(const QByteArray& eventType, void* message, qintptr* re case DBT_DEVICEARRIVAL: case DBT_DEVICEREMOVECOMPLETE: emit usbHotplug(); + lastUsbNotify = QDateTime::currentMSecsSinceEpoch(); break; case DBT_DEVNODES_CHANGED: break; @@ -9618,4 +9651,23 @@ bool wfmain::nativeEvent(const QByteArray& eventType, void* message, qintptr* re } return false; // Process native events as normal } + +#elif defined(Q_OS_LINUX) + +void wfmain::uDevEvent() +{ + udev_device *dev = udev_monitor_receive_device(uDevMonitor); + if (dev) + { + const char* action = udev_device_get_action(dev); + if (action && strcmp(action, "add") == 0 && QDateTime::currentMSecsSinceEpoch() > lastUsbNotify + 10) + { + emit usbHotplug(); + lastUsbNotify = QDateTime::currentMSecsSinceEpoch(); + } + udev_device_unref(dev); + } +} #endif +#endif + diff --git a/wfmain.h b/wfmain.h index dcf5225..0c912ce 100644 --- a/wfmain.h +++ b/wfmain.h @@ -68,6 +68,10 @@ #include #include #define USB_HOTPLUG + #elif defined(Q_OS_LINUX) + #include + #include + #define USB_HOTPLUG #endif #endif @@ -88,8 +92,13 @@ public: void handleLogText(QString text); #ifdef USB_HOTPLUG -protected: - virtual bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result); + #if defined(Q_OS_WIN) + protected: + virtual bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result); + #elif defined(Q_OS_LINUX) + private slots: + void uDevEvent(); + #endif #endif signals: @@ -1195,6 +1204,13 @@ private: QVector usbKnobs; usbDevMap usbDevices; QMutex usbMutex; + qint64 lastUsbNotify; + + #if defined (Q_OS_LINUX) + struct udev* uDev = nullptr; + struct udev_monitor* uDevMonitor = nullptr; + QSocketNotifier* uDevNotifier = nullptr; + #endif #endif dxClusterClient* cluster = Q_NULLPTR; @@ -1241,6 +1257,7 @@ Q_DECLARE_METATYPE(enum rptAccessTxRx) Q_DECLARE_METATYPE(struct rptrTone_t) Q_DECLARE_METATYPE(struct rptrAccessData_t) Q_DECLARE_METATYPE(enum usbFeatureType) +Q_DECLARE_METATYPE(enum cmds) //void (*wfmain::logthistext)(QString text) = NULL; diff --git a/wfview.pro b/wfview.pro index 245fc7c..a401d92 100644 --- a/wfview.pro +++ b/wfview.pro @@ -51,7 +51,7 @@ macx:DEFINES += __MACOSX_CORE__ !linux:HEADERS += ../rtaudio/RTAUdio.h !linux:INCLUDEPATH += ../rtaudio -linux:LIBS += -lpulse -lpulse-simple -lrtaudio -lpthread +linux:LIBS += -lpulse -lpulse-simple -lrtaudio -lpthread -ludev win32:INCLUDEPATH += ../portaudio/include !win32:LIBS += -lportaudio