From a718fe6e4ff70b4d98d14b5e16972189a050f3de Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Sat, 5 Jul 2025 19:33:01 -0500 Subject: [PATCH 1/8] DXSpot for Flex Radio Added the option to send spots to Flex Radio's using HamLib - 'SmartSDR Slice' rigs. --- rig/drivers/HamlibRigDrv.cpp | 68 +++++++++++++++++++++++++++++++++--- rig/drivers/HamlibRigDrv.h | 4 +-- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index 555a9b12..aba481b6 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -5,6 +5,7 @@ #include "core/debug.h" #include "rig/macros.h" #include "data/SerialPort.h" +#include "data/Data.h" #ifndef HAMLIB_FILPATHLEN #define HAMLIB_FILPATHLEN FILPATHLEN @@ -90,7 +91,7 @@ RigCaps HamlibRigDrv::getCaps(int model) const struct rig_caps *caps = rig_get_caps(model); RigCaps ret; - + qWarning() << "HamLib Model Name" << caps->model_name; ret.isNetworkOnly = (model == RIG_MODEL_NETRIGCTL); ret.needPolling = true; @@ -107,6 +108,11 @@ RigCaps HamlibRigDrv::getCaps(int model) ret.canGetPTT = ( caps->get_ptt ); ret.canSendMorse = ( caps->send_morse != nullptr ); + if(std::strstr(caps->model_name,"SmartSDR Slice") != nullptr) + { + ret.canProcessDXSpot = true; + } + if ( ret.isNetworkOnly ) { #if ( HAMLIBVERSION_MAJOR == 4 && ( HAMLIBVERSION_MINOR == 2 || HAMLIBVERSION_MINOR == 3 ) ) @@ -246,7 +252,15 @@ bool HamlibRigDrv::open() int status = rig_open(rig); - if ( !isRigRespOK(status, tr("Rig Open Error"), false) ) + rigStartTime = QTime::currentTime(); + + if (status != RIG_OK) { + qWarning() << "Initial open failed, retrying..."; + QThread::sleep(1); // optional + status = rig_open(rig); + } + + if (!isRigRespOK(status, tr("Rig Open Error"), false)) return false; qCDebug(runtime) << "Rig Open - OK"; @@ -495,13 +509,52 @@ void HamlibRigDrv::stopTimers() errorTimer.stop(); } -void HamlibRigDrv::sendDXSpot(const DxSpot &) +void HamlibRigDrv::sendDXSpot(const DxSpot &spot) { FCT_IDENTIFICATION; + if (!rig || !opened || currFreq == 0) { + qCWarning(runtime) << "Rig is not active"; + return; + } - // no action + QString freqStr = QString::number(spot.freq, 'f', 3); + QString call = spot.callsign.trimmed(); + + QColor spotColor = Data::statusToColor(spot.status, spot.dupeCount, QColor(187,194,195)); + + SmartSDRSpotCounter = SmartSDRSpotCounter + 1; + QString command = QString("C%1|spot add rx_freq=%2 callsign=%3 color=%4 source=QLog timestamp=%5 lifetime_seconds=3600 priority=4\n") + .arg(SmartSDRSpotCounter) + .arg(freqStr) + .arg(call.toUpper()) + .arg(spotColor.name(QColor::HexArgb).toUpper()) + .arg(spot.dateTime.toSecsSinceEpoch()); + + qWarning() << "Sending DX Spot command:" << command; + + QByteArray cmdBytes = command.toUtf8(); + unsigned char terminator = '\n'; + const unsigned char* dataPtr = reinterpret_cast(cmdBytes.constData()); + + int status = rig_send_raw( + rig, + dataPtr, + cmdBytes.length(), + NULL, + 0, + &terminator + ); + + if (status != RIG_OK) { + qCDebug(runtime) << "rig_send_raw failed:" << status; + qCDebug(runtime) << hamlibErrorString(status); + } else { + qCDebug(runtime) << "DX Spot sent successfully"; + } } + + void HamlibRigDrv::checkChanges() { FCT_IDENTIFICATION; @@ -965,6 +1018,13 @@ bool HamlibRigDrv::isRigRespOK(int errorStatus, qCDebug(function_parameters) << errorStatus << errorName << emitError; + // Inside isRigRespOK + if (errorStatus == -6 && QTime::currentTime() < rigStartTime.addSecs(5)) { + qCDebug(runtime) << "Suppressed transient error: Feature not available during rig startup"; + return true; + } + + if ( errorStatus == RIG_OK ) { if ( emitError ) diff --git a/rig/drivers/HamlibRigDrv.h b/rig/drivers/HamlibRigDrv.h index 212a1d6d..7aeeecca 100644 --- a/rig/drivers/HamlibRigDrv.h +++ b/rig/drivers/HamlibRigDrv.h @@ -76,11 +76,11 @@ private slots: serial_handshake_e stringToHamlibFlowControl(const QString &in_flowcontrol); serial_parity_e stringToHamlibParity(const QString &in_parity); QString hamlibErrorString(int); - + QTime rigStartTime; RIG* rig; QTimer timer; QTimer errorTimer; - + int SmartSDRSpotCounter; bool forceSendState; bool currPTT; double currFreq; From 26201576941fa5c610eb1b21f0495bd101e94827 Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Sun, 6 Jul 2025 10:16:54 -0500 Subject: [PATCH 2/8] shortenTimeout --- QLog.pro | 4 +-- rig/drivers/HamlibRigDrv.cpp | 70 +++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/QLog.pro b/QLog.pro index 89536319..916f6cde 100644 --- a/QLog.pro +++ b/QLog.pro @@ -476,8 +476,8 @@ macx: { INSTALLS += target } - INCLUDEPATH += /usr/local/include /opt/homebrew/include - LIBS += -L/usr/local/lib -L/opt/homebrew/lib -lhamlib -lsqlite3 + INCLUDEPATH += /usr/local/include /opt/homebrew/include /opt/local/include + LIBS += -L/usr/local/lib -L/opt/homebrew/lib -lhamlib -lsqlite3 -L/opt/local/lib equals(QT_MAJOR_VERSION, 6): LIBS += -lqt6keychain equals(QT_MAJOR_VERSION, 5): LIBS += -lqt5keychain DISTFILES += diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index aba481b6..abc72f52 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -517,40 +517,44 @@ void HamlibRigDrv::sendDXSpot(const DxSpot &spot) return; } - QString freqStr = QString::number(spot.freq, 'f', 3); - QString call = spot.callsign.trimmed(); - - QColor spotColor = Data::statusToColor(spot.status, spot.dupeCount, QColor(187,194,195)); - - SmartSDRSpotCounter = SmartSDRSpotCounter + 1; - QString command = QString("C%1|spot add rx_freq=%2 callsign=%3 color=%4 source=QLog timestamp=%5 lifetime_seconds=3600 priority=4\n") - .arg(SmartSDRSpotCounter) - .arg(freqStr) - .arg(call.toUpper()) - .arg(spotColor.name(QColor::HexArgb).toUpper()) - .arg(spot.dateTime.toSecsSinceEpoch()); - - qWarning() << "Sending DX Spot command:" << command; - - QByteArray cmdBytes = command.toUtf8(); - unsigned char terminator = '\n'; - const unsigned char* dataPtr = reinterpret_cast(cmdBytes.constData()); - - int status = rig_send_raw( - rig, - dataPtr, - cmdBytes.length(), - NULL, - 0, - &terminator - ); - - if (status != RIG_OK) { - qCDebug(runtime) << "rig_send_raw failed:" << status; - qCDebug(runtime) << hamlibErrorString(status); - } else { - qCDebug(runtime) << "DX Spot sent successfully"; + if(std::strstr(rig->caps->model_name,"SmartSDR Slice") != nullptr) + { + QString freqStr = QString::number(spot.freq, 'f', 3); + QString call = spot.callsign.trimmed(); + + QColor spotColor = Data::statusToColor(spot.status, spot.dupeCount, QColor(187,194,195)); + + SmartSDRSpotCounter = SmartSDRSpotCounter + 1; + QString command = QString("C%1|spot add rx_freq=%2 callsign=%3 color=%4 source=QLog timestamp=%5 lifetime_seconds=300 priority=4\n") + .arg(SmartSDRSpotCounter) + .arg(freqStr) + .arg(call.toUpper()) + .arg(spotColor.name(QColor::HexArgb).toUpper()) + .arg(spot.dateTime.toSecsSinceEpoch()); + + qWarning() << "Sending DX Spot command:" << command; + + QByteArray cmdBytes = command.toUtf8(); + unsigned char terminator = '\n'; + const unsigned char* dataPtr = reinterpret_cast(cmdBytes.constData()); + + int status = rig_send_raw( + rig, + dataPtr, + cmdBytes.length(), + NULL, + 0, + &terminator + ); + + if (status != RIG_OK) { + qCDebug(runtime) << "rig_send_raw failed:" << status; + qCDebug(runtime) << hamlibErrorString(status); + } else { + qCDebug(runtime) << "DX Spot sent successfully"; + } } + return; } From 68e5e5cd52d42704c88a372b06d2d3c1c20be54d Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Tue, 8 Jul 2025 12:57:18 -0500 Subject: [PATCH 3/8] HamLib Version Check Added to make sure using version 4.5 of hamlib or newer. --- rig/drivers/HamlibRigDrv.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index abc72f52..449a9f7c 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -108,8 +108,7 @@ RigCaps HamlibRigDrv::getCaps(int model) ret.canGetPTT = ( caps->get_ptt ); ret.canSendMorse = ( caps->send_morse != nullptr ); - if(std::strstr(caps->model_name,"SmartSDR Slice") != nullptr) - { + if (QString::fromLatin1(caps->model_name).contains("SmartSDR Slice", Qt::CaseInsensitive)) { ret.canProcessDXSpot = true; } @@ -512,12 +511,12 @@ void HamlibRigDrv::stopTimers() void HamlibRigDrv::sendDXSpot(const DxSpot &spot) { FCT_IDENTIFICATION; + if (!rig || !opened || currFreq == 0) { qCWarning(runtime) << "Rig is not active"; return; } - - if(std::strstr(rig->caps->model_name,"SmartSDR Slice") != nullptr) + if (QString::fromLatin1(rig->caps->model_name).contains("SmartSDR Slice", Qt::CaseInsensitive)) { QString freqStr = QString::number(spot.freq, 'f', 3); QString call = spot.callsign.trimmed(); @@ -534,6 +533,8 @@ void HamlibRigDrv::sendDXSpot(const DxSpot &spot) qWarning() << "Sending DX Spot command:" << command; +#if (HAMLIBVERSION_MAJOR >= 4 && HAMLIBVERSION_MINOR >= 5 ) + QByteArray cmdBytes = command.toUtf8(); unsigned char terminator = '\n'; const unsigned char* dataPtr = reinterpret_cast(cmdBytes.constData()); @@ -542,7 +543,7 @@ void HamlibRigDrv::sendDXSpot(const DxSpot &spot) rig, dataPtr, cmdBytes.length(), - NULL, + nullptr, 0, &terminator ); @@ -553,8 +554,11 @@ void HamlibRigDrv::sendDXSpot(const DxSpot &spot) } else { qCDebug(runtime) << "DX Spot sent successfully"; } + +#else + qCWarning(runtime) << "Hamlib version does not support rig_send_raw. DX Spot not sent."; +#endif } - return; } From 44e54f084c4bb6202ffe2b97ef1ad1b5400475e5 Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Thu, 10 Jul 2025 11:03:17 -0500 Subject: [PATCH 4/8] Create entitlements.xml --- entitlements.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 entitlements.xml diff --git a/entitlements.xml b/entitlements.xml new file mode 100644 index 00000000..36d136cf --- /dev/null +++ b/entitlements.xml @@ -0,0 +1,11 @@ + + + + +com.apple.security.cs.allow-unsigned-executable-memory +com.apple.security.cs.disable-library-validation +com.apple.security.cs.allow-jit +com.apple.security.cs.disable-executable-page-protection + + + From 83d4cf2c5c7279441be5b22c0abc3fd521e96472 Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Thu, 10 Jul 2025 11:20:25 -0500 Subject: [PATCH 5/8] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index caf25472..56048a94 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -24,7 +24,9 @@ jobs: brew update brew upgrade || true brew install qt6 + brew install qt6-webengine brew link qt6 --force + brew link qt6-webengine --force brew install hamlib brew link hamlib --force brew install qtkeychain @@ -45,7 +47,7 @@ jobs: run: | mkdir build cd build - qmake -config release .. + /opt/homebrew/opt/qt6/bin/qmake -config release .. make -j4 - name: Build dmg run: | From 382179bdc84272358ee84fc531cd1e847d028bf7 Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Wed, 16 Jul 2025 10:38:32 -0500 Subject: [PATCH 6/8] a little clean up. --- rig/drivers/HamlibRigDrv.cpp | 10 ---------- rig/drivers/HamlibRigDrv.h | 1 - 2 files changed, 11 deletions(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index 449a9f7c..9f17a986 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -91,7 +91,6 @@ RigCaps HamlibRigDrv::getCaps(int model) const struct rig_caps *caps = rig_get_caps(model); RigCaps ret; - qWarning() << "HamLib Model Name" << caps->model_name; ret.isNetworkOnly = (model == RIG_MODEL_NETRIGCTL); ret.needPolling = true; @@ -251,8 +250,6 @@ bool HamlibRigDrv::open() int status = rig_open(rig); - rigStartTime = QTime::currentTime(); - if (status != RIG_OK) { qWarning() << "Initial open failed, retrying..."; QThread::sleep(1); // optional @@ -1026,13 +1023,6 @@ bool HamlibRigDrv::isRigRespOK(int errorStatus, qCDebug(function_parameters) << errorStatus << errorName << emitError; - // Inside isRigRespOK - if (errorStatus == -6 && QTime::currentTime() < rigStartTime.addSecs(5)) { - qCDebug(runtime) << "Suppressed transient error: Feature not available during rig startup"; - return true; - } - - if ( errorStatus == RIG_OK ) { if ( emitError ) diff --git a/rig/drivers/HamlibRigDrv.h b/rig/drivers/HamlibRigDrv.h index 7aeeecca..6c835e45 100644 --- a/rig/drivers/HamlibRigDrv.h +++ b/rig/drivers/HamlibRigDrv.h @@ -76,7 +76,6 @@ private slots: serial_handshake_e stringToHamlibFlowControl(const QString &in_flowcontrol); serial_parity_e stringToHamlibParity(const QString &in_parity); QString hamlibErrorString(int); - QTime rigStartTime; RIG* rig; QTimer timer; QTimer errorTimer; From bcf3c902b3cbc30b004fec53dfc29749a4b4501c Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Wed, 16 Jul 2025 10:43:12 -0500 Subject: [PATCH 7/8] Missed this one --- rig/drivers/HamlibRigDrv.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index 9f17a986..c52831f2 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -250,12 +250,6 @@ bool HamlibRigDrv::open() int status = rig_open(rig); - if (status != RIG_OK) { - qWarning() << "Initial open failed, retrying..."; - QThread::sleep(1); // optional - status = rig_open(rig); - } - if (!isRigRespOK(status, tr("Rig Open Error"), false)) return false; From 5887d932b18cb308184f9041ff91187cbd87ab2a Mon Sep 17 00:00:00 2001 From: Michael Morgan <84428382+aa5sh@users.noreply.github.com> Date: Wed, 16 Jul 2025 11:32:22 -0500 Subject: [PATCH 8/8] Trying to cleanup other files --- .github/workflows/macOSBuild.yml | 4 +--- QLog.pro | 4 ++-- entitlements.xml | 11 ----------- 3 files changed, 3 insertions(+), 16 deletions(-) delete mode 100644 entitlements.xml diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 56048a94..caf25472 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -24,9 +24,7 @@ jobs: brew update brew upgrade || true brew install qt6 - brew install qt6-webengine brew link qt6 --force - brew link qt6-webengine --force brew install hamlib brew link hamlib --force brew install qtkeychain @@ -47,7 +45,7 @@ jobs: run: | mkdir build cd build - /opt/homebrew/opt/qt6/bin/qmake -config release .. + qmake -config release .. make -j4 - name: Build dmg run: | diff --git a/QLog.pro b/QLog.pro index 916f6cde..89536319 100644 --- a/QLog.pro +++ b/QLog.pro @@ -476,8 +476,8 @@ macx: { INSTALLS += target } - INCLUDEPATH += /usr/local/include /opt/homebrew/include /opt/local/include - LIBS += -L/usr/local/lib -L/opt/homebrew/lib -lhamlib -lsqlite3 -L/opt/local/lib + INCLUDEPATH += /usr/local/include /opt/homebrew/include + LIBS += -L/usr/local/lib -L/opt/homebrew/lib -lhamlib -lsqlite3 equals(QT_MAJOR_VERSION, 6): LIBS += -lqt6keychain equals(QT_MAJOR_VERSION, 5): LIBS += -lqt5keychain DISTFILES += diff --git a/entitlements.xml b/entitlements.xml deleted file mode 100644 index 36d136cf..00000000 --- a/entitlements.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - -com.apple.security.cs.allow-unsigned-executable-memory -com.apple.security.cs.disable-library-validation -com.apple.security.cs.allow-jit -com.apple.security.cs.disable-executable-page-protection - - -