PTT Feature: initial commit

This commit is contained in:
f4exb 2020-09-20 01:06:50 +02:00
parent e8f3745bf3
commit e36ab79b7a
16 changed files with 1764 additions and 0 deletions

View File

@ -40,5 +40,6 @@ endif()
add_subdirectory(channelrx)
add_subdirectory(channeltx)
add_subdirectory(feature)
add_subdirectory(samplesource)
add_subdirectory(samplesink)

View File

@ -0,0 +1,3 @@
project(feature)
add_subdirectory(simpleptt)

View File

@ -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})

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QDebug>
#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;
}

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FEATURE_SIMPLEPTT_H_
#define INCLUDE_FEATURE_SIMPLEPTT_H_
#include <QThread>
#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_

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QMessageBox>
#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<SimplePTT*>(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<DeviceUISet*>& deviceUISets = mainWindow->getDeviceUISets();
std::vector<DeviceUISet*>::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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FEATURE_SIMPLEPTTGUI_H_
#define INCLUDE_FEATURE_SIMPLEPTTGUI_H_
#include <QTimer>
#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<QString> m_statusColors;
std::vector<QString> 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_

View File

@ -0,0 +1,327 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SimplePTTGUI</class>
<widget class="RollupWidget" name="SimplePTTGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>181</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>320</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>320</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Simple PTT</string>
</property>
<property name="statusTip">
<string>Local Sink</string>
</property>
<widget class="QWidget" name="settingsContainer" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>301</width>
<height>151</height>
</rect>
</property>
<property name="windowTitle">
<string>Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="pttLayout">
<item>
<widget class="ButtonSwitch" name="startStop">
<property name="toolTip">
<string>start/stop acquisition</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/play.png</normaloff>
<normalon>:/stop.png</normalon>:/play.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="ptt">
<property name="minimumSize">
<size>
<width>200</width>
<height>50</height>
</size>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string>Push To Talk</string>
</property>
<property name="text">
<string>PTT</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="statusIndicator">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Idle</string>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: gray; border-radius: 12px; }</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="localDeviceLayout">
<item>
<widget class="QPushButton" name="devicesRefresh">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Refresh indexes of available local devices</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rxDeviceLabel">
<property name="text">
<string>Rx dev</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="rxDevice">
<property name="minimumSize">
<size>
<width>55</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Receiver deviceset index</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="txDeviceLabel">
<property name="text">
<string>Tx dev</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="txDevice">
<property name="minimumSize">
<size>
<width>55</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Transmitter deviceset index</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="DelaysLayout">
<item>
<widget class="QLabel" name="rxtxDelayLabel">
<property name="text">
<string>Rx-Tx </string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="rxtxDelay">
<property name="toolTip">
<string>Rx to Tx transition delay (ms)</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rxtxDelayUnits">
<property name="text">
<string>ms</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="txrxDelayLabel">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Tx-Rx</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="txrxDelay">
<property name="toolTip">
<string>Tx to Rx transition delay (ms)</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="txrxDelayUnits">
<property name="text">
<string>ms</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>RollupWidget</class>
<extends>QWidget</extends>
<header>gui/rollupwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QtPlugin>
#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);
}

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FEATURE_SIMPLEPTTPLUGIN_H
#define INCLUDE_FEATURE_SIMPLEPTTPLUGIN_H
#include <QObject>
#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

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "simplepttreport.h"
MESSAGE_CLASS_DEFINITION(SimplePTTReport::MsgRadioState, Message)
SimplePTTReport::SimplePTTReport()
{}
SimplePTTReport::~SimplePTTReport()
{}

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#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_

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QColor>
#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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FEATURE_SIMPLEPTTSETTINGS_H_
#define INCLUDE_FEATURE_SIMPLEPTTSETTINGS_H_
#include <QByteArray>
#include <QString>
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_

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QDebug>
#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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FEATURE_SIMPLEPTTWORKER_H_
#define INCLUDE_FEATURE_SIMPLEPTTWORKER_H_
#include <QObject>
#include <QTimer>
#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_