From e36ab79b7acc38b661daa4bb22c4b5659cc6ca18 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 20 Sep 2020 01:06:50 +0200 Subject: [PATCH] PTT Feature: initial commit --- plugins/CMakeLists.txt | 1 + plugins/feature/CMakeLists.txt | 3 + plugins/feature/simpleptt/CMakeLists.txt | 56 +++ plugins/feature/simpleptt/simpleptt.cpp | 151 +++++++ plugins/feature/simpleptt/simpleptt.h | 119 ++++++ plugins/feature/simpleptt/simplepttgui.cpp | 372 ++++++++++++++++++ plugins/feature/simpleptt/simplepttgui.h | 93 +++++ plugins/feature/simpleptt/simplepttgui.ui | 327 +++++++++++++++ plugins/feature/simpleptt/simplepttplugin.cpp | 74 ++++ plugins/feature/simpleptt/simplepttplugin.h | 46 +++ plugins/feature/simpleptt/simplepttreport.cpp | 26 ++ plugins/feature/simpleptt/simplepttreport.h | 55 +++ .../feature/simpleptt/simplepttsettings.cpp | 85 ++++ plugins/feature/simpleptt/simplepttsettings.h | 41 ++ plugins/feature/simpleptt/simplepttworker.cpp | 209 ++++++++++ plugins/feature/simpleptt/simplepttworker.h | 106 +++++ 16 files changed, 1764 insertions(+) create mode 100644 plugins/feature/CMakeLists.txt create mode 100644 plugins/feature/simpleptt/CMakeLists.txt create mode 100644 plugins/feature/simpleptt/simpleptt.cpp create mode 100644 plugins/feature/simpleptt/simpleptt.h create mode 100644 plugins/feature/simpleptt/simplepttgui.cpp create mode 100644 plugins/feature/simpleptt/simplepttgui.h create mode 100644 plugins/feature/simpleptt/simplepttgui.ui create mode 100644 plugins/feature/simpleptt/simplepttplugin.cpp create mode 100644 plugins/feature/simpleptt/simplepttplugin.h create mode 100644 plugins/feature/simpleptt/simplepttreport.cpp create mode 100644 plugins/feature/simpleptt/simplepttreport.h create mode 100644 plugins/feature/simpleptt/simplepttsettings.cpp create mode 100644 plugins/feature/simpleptt/simplepttsettings.h create mode 100644 plugins/feature/simpleptt/simplepttworker.cpp create mode 100644 plugins/feature/simpleptt/simplepttworker.h diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 0a39be051..d3ab55f71 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -40,5 +40,6 @@ endif() add_subdirectory(channelrx) add_subdirectory(channeltx) +add_subdirectory(feature) add_subdirectory(samplesource) add_subdirectory(samplesink) diff --git a/plugins/feature/CMakeLists.txt b/plugins/feature/CMakeLists.txt new file mode 100644 index 000000000..40d228b3a --- /dev/null +++ b/plugins/feature/CMakeLists.txt @@ -0,0 +1,3 @@ +project(feature) + +add_subdirectory(simpleptt) diff --git a/plugins/feature/simpleptt/CMakeLists.txt b/plugins/feature/simpleptt/CMakeLists.txt new file mode 100644 index 000000000..8902dd59d --- /dev/null +++ b/plugins/feature/simpleptt/CMakeLists.txt @@ -0,0 +1,56 @@ +project(simpleptt) + +set(simpleptt_SOURCES + simpleptt.cpp + simplepttsettings.cpp + simplepttplugin.cpp + simplepttworker.cpp + simplepttreport.cpp +) + +set(simpleptt_HEADERS + simpleptt.h + simplepttsettings.h + simplepttplugin.h + simplepttworker.h + simplepttreport.h +) + +include_directories( + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client +) + +if(NOT SERVER_MODE) + set(simpleptt_SOURCES + ${simpleptt_SOURCES} + simplepttgui.cpp + simplepttgui.ui + ) + set(simpleptt_HEADERS + ${simpleptt_HEADERS} + simplepttgui.h + ) + + set(TARGET_NAME featuresimpleptt) + set(TARGET_LIB "Qt5::Widgets") + set(TARGET_LIB_GUI "sdrgui") + set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR}) +else() + set(TARGET_NAME featuresimplepttsrv) + set(TARGET_LIB "") + set(TARGET_LIB_GUI "") + set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) +endif() + +add_library(${TARGET_NAME} SHARED + ${simpleptt_SOURCES} +) + +target_link_libraries(${TARGET_NAME} + Qt5::Core + ${TARGET_LIB} + sdrbase + ${TARGET_LIB_GUI} +) + +install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER}) diff --git a/plugins/feature/simpleptt/simpleptt.cpp b/plugins/feature/simpleptt/simpleptt.cpp new file mode 100644 index 000000000..40d799bd5 --- /dev/null +++ b/plugins/feature/simpleptt/simpleptt.cpp @@ -0,0 +1,151 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "dsp/dspengine.h" + +#include "simplepttworker.h" +#include "simpleptt.h" + +MESSAGE_CLASS_DEFINITION(SimplePTT::MsgConfigureSimplePTT, Message) +MESSAGE_CLASS_DEFINITION(SimplePTT::MsgPTT, Message) +MESSAGE_CLASS_DEFINITION(SimplePTT::MsgStartStop, Message) + +const QString SimplePTT::m_featureIdURI = "sdrangel.feature.simpleptt"; +const QString SimplePTT::m_featureId = "SimplePTT"; + +SimplePTT::SimplePTT(WebAPIAdapterInterface *webAPIAdapterInterface) : + Feature(m_featureIdURI, webAPIAdapterInterface) +{ + setObjectName(m_featureId); + m_worker = new SimplePTTWorker(webAPIAdapterInterface); + m_state = StIdle; + m_errorMessage = "SimplePTT error"; +} + +SimplePTT::~SimplePTT() +{ + if (m_worker->isRunning()) { + stop(); + } + + delete m_worker; +} + +void SimplePTT::start() +{ + qDebug("SimplePTT::start"); + + m_worker->reset(); + m_worker->setMessageQueueToGUI(getMessageQueueToGUI()); + bool ok = m_worker->startWork(); + m_state = ok ? StRunning : StError; + m_thread.start(); + + SimplePTTWorker::MsgConfigureSimplePTTWorker *msg = SimplePTTWorker::MsgConfigureSimplePTTWorker::create(m_settings, true); + m_worker->getInputMessageQueue()->push(msg); +} + +void SimplePTT::stop() +{ + qDebug("SimplePTT::stop"); + m_worker->stopWork(); + m_state = StIdle; + m_thread.quit(); + m_thread.wait(); +} + +bool SimplePTT::handleMessage(const Message& cmd) +{ + if (MsgConfigureSimplePTT::match(cmd)) + { + MsgConfigureSimplePTT& cfg = (MsgConfigureSimplePTT&) cmd; + qDebug() << "SimplePTT::handleMessage: MsgConfigureSimplePTT"; + applySettings(cfg.getSettings(), cfg.getForce()); + + return true; + } + else if (MsgPTT::match(cmd)) + { + MsgPTT& cfg = (MsgPTT&) cmd; + qDebug() << "SimplePTT::handleMessage: MsgPTT: tx:" << cfg.getTx(); + + SimplePTTWorker::MsgPTT *msg = SimplePTTWorker::MsgPTT::create(cfg.getTx()); + m_worker->getInputMessageQueue()->push(msg); + + return true; + } + else if (MsgStartStop::match(cmd)) + { + MsgStartStop& cfg = (MsgStartStop&) cmd; + qDebug() << "SimplePTT::handleMessage: MsgStartStop: start:" << cfg.getStartStop(); + + if (cfg.getStartStop()) { + start(); + } else { + stop(); + } + + return true; + } + else + { + return false; + } +} + +QByteArray SimplePTT::serialize() const +{ + return m_settings.serialize(); +} + +bool SimplePTT::deserialize(const QByteArray& data) +{ + if (m_settings.deserialize(data)) + { + MsgConfigureSimplePTT *msg = MsgConfigureSimplePTT::create(m_settings, true); + m_inputMessageQueue.push(msg); + return true; + } + else + { + m_settings.resetToDefaults(); + MsgConfigureSimplePTT *msg = MsgConfigureSimplePTT::create(m_settings, true); + m_inputMessageQueue.push(msg); + return false; + } +} + +void SimplePTT::applySettings(const SimplePTTSettings& settings, bool force) +{ + qDebug() << "SimplePTT::applySettings:" + << " m_title: " << settings.m_title + << " m_rgbColor: " << settings.m_rgbColor + << " m_rxDeviceSetIndex: " << settings.m_rxDeviceSetIndex + << " m_txDeviceSetIndex: " << settings.m_txDeviceSetIndex + << " m_rx2TxDelayMs: " << settings.m_rx2TxDelayMs + << " m_tx2RxDelayMs: " << settings.m_tx2RxDelayMs + << " force: " << force; + + SimplePTTWorker::MsgConfigureSimplePTTWorker *msg = SimplePTTWorker::MsgConfigureSimplePTTWorker::create( + settings, force + ); + m_worker->getInputMessageQueue()->push(msg); + + m_settings = settings; +} diff --git a/plugins/feature/simpleptt/simpleptt.h b/plugins/feature/simpleptt/simpleptt.h new file mode 100644 index 000000000..8a22d3d71 --- /dev/null +++ b/plugins/feature/simpleptt/simpleptt.h @@ -0,0 +1,119 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_FEATURE_SIMPLEPTT_H_ +#define INCLUDE_FEATURE_SIMPLEPTT_H_ + +#include + +#include "feature/feature.h" +#include "util/message.h" + +#include "simplepttsettings.h" + +class WebAPIAdapterInterface; +class SimplePTTWorker; + +class SimplePTT : public Feature +{ + Q_OBJECT +public: + class MsgConfigureSimplePTT : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const SimplePTTSettings& getSettings() const { return m_settings; } + bool getForce() const { return m_force; } + + static MsgConfigureSimplePTT* create(const SimplePTTSettings& settings, bool force) { + return new MsgConfigureSimplePTT(settings, force); + } + + private: + SimplePTTSettings m_settings; + bool m_force; + + MsgConfigureSimplePTT(const SimplePTTSettings& settings, bool force) : + Message(), + m_settings(settings), + m_force(force) + { } + }; + + class MsgPTT : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getTx() const { return m_tx; } + + static MsgPTT* create(bool tx) { + return new MsgPTT(tx); + } + + private: + bool m_tx; + + MsgPTT(bool tx) : + Message(), + m_tx(tx) + { } + }; + + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + + SimplePTT(WebAPIAdapterInterface *webAPIAdapterInterface); + ~SimplePTT(); + virtual void destroy() { delete this; } + virtual bool handleMessage(const Message& cmd); + + virtual void getIdentifier(QString& id) { id = objectName(); } + virtual void getTitle(QString& title) { title = m_settings.m_title; } + + virtual QByteArray serialize() const; + virtual bool deserialize(const QByteArray& data); + + static const QString m_featureIdURI; + static const QString m_featureId; + +private: + QThread m_thread; + SimplePTTWorker *m_worker; + SimplePTTSettings m_settings; + + void start(); + void stop(); + void applySettings(const SimplePTTSettings& settings, bool force = false); +}; + +#endif // INCLUDE_FEATURE_SIMPLEPTT_H_ \ No newline at end of file diff --git a/plugins/feature/simpleptt/simplepttgui.cpp b/plugins/feature/simpleptt/simplepttgui.cpp new file mode 100644 index 000000000..e71c6d3f8 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttgui.cpp @@ -0,0 +1,372 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "feature/featureuiset.h" +#include "gui/basicfeaturesettingsdialog.h" +#include "mainwindow.h" +#include "device/deviceuiset.h" + +#include "ui_simplepttgui.h" +#include "simplepttreport.h" +#include "simpleptt.h" +#include "simplepttgui.h" + +SimplePTTGUI* SimplePTTGUI::create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature) +{ + SimplePTTGUI* gui = new SimplePTTGUI(pluginAPI, featureUISet, feature); + return gui; +} + +void SimplePTTGUI::destroy() +{ + delete this; +} + +void SimplePTTGUI::setName(const QString& name) +{ + setObjectName(name); +} + +QString SimplePTTGUI::getName() const +{ + return objectName(); +} + +void SimplePTTGUI::resetToDefaults() +{ + m_settings.resetToDefaults(); + displaySettings(); + applySettings(true); +} + +QByteArray SimplePTTGUI::serialize() const +{ + return m_settings.serialize(); +} + +bool SimplePTTGUI::deserialize(const QByteArray& data) +{ + if (m_settings.deserialize(data)) + { + displaySettings(); + applySettings(true); + return true; + } + else + { + resetToDefaults(); + return false; + } +} + +bool SimplePTTGUI::handleMessage(const Message& message) +{ + if (SimplePTT::MsgConfigureSimplePTT::match(message)) + { + qDebug("SimplePTTGUI::handleMessage: SimplePTT::MsgConfigureSimplePTT"); + const SimplePTT::MsgConfigureSimplePTT& cfg = (SimplePTT::MsgConfigureSimplePTT&) message; + m_settings = cfg.getSettings(); + blockApplySettings(true); + displaySettings(); + blockApplySettings(false); + + return true; + } + else if (SimplePTTReport::MsgRadioState::match(message)) + { + qDebug("SimplePTTGUI::handleMessage: SimplePTTReport::MsgRadioState"); + const SimplePTTReport::MsgRadioState& cfg = (SimplePTTReport::MsgRadioState&) message; + SimplePTTReport::RadioState state = cfg.getState(); + ui->statusIndicator->setStyleSheet("QLabel { background-color: " + + m_statusColors[(int) state] + "; border-radius: 12px; }"); + ui->statusIndicator->setToolTip(m_statusTooltips[(int) state]); + + return true; + } + + return false; +} + +void SimplePTTGUI::handleInputMessages() +{ + Message* message; + + while ((message = getInputMessageQueue()->pop())) + { + if (handleMessage(*message)) { + delete message; + } + } +} + +void SimplePTTGUI::onWidgetRolled(QWidget* widget, bool rollDown) +{ + (void) widget; + (void) rollDown; +} + +SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : + RollupWidget(parent), + ui(new Ui::SimplePTTGUI), + m_pluginAPI(pluginAPI), + m_featureUISet(featureUISet), + m_doApplySettings(true), + m_lastFeatureState(0) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose, true); + setChannelWidget(false); + connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); + m_simplePTT = reinterpret_cast(feature); + m_simplePTT->setMessageQueueToGUI(&m_inputMessageQueue); + + m_featureUISet->registerFeatureInstance(SimplePTT::m_featureIdURI, this); + m_featureUISet->addRollupWidget(this); + + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); + connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + + connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); + m_statusTimer.start(1000); + + m_statusTooltips.push_back("Idle"); // 0 - all off + m_statusTooltips.push_back("Rx on"); // 1 - Rx on + m_statusTooltips.push_back("Tx on"); // 2 - Tx on + + m_statusColors.push_back("gray"); // All off + m_statusColors.push_back("rgb(85, 232, 85)"); // Rx on (green) + m_statusColors.push_back("rgb(232, 85, 85)"); // Tx on (red) + + updateDeviceSetLists(); + displaySettings(); + applySettings(true); +} + +SimplePTTGUI::~SimplePTTGUI() +{ + m_featureUISet->removeFeatureInstance(this); + delete m_simplePTT; // When the GUI closes it has to delete the demodulator because it can be done with (x) + delete ui; +} + +void SimplePTTGUI::blockApplySettings(bool block) +{ + m_doApplySettings = !block; +} + +void SimplePTTGUI::displaySettings() +{ + setTitleColor(m_settings.m_rgbColor); + setWindowTitle(m_settings.m_title); +} + +void SimplePTTGUI::updateDeviceSetLists() +{ + MainWindow *mainWindow = MainWindow::getInstance(); + std::vector& deviceUISets = mainWindow->getDeviceUISets(); + std::vector::const_iterator it = deviceUISets.begin(); + + ui->rxDevice->blockSignals(true); + ui->txDevice->blockSignals(true); + + ui->rxDevice->clear(); + ui->txDevice->clear(); + unsigned int deviceIndex = 0; + unsigned int rxIndex = 0; + unsigned int txIndex = 0; + + for (; it != deviceUISets.end(); ++it, deviceIndex++) + { + DSPDeviceSourceEngine *deviceSourceEngine = (*it)->m_deviceSourceEngine; + DSPDeviceSinkEngine *deviceSinkEngine = (*it)->m_deviceSinkEngine; + + if (deviceSourceEngine) + { + ui->rxDevice->addItem(QString("R%1").arg(deviceIndex), deviceIndex); + rxIndex++; + } + else if (deviceSinkEngine) + { + ui->txDevice->addItem(QString("T%1").arg(deviceIndex), deviceIndex); + txIndex++; + } + } + + if (rxIndex > 0) + { + if (m_settings.m_rxDeviceSetIndex < 0) { + ui->rxDevice->setCurrentIndex(0); + } else { + ui->rxDevice->setCurrentIndex(m_settings.m_rxDeviceSetIndex); + } + } + + if (txIndex > 0) + { + if (m_settings.m_txDeviceSetIndex < 0) { + ui->txDevice->setCurrentIndex(0); + } else { + ui->txDevice->setCurrentIndex(m_settings.m_txDeviceSetIndex); + } + } + + int rxDeviceIndex = ui->rxDevice->currentData().toInt(); + int txDeviceIndex = ui->txDevice->currentData().toInt(); + + if ((rxDeviceIndex != m_settings.m_rxDeviceSetIndex) || + (txDeviceIndex != m_settings.m_txDeviceSetIndex)) + { + qDebug("SimplePTTGUI::updateDeviceSetLists: device index changed: %d:%d", rxDeviceIndex, txDeviceIndex); + m_settings.m_rxDeviceSetIndex = rxDeviceIndex; + m_settings.m_txDeviceSetIndex = txDeviceIndex; + applySettings(); + } + + ui->rxDevice->blockSignals(false); + ui->txDevice->blockSignals(false); +} + +void SimplePTTGUI::leaveEvent(QEvent*) +{ +} + +void SimplePTTGUI::enterEvent(QEvent*) +{ +} + +void SimplePTTGUI::onMenuDialogCalled(const QPoint &p) +{ + if (m_contextMenuType == ContextMenuChannelSettings) + { + BasicFeatureSettingsDialog dialog(this); + dialog.setTitle(m_settings.m_title); + dialog.setColor(m_settings.m_rgbColor); + + dialog.move(p); + dialog.exec(); + + m_settings.m_rgbColor = dialog.getColor().rgb(); + m_settings.m_title = dialog.getTitle(); + + setWindowTitle(m_settings.m_title); + setTitleColor(m_settings.m_rgbColor); + + applySettings(); + } + + resetContextMenuType(); +} + +void SimplePTTGUI::on_startStop_toggled(bool checked) +{ + if (m_doApplySettings) + { + SimplePTT::MsgStartStop *message = SimplePTT::MsgStartStop::create(checked); + m_simplePTT->getInputMessageQueue()->push(message); + } +} + +void SimplePTTGUI::on_devicesRefresh_clicked() +{ + updateDeviceSetLists(); + displaySettings(); +} + +void SimplePTTGUI::on_rxDevice_currentIndexChanged(int index) +{ + if (index >= 0) + { + m_settings.m_rxDeviceSetIndex = index; + applySettings(); + } +} + +void SimplePTTGUI::on_txDevice_currentIndexChanged(int index) +{ + if (index >= 0) + { + m_settings.m_txDeviceSetIndex = index; + applySettings(); + } + +} + +void SimplePTTGUI::on_rxtxDelay_valueChanged(int value) +{ + m_settings.m_rx2TxDelayMs = value; + applySettings(); +} + +void SimplePTTGUI::on_txrxDelay_valueChanged(int value) +{ + m_settings.m_tx2RxDelayMs = value; + applySettings(); +} + +void SimplePTTGUI::on_ptt_toggled(bool checked) +{ + applyPTT(checked); +} + +void SimplePTTGUI::updateStatus() +{ + int state = m_simplePTT->getState(); + + if (m_lastFeatureState != state) + { + switch (state) + { + case Feature::StNotStarted: + ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); + break; + case Feature::StIdle: + ui->startStop->setStyleSheet("QToolButton { background-color : blue; }"); + break; + case Feature::StRunning: + ui->startStop->setStyleSheet("QToolButton { background-color : green; }"); + break; + case Feature::StError: + ui->startStop->setStyleSheet("QToolButton { background-color : red; }"); + QMessageBox::information(this, tr("Message"), m_simplePTT->getErrorMessage()); + break; + default: + break; + } + + m_lastFeatureState = state; + } +} + +void SimplePTTGUI::applySettings(bool force) +{ + if (m_doApplySettings) + { + SimplePTT::MsgConfigureSimplePTT* message = SimplePTT::MsgConfigureSimplePTT::create( m_settings, force); + m_simplePTT->getInputMessageQueue()->push(message); + } +} + +void SimplePTTGUI::applyPTT(bool tx) +{ + if (m_doApplySettings) + { + SimplePTT::MsgPTT* message = SimplePTT::MsgPTT::create(tx); + m_simplePTT->getInputMessageQueue()->push(message); + } +} diff --git a/plugins/feature/simpleptt/simplepttgui.h b/plugins/feature/simpleptt/simplepttgui.h new file mode 100644 index 000000000..c94dc9a17 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttgui.h @@ -0,0 +1,93 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_FEATURE_SIMPLEPTTGUI_H_ +#define INCLUDE_FEATURE_SIMPLEPTTGUI_H_ + +#include + +#include "plugin/plugininstancegui.h" +#include "gui/rollupwidget.h" +#include "util/messagequeue.h" +#include "simplepttsettings.h" + +class PluginAPI; +class FeatureUISet; +class SimplePTT; + +namespace Ui { + class SimplePTTGUI; +} + +class SimplePTTGUI : public RollupWidget, public PluginInstanceGUI { + Q_OBJECT +public: + static SimplePTTGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature); + virtual void destroy(); + void setName(const QString& name); + QString getName() const; + virtual qint64 getCenterFrequency() const { return 0; } + virtual void setCenterFrequency(qint64 centerFrequency) {} + + void resetToDefaults(); + QByteArray serialize() const; + bool deserialize(const QByteArray& data); + virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } + virtual bool handleMessage(const Message& message); + +private: + Ui::SimplePTTGUI* ui; + PluginAPI* m_pluginAPI; + FeatureUISet* m_featureUISet; + SimplePTTSettings m_settings; + bool m_doApplySettings; + + SimplePTT* m_simplePTT; + MessageQueue m_inputMessageQueue; + QTimer m_statusTimer; + int m_lastFeatureState; + std::vector m_statusColors; + std::vector m_statusTooltips; + + explicit SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); + virtual ~SimplePTTGUI(); + + void blockApplySettings(bool block); + void applySettings(bool force = false); + void applyPTT(bool tx); + void displaySettings(); + void updateDeviceSetLists(); + + void leaveEvent(QEvent*); + void enterEvent(QEvent*); + +private slots: + void onMenuDialogCalled(const QPoint &p); + void onWidgetRolled(QWidget* widget, bool rollDown); + void handleInputMessages(); + void on_startStop_toggled(bool checked); + void on_devicesRefresh_clicked(); + void on_rxDevice_currentIndexChanged(int index); + void on_txDevice_currentIndexChanged(int index); + void on_rxtxDelay_valueChanged(int value); + void on_txrxDelay_valueChanged(int value); + void on_ptt_toggled(bool checked); + void updateStatus(); +}; + + +#endif // INCLUDE_FEATURE_SIMPLEPTTGUI_H_ \ No newline at end of file diff --git a/plugins/feature/simpleptt/simplepttgui.ui b/plugins/feature/simpleptt/simplepttgui.ui new file mode 100644 index 000000000..ebe97b6fb --- /dev/null +++ b/plugins/feature/simpleptt/simplepttgui.ui @@ -0,0 +1,327 @@ + + + SimplePTTGUI + + + + 0 + 0 + 320 + 181 + + + + + 0 + 0 + + + + + 320 + 100 + + + + + 320 + 16777215 + + + + + Liberation Sans + 9 + + + + Simple PTT + + + Local Sink + + + + + 10 + 10 + 301 + 151 + + + + Settings + + + + 3 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + start/stop acquisition + + + + + + + :/play.png + :/stop.png:/play.png + + + + + + + + 200 + 50 + + + + + 20 + 75 + true + + + + Push To Talk + + + PTT + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + Idle + + + QLabel { background-color: gray; border-radius: 12px; } + + + + + + + + + + + + + + + 24 + 16777215 + + + + Refresh indexes of available local devices + + + + + + + :/recycle.png:/recycle.png + + + + + + + Rx dev + + + + + + + + 55 + 0 + + + + + 50 + 16777215 + + + + Receiver deviceset index + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Tx dev + + + + + + + + 55 + 0 + + + + + 50 + 16777215 + + + + Transmitter deviceset index + + + + + + + + + + + Rx-Tx + + + + + + + Rx to Tx transition delay (ms) + + + 100 + + + 5000 + + + 100 + + + + + + + ms + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Tx-Rx + + + + + + + Tx to Rx transition delay (ms) + + + 100 + + + 5000 + + + 100 + + + + + + + ms + + + + + + + + + + + RollupWidget + QWidget +
gui/rollupwidget.h
+ 1 +
+ + ButtonSwitch + QToolButton +
gui/buttonswitch.h
+
+
+ + + + +
diff --git a/plugins/feature/simpleptt/simplepttplugin.cpp b/plugins/feature/simpleptt/simplepttplugin.cpp new file mode 100644 index 000000000..e99444ae4 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttplugin.cpp @@ -0,0 +1,74 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + + +#include +#include "plugin/pluginapi.h" + +#ifndef SERVER_MODE +#include "simplepttgui.h" +#endif +#include "simpleptt.h" +#include "simplepttplugin.h" + +const PluginDescriptor SimplePTTPlugin::m_pluginDescriptor = { + SimplePTT::m_featureId, + QString("Simple PTT"), + QString("5.12.0"), + QString("(c) Edouard Griffiths, F4EXB"), + QString("https://github.com/f4exb/sdrangel"), + true, + QString("https://github.com/f4exb/sdrangel") +}; + +SimplePTTPlugin::SimplePTTPlugin(QObject* parent) : + QObject(parent), + m_pluginAPI(nullptr) +{ +} + +const PluginDescriptor& SimplePTTPlugin::getPluginDescriptor() const +{ + return m_pluginDescriptor; +} + +void SimplePTTPlugin::initPlugin(PluginAPI* pluginAPI) +{ + m_pluginAPI = pluginAPI; + + // register Simple PTT feature + m_pluginAPI->registerFeature(SimplePTT::m_featureIdURI, SimplePTT::m_featureId, this); +} + +#ifdef SERVER_MODE +PluginInstanceGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const +{ + (void) featureUISet; + (void) feature; + return nullptr; +} +#else +PluginInstanceGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const +{ + return SimplePTTGUI::create(m_pluginAPI, featureUISet, feature); +} +#endif + +Feature* SimplePTTPlugin::createFeature(WebAPIAdapterInterface* webAPIAdapterInterface) const +{ + return new SimplePTT(webAPIAdapterInterface); +} diff --git a/plugins/feature/simpleptt/simplepttplugin.h b/plugins/feature/simpleptt/simplepttplugin.h new file mode 100644 index 000000000..0d32b88fc --- /dev/null +++ b/plugins/feature/simpleptt/simplepttplugin.h @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_FEATURE_SIMPLEPTTPLUGIN_H +#define INCLUDE_FEATURE_SIMPLEPTTPLUGIN_H + +#include +#include "plugin/plugininterface.h" + +class WebAPIAdapterInterface; + +class SimplePTTPlugin : public QObject, PluginInterface { + Q_OBJECT + Q_INTERFACES(PluginInterface) + Q_PLUGIN_METADATA(IID "sdrangel.feature.simpleptt") + +public: + explicit SimplePTTPlugin(QObject* parent = nullptr); + + const PluginDescriptor& getPluginDescriptor() const; + void initPlugin(PluginAPI* pluginAPI); + + virtual PluginInstanceGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const; + virtual Feature* createFeature(WebAPIAdapterInterface *webAPIAdapterInterface) const; + +private: + static const PluginDescriptor m_pluginDescriptor; + + PluginAPI* m_pluginAPI; +}; + +#endif // INCLUDE_FEATURE_SIMPLEPTTPLUGIN_H diff --git a/plugins/feature/simpleptt/simplepttreport.cpp b/plugins/feature/simpleptt/simplepttreport.cpp new file mode 100644 index 000000000..e84f57355 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttreport.cpp @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "simplepttreport.h" + +MESSAGE_CLASS_DEFINITION(SimplePTTReport::MsgRadioState, Message) + +SimplePTTReport::SimplePTTReport() +{} + +SimplePTTReport::~SimplePTTReport() +{} diff --git a/plugins/feature/simpleptt/simplepttreport.h b/plugins/feature/simpleptt/simplepttreport.h new file mode 100644 index 000000000..8f687b91b --- /dev/null +++ b/plugins/feature/simpleptt/simplepttreport.h @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_FEATURE_SIMPLEPTTREPORT_H_ +#define INCLUDE_FEATURE_SIMPLEPTTREPORT_H_ + +#include "util/message.h" + +class SimplePTTReport +{ +public: + enum RadioState { + RadioIdle, + RadioRx, + RadioTx + }; + class MsgRadioState : public Message { + MESSAGE_CLASS_DECLARATION + + public: + RadioState getState() const { return m_state; } + + static MsgRadioState* create(RadioState state) + { + return new MsgRadioState(state); + } + + private: + RadioState m_state; + + MsgRadioState(RadioState state) : + Message(), + m_state(state) + { } + }; + + SimplePTTReport(); + ~SimplePTTReport(); +}; + +#endif // INCLUDE_FEATURE_SIMPLEPTTREPORT_H_ diff --git a/plugins/feature/simpleptt/simplepttsettings.cpp b/plugins/feature/simpleptt/simplepttsettings.cpp new file mode 100644 index 000000000..bfe9434d6 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttsettings.cpp @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "util/simpleserializer.h" +#include "settings/serializable.h" + +#include "simplepttsettings.h" + +SimplePTTSettings::SimplePTTSettings() +{ + resetToDefaults(); +} + +void SimplePTTSettings::resetToDefaults() +{ + m_title = "Simple PTT"; + m_rgbColor = QColor(255, 0, 0).rgb(); + m_rxDeviceSetIndex = -1; + m_txDeviceSetIndex = -1; + m_rx2TxDelayMs = 0; + m_tx2RxDelayMs = 0; +} + +QByteArray SimplePTTSettings::serialize() const +{ + SimpleSerializer s(1); + + s.writeString(1, m_title); + s.writeU32(2, m_rgbColor); + s.writeS32(3, m_rxDeviceSetIndex); + s.writeS32(4, m_txDeviceSetIndex); + s.writeU32(5, m_rx2TxDelayMs); + s.writeU32(6, m_tx2RxDelayMs); + + return s.final(); +} + +bool SimplePTTSettings::deserialize(const QByteArray& data) +{ + SimpleDeserializer d(data); + + if(!d.isValid()) + { + resetToDefaults(); + return false; + } + + if(d.getVersion() == 1) + { + QByteArray bytetmp; + qint32 tmp; + uint32_t utmp; + QString strtmp; + + d.readString(1, &m_title, "Simple PTT"); + d.readU32(2, &m_rgbColor, QColor(255, 0, 0).rgb()); + d.readS32(3, &m_rxDeviceSetIndex, -1); + d.readS32(4, &m_txDeviceSetIndex, -1); + d.readU32(5, &m_rx2TxDelayMs, 0); + d.readU32(6, &m_tx2RxDelayMs, 0); + + return true; + } + else + { + resetToDefaults(); + return false; + } +} diff --git a/plugins/feature/simpleptt/simplepttsettings.h b/plugins/feature/simpleptt/simplepttsettings.h new file mode 100644 index 000000000..9d003141f --- /dev/null +++ b/plugins/feature/simpleptt/simplepttsettings.h @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_FEATURE_SIMPLEPTTSETTINGS_H_ +#define INCLUDE_FEATURE_SIMPLEPTTSETTINGS_H_ + +#include +#include + +class Serializable; + +struct SimplePTTSettings +{ + QString m_title; + quint32 m_rgbColor; + int m_rxDeviceSetIndex; + int m_txDeviceSetIndex; + unsigned int m_rx2TxDelayMs; + unsigned int m_tx2RxDelayMs; + + SimplePTTSettings(); + void resetToDefaults(); + QByteArray serialize() const; + bool deserialize(const QByteArray& data); +}; + +#endif // INCLUDE_FEATURE_SIMPLEPTTSETTINGS_H_ diff --git a/plugins/feature/simpleptt/simplepttworker.cpp b/plugins/feature/simpleptt/simplepttworker.cpp new file mode 100644 index 000000000..c1d47d635 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttworker.cpp @@ -0,0 +1,209 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "SWGDeviceState.h" +#include "SWGSuccessResponse.h" +#include "SWGErrorResponse.h" + +#include "webapi/webapiadapterinterface.h" + +#include "simplepttreport.h" +#include "simplepttworker.h" + +MESSAGE_CLASS_DEFINITION(SimplePTTWorker::MsgConfigureSimplePTTWorker, Message) +MESSAGE_CLASS_DEFINITION(SimplePTTWorker::MsgPTT, Message) + +SimplePTTWorker::SimplePTTWorker(WebAPIAdapterInterface *webAPIAdapterInterface) : + m_webAPIAdapterInterface(webAPIAdapterInterface), + m_msgQueueToGUI(nullptr), + m_running(false), + m_mutex(QMutex::Recursive) +{ + qDebug("SimplePTTWorker::SimplePTTWorker"); + connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); +} + +SimplePTTWorker::~SimplePTTWorker() +{ + m_inputMessageQueue.clear(); +} + +void SimplePTTWorker::reset() +{ + QMutexLocker mutexLocker(&m_mutex); + m_inputMessageQueue.clear(); +} + +bool SimplePTTWorker::startWork() +{ + QMutexLocker mutexLocker(&m_mutex); + connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + m_running = true; + return m_running; +} + +void SimplePTTWorker::stopWork() +{ + QMutexLocker mutexLocker(&m_mutex); + disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + m_running = false; +} + +void SimplePTTWorker::handleInputMessages() +{ + Message* message; + + while ((message = m_inputMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} + +bool SimplePTTWorker::handleMessage(const Message& cmd) +{ + if (MsgConfigureSimplePTTWorker::match(cmd)) + { + QMutexLocker mutexLocker(&m_mutex); + MsgConfigureSimplePTTWorker& cfg = (MsgConfigureSimplePTTWorker&) cmd; + qDebug() << "SimplePTTWorker::handleMessage: MsgConfigureSimplePTTWorker"; + + applySettings(cfg.getSettings(), cfg.getForce()); + + return true; + } + else if (MsgPTT::match(cmd)) + { + MsgPTT& cfg = (MsgPTT&) cmd; + qDebug() << "SimplePTTWorker::handleMessage: MsgPTT"; + + sendPTT(cfg.getTx()); + + return true; + } + else + { + return false; + } +} + +void SimplePTTWorker::applySettings(const SimplePTTSettings& settings, bool force) +{ + qDebug() << "SimplePTTWorker::applySettings:" + << " m_title: " << settings.m_title + << " m_rgbColor: " << settings.m_rgbColor + << " m_rxDeviceSetIndex: " << settings.m_rxDeviceSetIndex + << " m_txDeviceSetIndex: " << settings.m_txDeviceSetIndex + << " m_rx2TxDelayMs: " << settings.m_rx2TxDelayMs + << " m_tx2RxDelayMs: " << settings.m_tx2RxDelayMs + << " force: " << force; + m_settings = settings; +} + +void SimplePTTWorker::sendPTT(bool tx) +{ + if (!m_updateTimer.isActive()) + { + bool switchedOff = false; + m_mutex.lock(); + + if (tx) + { + if (m_settings.m_rxDeviceSetIndex >= 0) + { + m_tx = false; + switchedOff = turnDevice(false); + } + + if (m_settings.m_txDeviceSetIndex >= 0) + { + m_tx = true; + m_updateTimer.start(m_settings.m_rx2TxDelayMs); + } + } + else + { + if (m_settings.m_txDeviceSetIndex >= 0) + { + m_tx = true; + switchedOff = turnDevice(false); + } + + if (m_settings.m_rxDeviceSetIndex >= 0) + { + m_tx = false; + m_updateTimer.start(m_settings.m_tx2RxDelayMs); + } + } + + if (switchedOff && (m_msgQueueToGUI)) + { + SimplePTTReport::MsgRadioState *msg = SimplePTTReport::MsgRadioState::create(SimplePTTReport::RadioIdle); + m_msgQueueToGUI->push(msg); + } + } +} + +void SimplePTTWorker::updateHardware() +{ + SWGSDRangel::SWGSuccessResponse response; + SWGSDRangel::SWGErrorResponse error; + m_updateTimer.stop(); + m_mutex.unlock(); + + if (turnDevice(true)) + { + m_webAPIAdapterInterface->devicesetFocusPatch( + m_tx ? m_settings.m_txDeviceSetIndex : m_settings.m_rxDeviceSetIndex, response, error); + + if (m_msgQueueToGUI) + { + SimplePTTReport::MsgRadioState *msg = SimplePTTReport::MsgRadioState::create( + m_tx ? SimplePTTReport::RadioTx : SimplePTTReport::RadioRx + ); + m_msgQueueToGUI->push(msg); + } + } +} + +bool SimplePTTWorker::turnDevice(bool on) +{ + SWGSDRangel::SWGDeviceState response; + SWGSDRangel::SWGErrorResponse error; + int httpCode; + + if (on) { + httpCode = m_webAPIAdapterInterface->devicesetDeviceRunPost( + m_tx ? m_settings.m_txDeviceSetIndex : m_settings.m_rxDeviceSetIndex, response, error); + } else { + httpCode = m_webAPIAdapterInterface->devicesetDeviceRunDelete( + m_tx ? m_settings.m_txDeviceSetIndex : m_settings.m_rxDeviceSetIndex, response, error); + } + + if (httpCode/100 == 2) + { + return true; + } + else + { + qWarning("SimplePTTWorker::turnDevice: error: %s", qPrintable(*error.getMessage())); + return false; + } +} \ No newline at end of file diff --git a/plugins/feature/simpleptt/simplepttworker.h b/plugins/feature/simpleptt/simplepttworker.h new file mode 100644 index 000000000..b064021e6 --- /dev/null +++ b/plugins/feature/simpleptt/simplepttworker.h @@ -0,0 +1,106 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_FEATURE_SIMPLEPTTWORKER_H_ +#define INCLUDE_FEATURE_SIMPLEPTTWORKER_H_ + +#include +#include + +#include "util/message.h" +#include "util/messagequeue.h" + +#include "simplepttsettings.h" + +class WebAPIAdapterInterface; + +class SimplePTTWorker : public QObject +{ + Q_OBJECT +public: + class MsgConfigureSimplePTTWorker : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const SimplePTTSettings& getSettings() const { return m_settings; } + bool getForce() const { return m_force; } + + static MsgConfigureSimplePTTWorker* create(const SimplePTTSettings& settings, bool force) + { + return new MsgConfigureSimplePTTWorker(settings, force); + } + + private: + SimplePTTSettings m_settings; + bool m_force; + + MsgConfigureSimplePTTWorker(const SimplePTTSettings& settings, bool force) : + Message(), + m_settings(settings), + m_force(force) + { } + }; + + class MsgPTT : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getTx() const { return m_tx; } + + static MsgPTT* create(bool tx) { + return new MsgPTT(tx); + } + + private: + bool m_tx; + + MsgPTT(bool tx) : + Message(), + m_tx(tx) + { } + }; + + SimplePTTWorker(WebAPIAdapterInterface *webAPIAdapterInterface); + ~SimplePTTWorker(); + void reset(); + bool startWork(); + void stopWork(); + bool isRunning() const { return m_running; } + MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } + void setMessageQueueToGUI(MessageQueue *messageQueue) { m_msgQueueToGUI = messageQueue; } + +private: + WebAPIAdapterInterface *m_webAPIAdapterInterface; + MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication + MessageQueue *m_msgQueueToGUI; //!< Queue to report state to GUI + SimplePTTSettings m_settings; + bool m_running; + bool m_tx; + QTimer m_updateTimer; + QMutex m_mutex; + + bool handleMessage(const Message& cmd); + void applySettings(const SimplePTTSettings& settings, bool force = false); + void sendPTT(bool tx); + bool turnDevice(bool on); + +private slots: + void handleInputMessages(); + void updateHardware(); +}; + +#endif // INCLUDE_FEATURE_SIMPLEPTTWORKER_H_ \ No newline at end of file