1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-17 13:51:47 -05:00

Feature plugins framework: REST API and server implementationo

This commit is contained in:
f4exb 2020-09-21 03:13:36 +02:00
parent 20ef49ea84
commit 153429cc7f
27 changed files with 2032 additions and 48 deletions

View File

@ -16,6 +16,15 @@
///////////////////////////////////////////////////////////////////////////////////
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QBuffer>
#include "SWGFeatureSettings.h"
#include "SWGFeatureReport.h"
#include "SWGFeatureActions.h"
#include "SWGSimplePTTReport.h"
#include "SWGDeviceState.h"
#include "dsp/dspengine.h"
@ -30,7 +39,8 @@ const QString SimplePTT::m_featureIdURI = "sdrangel.feature.simpleptt";
const QString SimplePTT::m_featureId = "SimplePTT";
SimplePTT::SimplePTT(WebAPIAdapterInterface *webAPIAdapterInterface) :
Feature(m_featureIdURI, webAPIAdapterInterface)
Feature(m_featureIdURI, webAPIAdapterInterface),
m_ptt(false)
{
setObjectName(m_featureId);
m_worker = new SimplePTTWorker(webAPIAdapterInterface);
@ -83,9 +93,10 @@ bool SimplePTT::handleMessage(const Message& cmd)
else if (MsgPTT::match(cmd))
{
MsgPTT& cfg = (MsgPTT&) cmd;
qDebug() << "SimplePTT::handleMessage: MsgPTT: tx:" << cfg.getTx();
m_ptt = cfg.getTx();
qDebug() << "SimplePTT::handleMessage: MsgPTT: tx:" << m_ptt;
SimplePTTWorker::MsgPTT *msg = SimplePTTWorker::MsgPTT::create(cfg.getTx());
SimplePTTWorker::MsgPTT *msg = SimplePTTWorker::MsgPTT::create(m_ptt);
m_worker->getInputMessageQueue()->push(msg);
return true;
@ -142,10 +153,260 @@ void SimplePTT::applySettings(const SimplePTTSettings& settings, bool force)
<< " m_tx2RxDelayMs: " << settings.m_tx2RxDelayMs
<< " force: " << force;
QList<QString> reverseAPIKeys;
if ((m_settings.m_title != settings.m_title) || force) {
reverseAPIKeys.append("title");
}
if ((m_settings.m_rgbColor != settings.m_rgbColor) || force) {
reverseAPIKeys.append("rgbColor");
}
if ((m_settings.m_rxDeviceSetIndex != settings.m_rxDeviceSetIndex) || force) {
reverseAPIKeys.append("rxDeviceSetIndex");
}
if ((m_settings.m_txDeviceSetIndex != settings.m_txDeviceSetIndex) || force) {
reverseAPIKeys.append("txDeviceSetIndex");
}
if ((m_settings.m_rx2TxDelayMs != settings.m_rx2TxDelayMs) || force) {
reverseAPIKeys.append("rx2TxDelayMs");
}
if ((m_settings.m_tx2RxDelayMs != settings.m_tx2RxDelayMs) || force) {
reverseAPIKeys.append("tx2RxDelayMs");
}
SimplePTTWorker::MsgConfigureSimplePTTWorker *msg = SimplePTTWorker::MsgConfigureSimplePTTWorker::create(
settings, force
);
m_worker->getInputMessageQueue()->push(msg);
if (settings.m_useReverseAPI)
{
bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
(m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
(m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
(m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex) ||
(m_settings.m_reverseAPIChannelIndex != settings.m_reverseAPIChannelIndex);
webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
}
m_settings = settings;
}
int SimplePTT::webapiRun(bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage)
{
getFeatureStateStr(*response.getState());
MsgStartStop *msg = MsgStartStop::create(run);
getInputMessageQueue()->push(msg);
return 202;
}
int SimplePTT::webapiSettingsGet(
SWGSDRangel::SWGFeatureSettings& response,
QString& errorMessage)
{
(void) errorMessage;
response.setSimplePttSettings(new SWGSDRangel::SWGSimplePTTSettings());
response.getSimplePttSettings()->init();
webapiFormatFeatureSettings(response, m_settings);
return 200;
}
int SimplePTT::webapiSettingsPutPatch(
bool force,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response,
QString& errorMessage)
{
(void) errorMessage;
SimplePTTSettings settings = m_settings;
webapiUpdateFeatureSettings(settings, featureSettingsKeys, response);
MsgConfigureSimplePTT *msg = MsgConfigureSimplePTT::create(settings, force);
m_inputMessageQueue.push(msg);
qDebug("SimplePTT::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureSimplePTT *msgToGUI = MsgConfigureSimplePTT::create(settings, force);
m_guiMessageQueue->push(msgToGUI);
}
webapiFormatFeatureSettings(response, settings);
return 200;
}
int SimplePTT::webapiReportGet(
SWGSDRangel::SWGFeatureReport& response,
QString& errorMessage)
{
(void) errorMessage;
response.setSimplePttReport(new SWGSDRangel::SWGSimplePTTReport());
response.getSimplePttReport()->init();
webapiFormatFeatureReport(response);
return 200;
}
int SimplePTT::webapiActionsPost(
const QStringList& featureActionsKeys,
SWGSDRangel::SWGFeatureActions& query,
QString& errorMessage)
{
SWGSDRangel::SWGSimplePTTActions *swgSimplePTTActions = query.getSimplePttActions();
if (swgSimplePTTActions)
{
if (featureActionsKeys.contains("ptt"))
{
bool ptt = swgSimplePTTActions->getPtt() != 0;
MsgPTT *msg = MsgPTT::create(ptt);
getInputMessageQueue()->push(msg);
if (getMessageQueueToGUI())
{
MsgPTT *msgToGUI = MsgPTT::create(ptt);
getMessageQueueToGUI()->push(msgToGUI);
}
}
return 202;
}
else
{
errorMessage = "Missing SimplePTTActions in query";
return 400;
}
}
void SimplePTT::webapiFormatFeatureSettings(
SWGSDRangel::SWGFeatureSettings& response,
const SimplePTTSettings& settings)
{
if (response.getSimplePttSettings()->getTitle()) {
*response.getSimplePttSettings()->getTitle() = settings.m_title;
} else {
response.getSimplePttSettings()->setTitle(new QString(settings.m_title));
}
response.getSimplePttSettings()->setRgbColor(settings.m_rgbColor);
response.getSimplePttSettings()->setRxDeviceSetIndex(settings.m_rxDeviceSetIndex);
response.getSimplePttSettings()->setTxDeviceSetIndex(settings.m_txDeviceSetIndex);
response.getSimplePttSettings()->setRx2TxDelayMs(settings.m_rx2TxDelayMs);
response.getSimplePttSettings()->setTx2RxDelayMs(settings.m_tx2RxDelayMs);
response.getSimplePttSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
if (response.getSimplePttSettings()->getReverseApiAddress()) {
*response.getSimplePttSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
} else {
response.getSimplePttSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
}
response.getSimplePttSettings()->setReverseApiPort(settings.m_reverseAPIPort);
response.getSimplePttSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
response.getSimplePttSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex);
}
void SimplePTT::webapiUpdateFeatureSettings(
SimplePTTSettings& settings,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response)
{
if (featureSettingsKeys.contains("title")) {
settings.m_title = *response.getSimplePttSettings()->getTitle();
}
if (featureSettingsKeys.contains("rgbColor")) {
settings.m_rgbColor = response.getSimplePttSettings()->getRgbColor();
}
if (featureSettingsKeys.contains("rxDeviceSetIndex")) {
settings.m_rxDeviceSetIndex = response.getSimplePttSettings()->getRxDeviceSetIndex();
}
if (featureSettingsKeys.contains("txDeviceSetIndex")) {
settings.m_txDeviceSetIndex = response.getSimplePttSettings()->getTxDeviceSetIndex();
}
if (featureSettingsKeys.contains("rx2TxDelayMs")) {
settings.m_rx2TxDelayMs = response.getSimplePttSettings()->getRx2TxDelayMs();
}
if (featureSettingsKeys.contains("tx2RxDelayMs")) {
settings.m_tx2RxDelayMs = response.getSimplePttSettings()->getTx2RxDelayMs();
}
}
void SimplePTT::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response)
{
response.getSimplePttReport()->setPtt(m_ptt ? 1 : 0);
}
void SimplePTT::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const SimplePTTSettings& settings, bool force)
{
SWGSDRangel::SWGFeatureSettings *swgFeatureSettings = new SWGSDRangel::SWGFeatureSettings();
// swgFeatureSettings->setOriginatorFeatureIndex(getIndexInDeviceSet());
// swgFeatureSettings->setOriginatorFeatureSetIndex(getDeviceSetIndex());
swgFeatureSettings->setFeatureType(new QString("SimplePTT"));
swgFeatureSettings->setSimplePttSettings(new SWGSDRangel::SWGSimplePTTSettings());
SWGSDRangel::SWGSimplePTTSettings *swgSimplePTTSettings = swgFeatureSettings->getSimplePttSettings();
// transfer data that has been modified. When force is on transfer all data except reverse API data
if (channelSettingsKeys.contains("title") || force) {
swgSimplePTTSettings->setTitle(new QString(settings.m_title));
}
if (channelSettingsKeys.contains("rgbColor") || force) {
swgSimplePTTSettings->setRgbColor(settings.m_rgbColor);
}
if (channelSettingsKeys.contains("rxDeviceSetIndex") || force) {
swgSimplePTTSettings->setRxDeviceSetIndex(settings.m_rxDeviceSetIndex);
}
if (channelSettingsKeys.contains("txDeviceSetIndex") || force) {
swgSimplePTTSettings->setTxDeviceSetIndex(settings.m_txDeviceSetIndex);
}
if (channelSettingsKeys.contains("rx2TxDelayMs") || force) {
swgSimplePTTSettings->setRx2TxDelayMs(settings.m_rx2TxDelayMs);
}
if (channelSettingsKeys.contains("tx2RxDelayMs") || force) {
swgSimplePTTSettings->setTx2RxDelayMs(settings.m_tx2RxDelayMs);
}
QString channelSettingsURL = QString("http://%1:%2/sdrangel/featureset/%3/feature/%4/settings")
.arg(settings.m_reverseAPIAddress)
.arg(settings.m_reverseAPIPort)
.arg(settings.m_reverseAPIDeviceIndex)
.arg(settings.m_reverseAPIChannelIndex);
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgFeatureSettings->asJson().toUtf8());
buffer->seek(0);
// Always use PATCH to avoid passing reverse API settings
QNetworkReply *reply = m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
buffer->setParent(reply);
delete swgFeatureSettings;
}
void SimplePTT::networkManagerFinished(QNetworkReply *reply)
{
QNetworkReply::NetworkError replyError = reply->error();
if (replyError)
{
qWarning() << "SimplePTT::networkManagerFinished:"
<< " error(" << (int) replyError
<< "): " << replyError
<< ": " << reply->errorString();
}
else
{
QString answer = reply->readAll();
answer.chop(1); // remove last \n
qDebug("SimplePTT::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
}
reply->deleteLater();
}

View File

@ -19,6 +19,7 @@
#define INCLUDE_FEATURE_SIMPLEPTT_H_
#include <QThread>
#include <QNetworkRequest>
#include "feature/feature.h"
#include "util/message.h"
@ -27,6 +28,12 @@
class WebAPIAdapterInterface;
class SimplePTTWorker;
class QNetworkAccessManager;
class QNetworkReply;
namespace SWGSDRangel {
class SWGDeviceState;
}
class SimplePTT : public Feature
{
@ -97,12 +104,44 @@ public:
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 void getIdentifier(QString& id) const { id = objectName(); }
virtual void getTitle(QString& title) const { title = m_settings.m_title; }
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
virtual int webapiRun(bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
virtual int webapiSettingsGet(
SWGSDRangel::SWGFeatureSettings& response,
QString& errorMessage);
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response,
QString& errorMessage);
virtual int webapiReportGet(
SWGSDRangel::SWGFeatureReport& response,
QString& errorMessage);
virtual int webapiActionsPost(
const QStringList& featureActionsKeys,
SWGSDRangel::SWGFeatureActions& query,
QString& errorMessage);
static void webapiFormatFeatureSettings(
SWGSDRangel::SWGFeatureSettings& response,
const SimplePTTSettings& settings);
static void webapiUpdateFeatureSettings(
SimplePTTSettings& settings,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response);
static const QString m_featureIdURI;
static const QString m_featureId;
@ -110,10 +149,19 @@ private:
QThread m_thread;
SimplePTTWorker *m_worker;
SimplePTTSettings m_settings;
bool m_ptt;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
void start();
void stop();
void applySettings(const SimplePTTSettings& settings, bool force = false);
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
void webapiReverseSendSettings(QList<QString>& featureSettingsKeys, const SimplePTTSettings& settings, bool force);
private slots:
void networkManagerFinished(QNetworkReply *reply);
};
#endif // INCLUDE_FEATURE_SIMPLEPTT_H_

View File

@ -99,6 +99,17 @@ bool SimplePTTGUI::handleMessage(const Message& message)
return true;
}
else if (SimplePTT::MsgPTT::match(message))
{
qDebug("SimplePTTGUI::handleMessage: SimplePTT::MsgPTT");
const SimplePTT::MsgPTT& cfg = (SimplePTT::MsgPTT&) message;
bool ptt = cfg.getTx();
ui->ptt->blockSignals(true);
ui->ptt->setChecked(ptt);
ui->ptt->blockSignals(false);
return true;
}
return false;
}
@ -136,7 +147,7 @@ SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Fea
m_simplePTT = reinterpret_cast<SimplePTT*>(feature);
m_simplePTT->setMessageQueueToGUI(&m_inputMessageQueue);
m_featureUISet->registerFeatureInstance(SimplePTT::m_featureIdURI, this);
m_featureUISet->registerFeatureInstance(SimplePTT::m_featureIdURI, this, m_simplePTT);
m_featureUISet->addRollupWidget(this);
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
@ -174,6 +185,10 @@ void SimplePTTGUI::displaySettings()
{
setTitleColor(m_settings.m_rgbColor);
setWindowTitle(m_settings.m_title);
blockApplySettings(true);
ui->rxtxDelay->setValue(m_settings.m_rx2TxDelayMs);
ui->txrxDelay->setValue(m_settings.m_tx2RxDelayMs);
blockApplySettings(false);
}
void SimplePTTGUI::updateDeviceSetLists()
@ -208,6 +223,9 @@ void SimplePTTGUI::updateDeviceSetLists()
}
}
int rxDeviceIndex;
int txDeviceIndex;
if (rxIndex > 0)
{
if (m_settings.m_rxDeviceSetIndex < 0) {
@ -215,7 +233,14 @@ void SimplePTTGUI::updateDeviceSetLists()
} else {
ui->rxDevice->setCurrentIndex(m_settings.m_rxDeviceSetIndex);
}
rxDeviceIndex = ui->rxDevice->currentData().toInt();
}
else
{
rxDeviceIndex = -1;
}
if (txIndex > 0)
{
@ -224,10 +249,13 @@ void SimplePTTGUI::updateDeviceSetLists()
} else {
ui->txDevice->setCurrentIndex(m_settings.m_txDeviceSetIndex);
}
}
int rxDeviceIndex = ui->rxDevice->currentData().toInt();
int txDeviceIndex = ui->txDevice->currentData().toInt();
txDeviceIndex = ui->txDevice->currentData().toInt();
}
else
{
txDeviceIndex = -1;
}
if ((rxDeviceIndex != m_settings.m_rxDeviceSetIndex) ||
(txDeviceIndex != m_settings.m_txDeviceSetIndex))
@ -257,12 +285,22 @@ void SimplePTTGUI::onMenuDialogCalled(const QPoint &p)
BasicFeatureSettingsDialog dialog(this);
dialog.setTitle(m_settings.m_title);
dialog.setColor(m_settings.m_rgbColor);
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
dialog.setReverseAPIChannelIndex(m_settings.m_reverseAPIChannelIndex);
dialog.move(p);
dialog.exec();
m_settings.m_rgbColor = dialog.getColor().rgb();
m_settings.m_title = dialog.getTitle();
m_settings.m_useReverseAPI = dialog.useReverseAPI();
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
m_settings.m_reverseAPIChannelIndex = dialog.getReverseAPIChannelIndex();
setWindowTitle(m_settings.m_title);
setTitleColor(m_settings.m_rgbColor);

View File

@ -146,7 +146,7 @@
</size>
</property>
<property name="toolTip">
<string>Refresh indexes of available local devices</string>
<string>Refresh indexes of available device sets</string>
</property>
<property name="text">
<string/>

View File

@ -33,8 +33,13 @@ void SimplePTTSettings::resetToDefaults()
m_rgbColor = QColor(255, 0, 0).rgb();
m_rxDeviceSetIndex = -1;
m_txDeviceSetIndex = -1;
m_rx2TxDelayMs = 0;
m_tx2RxDelayMs = 0;
m_rx2TxDelayMs = 100;
m_tx2RxDelayMs = 100;
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
m_reverseAPIPort = 8888;
m_reverseAPIDeviceIndex = 0;
m_reverseAPIChannelIndex = 0;
}
QByteArray SimplePTTSettings::serialize() const
@ -47,6 +52,11 @@ QByteArray SimplePTTSettings::serialize() const
s.writeS32(4, m_txDeviceSetIndex);
s.writeU32(5, m_rx2TxDelayMs);
s.writeU32(6, m_tx2RxDelayMs);
s.writeBool(7, m_useReverseAPI);
s.writeString(8, m_reverseAPIAddress);
s.writeU32(9, m_reverseAPIPort);
s.writeU32(10, m_reverseAPIDeviceIndex);
s.writeU32(11, m_reverseAPIChannelIndex);
return s.final();
}
@ -72,8 +82,22 @@ bool SimplePTTSettings::deserialize(const QByteArray& data)
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);
d.readU32(5, &m_rx2TxDelayMs, 100);
d.readU32(6, &m_tx2RxDelayMs, 100);
d.readBool(7, &m_useReverseAPI, false);
d.readString(8, &m_reverseAPIAddress, "127.0.0.1");
d.readU32(9, &utmp, 0);
if ((utmp > 1023) && (utmp < 65535)) {
m_reverseAPIPort = utmp;
} else {
m_reverseAPIPort = 8888;
}
d.readU32(10, &utmp, 0);
m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
d.readU32(11, &utmp, 0);
m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
return true;
}

View File

@ -31,6 +31,11 @@ struct SimplePTTSettings
int m_txDeviceSetIndex;
unsigned int m_rx2TxDelayMs;
unsigned int m_tx2RxDelayMs;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex;
uint16_t m_reverseAPIChannelIndex;
SimplePTTSettings();
void resetToDefaults();

View File

@ -33,6 +33,7 @@ SimplePTTWorker::SimplePTTWorker(WebAPIAdapterInterface *webAPIAdapterInterface)
m_webAPIAdapterInterface(webAPIAdapterInterface),
m_msgQueueToGUI(nullptr),
m_running(false),
m_tx(false),
m_mutex(QMutex::Recursive)
{
qDebug("SimplePTTWorker::SimplePTTWorker");

View File

@ -20,6 +20,8 @@
#include "util/uid.h"
#include "util/message.h"
#include "SWGDeviceState.h"
#include "feature.h"
Feature::Feature(const QString& name, WebAPIAdapterInterface *webAPIAdapterInterface) :
@ -41,3 +43,33 @@ void Feature::handleInputMessages()
}
}
}
int Feature::webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage) const
{
getFeatureStateStr(*response.getState());
return 200;
}
void Feature::getFeatureStateStr(QString& stateStr) const
{
switch(m_state)
{
case StNotStarted:
stateStr = "notStarted";
break;
case StIdle:
stateStr = "idle";
break;
case StRunning:
stateStr = "running";
break;
case StError:
stateStr = "error";
break;
default:
stateStr = "notStarted";
break;
}
}

View File

@ -25,10 +25,19 @@
#include <QByteArray>
#include "export.h"
#include "util/message.h"
#include "util/messagequeue.h"
class WebAPIAdapterInterface;
namespace SWGSDRangel
{
class SWGFeatureSettings;
class SWGFeatureReport;
class SWGFeatureActions;
class SWGDeviceState;
}
class SDRBASE_API Feature : public QObject {
Q_OBJECT
public:
@ -44,14 +53,83 @@ public:
virtual void destroy() = 0;
virtual bool handleMessage(const Message& cmd) = 0; //!< Processing of a message. Returns true if message has actually been processed
virtual void getIdentifier(QString& id) = 0;
virtual void getTitle(QString& title) = 0;
virtual void getIdentifier(QString& id) const = 0;
virtual void getTitle(QString& title) const = 0;
virtual void setName(const QString& name) { m_name = name; }
virtual const QString& getName() const { return m_name; }
virtual QByteArray serialize() const = 0;
virtual bool deserialize(const QByteArray& data) = 0;
/**
* API adapter for the feature run GET requests
*/
virtual int webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage) const;
/**
* API adapter for the feature run POST and DELETE requests
*/
virtual int webapiRun(bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage)
{
(void) run;
(void) response;
errorMessage = "Not implemented";
return 501;
}
/**
* API adapter for the feature settings GET requests
*/
virtual int webapiSettingsGet(
SWGSDRangel::SWGFeatureSettings& response,
QString& errorMessage)
{
(void) response;
errorMessage = "Not implemented"; return 501;
}
/**
* API adapter for the feature settings PUT and PATCH requests
*/
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response,
QString& errorMessage)
{
(void) force;
(void) featureSettingsKeys;
(void) response;
errorMessage = "Not implemented"; return 501;
}
/**
* API adapter for the feature report GET requests
*/
virtual int webapiReportGet(
SWGSDRangel::SWGFeatureReport& response,
QString& errorMessage)
{
(void) response;
errorMessage = "Not implemented"; return 501;
}
/**
* API adapter for the feature actions POST requests
*/
virtual int webapiActionsPost(
const QStringList& featureActionsKeys,
SWGSDRangel::SWGFeatureActions& query,
QString& errorMessage)
{
(void) query;
(void) featureActionsKeys;
errorMessage = "Not implemented"; return 501;
}
uint64_t getUID() const { return m_uid; }
FeatureState getState() const { return m_state; }
@ -68,6 +146,8 @@ protected:
QString m_errorMessage;
WebAPIAdapterInterface *m_webAPIAdapterInterface;
void getFeatureStateStr(QString& stateStr) const;
protected slots:
void handleInputMessages();

View File

@ -38907,7 +38907,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2020-09-28T13:19:26.040+02:00
Generated 2020-09-28T13:34:44.975+02:00
</div>
</div>
</div>

View File

@ -62,6 +62,11 @@ namespace SWGSDRangel
class SWGChannelReport;
class SWGChannelActions;
class SWGSuccessResponse;
class SWGFeatureSetList;
class SWGFeatureSet;
class SWGFeatureSettings;
class SWGFeatureReport;
class SWGFeatureActions;
}
class SDRBASE_API WebAPIAdapterInterface

View File

@ -36,9 +36,9 @@ void FeatureUISet::addRollupWidget(QWidget *widget)
m_featureWindow->addRollupWidget(widget);
}
void FeatureUISet::registerFeatureInstance(const QString& featureName, PluginInstanceGUI* pluginGUI)
void FeatureUISet::registerFeatureInstance(const QString& featureName, PluginInstanceGUI* pluginGUI, Feature *feature)
{
m_featureInstanceRegistrations.append(FeatureInstanceRegistration(featureName, pluginGUI));
m_featureInstanceRegistrations.append(FeatureInstanceRegistration(featureName, pluginGUI, feature));
renameFeatureInstances();
}
@ -83,3 +83,21 @@ void FeatureUISet::deleteFeature(int featureIndex)
renameFeatureInstances();
}
}
const Feature *FeatureUISet::getFeatureAt(int featureIndex) const
{
if ((featureIndex >= 0) && (featureIndex < m_featureInstanceRegistrations.count())) {
return m_featureInstanceRegistrations[featureIndex].m_feature;
} else{
return nullptr;
}
}
Feature *FeatureUISet::getFeatureAt(int featureIndex)
{
if ((featureIndex >= 0) && (featureIndex < m_featureInstanceRegistrations.count())) {
return m_featureInstanceRegistrations[featureIndex].m_feature;
} else{
return nullptr;
}
}

View File

@ -26,6 +26,7 @@
class QWidget;
class FeatureWindow;
class PluginInstanceGUI;
class Feature;
class SDRGUI_API FeatureUISet
{
@ -35,10 +36,12 @@ public:
void addRollupWidget(QWidget *widget); //!< Add feature rollup widget to feature window
int getNumberOfFeatures() const { return m_featureInstanceRegistrations.size(); }
void registerFeatureInstance(const QString& featureName, PluginInstanceGUI* pluginGUI);
void registerFeatureInstance(const QString& featureName, PluginInstanceGUI* pluginGUI, Feature *feature);
void removeFeatureInstance(PluginInstanceGUI* pluginGUI);
void freeFeatures();
void deleteFeature(int featureIndex);
const Feature *getFeatureAt(int featureIndex) const;
Feature *getFeatureAt(int featureIndex);
FeatureWindow *m_featureWindow;
@ -47,15 +50,18 @@ private:
{
QString m_featureName;
PluginInstanceGUI* m_gui;
Feature* m_feature;
FeatureInstanceRegistration() :
m_featureName(),
m_gui(nullptr)
m_gui(nullptr),
m_feature(nullptr)
{ }
FeatureInstanceRegistration(const QString& featureName, PluginInstanceGUI* pluginGUI) :
FeatureInstanceRegistration(const QString& featureName, PluginInstanceGUI* pluginGUI, Feature *feature) :
m_featureName(featureName),
m_gui(pluginGUI)
m_gui(pluginGUI),
m_feature(feature)
{ }
bool operator<(const FeatureInstanceRegistration& other) const;

View File

@ -37,6 +37,16 @@ public:
void setColor(const QColor& color);
const QString& getTitle() const { return m_title; }
const QColor& getColor() const { return m_color; }
bool useReverseAPI() const { return m_useReverseAPI; }
const QString& getReverseAPIAddress() const { return m_reverseAPIAddress; }
uint16_t getReverseAPIPort() const { return m_reverseAPIPort; }
uint16_t getReverseAPIDeviceIndex() const { return m_reverseAPIDeviceIndex; }
uint16_t getReverseAPIChannelIndex() const { return m_reverseAPIChannelIndex; }
void setUseReverseAPI(bool useReverseAPI);
void setReverseAPIAddress(const QString& address);
void setReverseAPIPort(uint16_t port);
void setReverseAPIDeviceIndex(uint16_t deviceIndex);
void setReverseAPIChannelIndex(uint16_t channelIndex);
bool hasChanged() const { return m_hasChanged; }
private slots:
@ -48,6 +58,11 @@ private:
Ui::BasicFeatureSettingsDialog *ui;
QColor m_color;
QString m_title;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex;
uint16_t m_reverseAPIChannelIndex;
bool m_hasChanged;
void paintColor();

View File

@ -91,6 +91,154 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="reverseAPILayout">
<item>
<widget class="QCheckBox" name="reverseAPI">
<property name="toolTip">
<string>Sychronize with reverse API </string>
</property>
<property name="text">
<string>reverse API</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="reverseAPIAddress">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Reverse API address</string>
</property>
<property name="inputMask">
<string>000.000.000.000</string>
</property>
<property name="text">
<string>127.0.0.1</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="reverseAPISeparator">
<property name="text">
<string>:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="reverseAPIPort">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>45</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Reverse API port</string>
</property>
<property name="inputMask">
<string>00000</string>
</property>
<property name="text">
<string>8888</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="reverseAPIDeviceLabel">
<property name="text">
<string>D</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="reverseAPIDeviceIndex">
<property name="minimumSize">
<size>
<width>22</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>22</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Reverse API destination device index</string>
</property>
<property name="inputMask">
<string>00</string>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="reverseAPIChannelLabel">
<property name="text">
<string>C</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="reverseAPIChannelIndex">
<property name="minimumSize">
<size>
<width>22</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>22</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Reverse API destination channel index</string>
</property>
<property name="inputMask">
<string>00</string>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">

View File

@ -95,6 +95,8 @@ MESSAGE_CLASS_DEFINITION(MainWindow::MsgAddChannel, Message)
MESSAGE_CLASS_DEFINITION(MainWindow::MsgDeleteChannel, Message)
MESSAGE_CLASS_DEFINITION(MainWindow::MsgDeviceSetFocus, Message)
MESSAGE_CLASS_DEFINITION(MainWindow::MsgApplySettings, Message)
MESSAGE_CLASS_DEFINITION(MainWindow::MsgAddFeature, Message)
MESSAGE_CLASS_DEFINITION(MainWindow::MsgDeleteFeature, Message)
MainWindow *MainWindow::m_instance = 0;
@ -995,6 +997,20 @@ bool MainWindow::handleMessage(const Message& cmd)
ui->tabInputsView->setCurrentIndex(index);
}
}
else if (MsgAddFeature::match(cmd))
{
MsgAddFeature& notif = (MsgAddFeature&) cmd;
ui->tabFeatures->setCurrentIndex(notif.getFeatureSetIndex());
featureAddClicked(notif.getFeatureRegistrationIndex());
return true;
}
else if (MsgDeleteFeature::match(cmd))
{
MsgDeleteFeature& notif = (MsgDeleteFeature&) cmd;
deleteFeature(notif.getFeatureSetIndex(), notif.getFeatureIndex());
return true;
}
else if (MsgApplySettings::match(cmd))
{
applySettings();
@ -1901,6 +1917,15 @@ void MainWindow::featureAddClicked(int featureIndex)
}
}
void MainWindow::deleteFeature(int featureSetIndex, int featureIndex)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_featureUIs.size()))
{
FeatureUISet *featureSet = m_featureUIs[featureSetIndex];
featureSet->deleteFeature(featureIndex);
}
}
void MainWindow::on_action_About_triggered()
{
AboutDialog dlg(m_apiHost, m_apiPort, m_settings, this);

View File

@ -288,6 +288,51 @@ private:
{ }
};
class MsgAddFeature : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getFeatureSetIndex() const { return m_featureSetIndex; }
int getFeatureRegistrationIndex() const { return m_featureRegistrationIndex; }
static MsgAddFeature* create(int featureSetIndex, int featureRegistrationIndex)
{
return new MsgAddFeature(featureSetIndex, featureRegistrationIndex);
}
private:
int m_featureSetIndex;
int m_featureRegistrationIndex;
MsgAddFeature(int featureSetIndex, int featureRegistrationIndex) :
Message(),
m_featureSetIndex(featureSetIndex),
m_featureRegistrationIndex(featureRegistrationIndex)
{ }
};
class MsgDeleteFeature : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getFeatureSetIndex() const { return m_featureSetIndex; }
int getFeatureIndex() const { return m_featureIndex; }
static MsgDeleteFeature* create(int m_featureSetIndex, int m_featureIndex) {
return new MsgDeleteFeature(m_featureSetIndex, m_featureIndex);
}
private:
int m_featureSetIndex;
int m_featureIndex;
MsgDeleteFeature(int m_featureSetIndex, int m_featureIndex) :
Message(),
m_featureSetIndex(m_featureSetIndex),
m_featureIndex(m_featureIndex)
{ }
};
enum {
PGroup,
PItem
@ -370,6 +415,7 @@ private:
void deleteChannel(int deviceSetIndex, int channelIndex);
void sampleSourceChanged(int tabIndex, int newDeviceIndex);
void sampleSinkChanged(int tabIndex, int newDeviceIndex);
void deleteFeature(int featureSetIndex, int featureIndex);
void setLoggingOptions();

View File

@ -27,6 +27,8 @@
#include "device/deviceapi.h"
#include "device/deviceuiset.h"
#include "device/deviceenumerator.h"
#include "feature/featureuiset.h"
#include "feature/feature.h"
#include "dsp/devicesamplesource.h"
#include "dsp/devicesamplesink.h"
#include "dsp/devicesamplemimo.h"
@ -69,6 +71,10 @@
#include "SWGLimeRFEDevices.h"
#include "SWGLimeRFESettings.h"
#include "SWGLimeRFEPower.h"
#include "SWGFeatureSetList.h"
#include "SWGFeatureSettings.h"
#include "SWGFeatureReport.h"
#include "SWGFeatureActions.h"
#ifdef HAS_LIMERFEUSB
#include "limerfe/limerfecontroller.h"
@ -1332,6 +1338,15 @@ int WebAPIAdapterGUI::instanceDeviceSetsGet(
return 200;
}
int WebAPIAdapterGUI::instanceFeatureSetsGet(
SWGSDRangel::SWGFeatureSetList& response,
SWGSDRangel::SWGErrorResponse& error)
{
(void) error;
getFeatureSetList(&response);
return 200;
}
int WebAPIAdapterGUI::instanceDeviceSetPost(
int direction,
SWGSDRangel::SWGSuccessResponse& response,
@ -1389,7 +1404,7 @@ int WebAPIAdapterGUI::devicesetGet(
return 404;
}
}
}
int WebAPIAdapterGUI::devicesetFocusPatch(
int deviceSetIndex,
@ -2287,7 +2302,6 @@ int WebAPIAdapterGUI::devicesetChannelSettingsGet(
}
}
int WebAPIAdapterGUI::devicesetChannelReportGet(
int deviceSetIndex,
int channelIndex,
@ -2677,6 +2691,352 @@ int WebAPIAdapterGUI::devicesetChannelSettingsPutPatch(
}
}
int WebAPIAdapterGUI::featuresetFeaturePost(
int featureSetIndex,
SWGSDRangel::SWGFeatureSettings& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
PluginAPI::FeatureRegistrations *featureRegistrations = m_mainWindow.m_pluginManager->getFeatureRegistrations();
int nbRegistrations = featureRegistrations->size();
int index = 0;
for (; index < nbRegistrations; index++)
{
if (featureRegistrations->at(index).m_featureId == *query.getFeatureType()) {
break;
}
}
if (index < nbRegistrations)
{
MainWindow::MsgAddFeature *msg = MainWindow::MsgAddFeature::create(featureSetIndex, index);
m_mainWindow.m_inputMessageQueue.push(msg);
response.init();
*response.getMessage() = QString("Message to add a feature (MsgAddFeature) was submitted successfully");
return 202;
}
else
{
error.init();
*error.getMessage() = QString("There is no feature with id %1").arg(*query.getFeatureType());
return 404;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
MainWindow::MsgDeleteFeature *msg = MainWindow::MsgDeleteFeature::create(featureSetIndex, featureIndex);
m_mainWindow.m_inputMessageQueue.push(msg);
response.init();
*response.getMessage() = QString("Message to delete a feature (MsgDeleteFeature) was submitted successfully");
return 202;
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no device set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureRunGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
response.init();
const Feature *feature = featureSet->getFeatureAt(featureIndex);
return feature->webapiRunGet(response, *error.getMessage());
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureRunPost(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
response.init();
Feature *feature = featureSet->getFeatureAt(featureIndex);
return feature->webapiRun(true, response, *error.getMessage());
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureRunDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
response.init();
Feature *feature = featureSet->getFeatureAt(featureIndex);
return feature->webapiRun(false, response, *error.getMessage());
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureSettingsGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_deviceUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
response.setFeatureType(new QString());
feature->getIdentifier(*response.getFeatureType());
return feature->webapiSettingsGet(response, *error.getMessage());
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureSettingsPutPatch(
int featureSetIndex,
int featureIndex,
bool force,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
QString featureType;
feature->getIdentifier(featureType);
if (featureType == *response.getFeatureType())
{
return feature->webapiSettingsPutPatch(force, featureSettingsKeys, response, *error.getMessage());
}
else
{
*error.getMessage() = QString("There is no feature type %1 at index %2. Found %3.")
.arg(*response.getFeatureType())
.arg(featureIndex)
.arg(featureType);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureReportGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureReport& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
response.setFeatureType(new QString());
feature->getIdentifier(*response.getFeatureType());
return feature->webapiReportGet(response, *error.getMessage());
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureIndex);
return 404;
}
}
int WebAPIAdapterGUI::featuresetFeatureActionsPost(
int featureSetIndex,
int featureIndex,
const QStringList& featureActionsKeys,
SWGSDRangel::SWGFeatureActions& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
QString featureType;
feature->getIdentifier(featureType);
if (featureType == *query.getFeatureType())
{
int res = feature->webapiActionsPost(featureActionsKeys, query, *error.getMessage());
if (res/100 == 2)
{
response.init();
*response.getMessage() = QString("Message to post action was submitted successfully");
}
return res;
}
else
{
*error.getMessage() = QString("There is no feature type %1 at index %2. Found %3.")
.arg(*query.getFeatureType())
.arg(featureIndex)
.arg(featureType);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureIndex);
return 404;
}
}
void WebAPIAdapterGUI::getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSetList)
{
deviceSetList->init();
@ -2969,6 +3329,63 @@ void WebAPIAdapterGUI::getChannelsDetail(SWGSDRangel::SWGChannelsDetail *channel
}
}
int WebAPIAdapterGUI::featuresetGet(
int featureSetIndex,
SWGSDRangel::SWGFeatureSet& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainWindow.m_featureUIs.size()))
{
const FeatureUISet *featureSet = m_mainWindow.m_featureUIs[featureSetIndex];
getFeatureSet(&response, featureSet, featureSetIndex);
return 200;
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
void WebAPIAdapterGUI::getFeatureSetList(SWGSDRangel::SWGFeatureSetList* featureSetList)
{
featureSetList->init();
featureSetList->setFeaturesetcount((int) m_mainWindow.m_featureUIs.size());
std::vector<FeatureUISet*>::const_iterator it = m_mainWindow.m_featureUIs.begin();
for (int i = 0; it != m_mainWindow.m_featureUIs.end(); ++it, i++)
{
QList<SWGSDRangel::SWGFeatureSet*> *featureSets = featureSetList->getFeatureSets();
featureSets->append(new SWGSDRangel::SWGFeatureSet());
getFeatureSet(featureSets->back(), *it, i);
}
}
void WebAPIAdapterGUI::getFeatureSet(SWGSDRangel::SWGFeatureSet *featureSet, const FeatureUISet* featureUISet, int featureUISetIndex)
{
featureSet->init();
featureSet->setFeaturecount(featureUISet->getNumberOfFeatures());
QList<SWGSDRangel::SWGFeature*> *features = featureSet->getFeatures();
for (int i = 0; i < featureUISet->getNumberOfFeatures(); i++)
{
const Feature *feature = featureUISet->getFeatureAt(i);
features->append(new SWGSDRangel::SWGFeature);
features->back()->setIndex(i);
QString s;
feature->getTitle(s);
features->back()->setTitle(new QString(s));
feature->getIdentifier(s);
features->back()->setId(new QString(s));
features->back()->setUid(feature->getUID());
}
}
QtMsgType WebAPIAdapterGUI::getMsgTypeFromString(const QString& msgTypeString)
{
if (msgTypeString == "debug") {

View File

@ -193,6 +193,10 @@ public:
SWGSDRangel::SWGDeviceSetList& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int instanceFeatureSetsGet(
SWGSDRangel::SWGFeatureSetList& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int instanceDeviceSetPost(
int direction,
SWGSDRangel::SWGSuccessResponse& response,
@ -320,12 +324,77 @@ public:
SWGSDRangel::SWGChannelReport& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetGet(
int deviceSetIndex,
SWGSDRangel::SWGFeatureSet& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeaturePost(
int featureSetIndex,
SWGSDRangel::SWGFeatureSettings& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureRunGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureRunPost(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureRunDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureSettingsGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureSettingsPutPatch(
int featureSetIndex,
int featureIndex,
bool force,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureReportGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureReport& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureActionsPost(
int featureSetIndex,
int featureIndex,
const QStringList& featureActionsKeys,
SWGSDRangel::SWGFeatureActions& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error);
private:
MainWindow& m_mainWindow;
void getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSetList);
void getDeviceSet(SWGSDRangel::SWGDeviceSet *deviceSet, const DeviceUISet* deviceUISet, int deviceUISetIndex);
void getChannelsDetail(SWGSDRangel::SWGChannelsDetail *channelsDetail, const DeviceUISet* deviceUISet);
void getFeatureSetList(SWGSDRangel::SWGFeatureSetList* featureSetList);
void getFeatureSet(SWGSDRangel::SWGFeatureSet *featureSet, const FeatureUISet* featureUISet, int featureUISetIndex);
static QtMsgType getMsgTypeFromString(const QString& msgTypeString);
static void getMsgTypeString(const QtMsgType& msgType, QString& level);
};

View File

@ -3,12 +3,14 @@ project (sdrsrv)
set(sdrsrv_SOURCES
maincore.cpp
device/deviceset.cpp
feature/featureset.cpp
webapi/webapiadaptersrv.cpp
)
set(sdrsrv_HEADERS
maincore.h
device/deviceset.h
feature/featureset.h
webapi/webapiadaptersrv.h
)

View File

@ -0,0 +1,102 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 <QList>
#include "plugin/pluginapi.h"
#include "feature/feature.h"
#include "featureset.h"
FeatureSet::FeatureSet(int tabIndex)
{
m_featureTabIndex = tabIndex;
}
FeatureSet::~FeatureSet()
{
}
void FeatureSet::addFeature(int selectedFeatureIndex, PluginAPI *pluginAPI, WebAPIAdapterInterface *apiAdapter)
{
PluginAPI::FeatureRegistrations *featureRegistrations = pluginAPI->getFeatureRegistrations(); // Available feature plugins
Feature *feature = featureRegistrations->at(selectedFeatureIndex).m_plugin->createFeature(apiAdapter);
QString featureName;
feature->getIdentifier(featureName);
m_featureInstanceRegistrations.append(FeatureInstanceRegistration(featureName, feature));
renameFeatureInstances();
}
void FeatureSet::removeFeatureInstance(Feature* feature)
{
for (FeatureInstanceRegistrations::iterator it = m_featureInstanceRegistrations.begin(); it != m_featureInstanceRegistrations.end(); ++it)
{
if (it->m_feature == feature)
{
m_featureInstanceRegistrations.erase(it);
break;
}
}
renameFeatureInstances();
}
void FeatureSet::renameFeatureInstances()
{
for (int i = 0; i < m_featureInstanceRegistrations.count(); i++) {
m_featureInstanceRegistrations[i].m_feature->setName(QString("%1:%2").arg(m_featureInstanceRegistrations[i].m_featureName).arg(i));
}
}
void FeatureSet::freeFeatures()
{
for(int i = 0; i < m_featureInstanceRegistrations.count(); i++)
{
qDebug("FeatureSet::freeFeatures: destroying feature [%s]", qPrintable(m_featureInstanceRegistrations[i].m_featureName));
m_featureInstanceRegistrations[i].m_feature->destroy();
}
}
void FeatureSet::deleteFeature(int featureIndex)
{
if ((featureIndex >= 0) && (featureIndex < m_featureInstanceRegistrations.count()))
{
qDebug("FeatureSet::deleteFeature: delete feature [%s] at %d",
qPrintable(m_featureInstanceRegistrations[featureIndex].m_featureName),
featureIndex);
m_featureInstanceRegistrations[featureIndex].m_feature->destroy();
m_featureInstanceRegistrations.removeAt(featureIndex);
renameFeatureInstances();
}
}
const Feature *FeatureSet::getFeatureAt(int featureIndex) const
{
if ((featureIndex >= 0) && (featureIndex < m_featureInstanceRegistrations.count())) {
return m_featureInstanceRegistrations[featureIndex].m_feature;
} else{
return nullptr;
}
}
Feature *FeatureSet::getFeatureAt(int featureIndex)
{
if ((featureIndex >= 0) && (featureIndex < m_featureInstanceRegistrations.count())) {
return m_featureInstanceRegistrations[featureIndex].m_feature;
} else{
return nullptr;
}
}

View File

@ -0,0 +1,71 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 SDRSRV_FEATURE_FEATURESET_H_
#define SDRSRV_FEATURE_FEATURESET_H_
#include <QString>
#include <QList>
#include "export.h"
class PluginAPI;
class Feature;
class WebAPIAdapterInterface;
class SDRGUI_API FeatureSet
{
public:
FeatureSet(int tabIndex);
~FeatureSet();
int getNumberOfFeatures() const { return m_featureInstanceRegistrations.size(); }
void addFeature(int selectedFeatureIndex, PluginAPI *pluginAPI, WebAPIAdapterInterface *apiAdapter);
void removeFeatureInstance(Feature* feature);
void freeFeatures();
void deleteFeature(int featureIndex);
const Feature *getFeatureAt(int featureIndex) const;
Feature *getFeatureAt(int featureIndex);
private:
struct FeatureInstanceRegistration
{
QString m_featureName;
Feature* m_feature;
FeatureInstanceRegistration() :
m_featureName(),
m_feature(nullptr)
{ }
FeatureInstanceRegistration(const QString& featureName, Feature *feature) :
m_featureName(featureName),
m_feature(feature)
{ }
bool operator<(const FeatureInstanceRegistration& other) const;
};
typedef QList<FeatureInstanceRegistration> FeatureInstanceRegistrations;
FeatureInstanceRegistrations m_featureInstanceRegistrations;
int m_featureTabIndex;
void renameFeatureInstances();
};
#endif // SDRSRV_FEATURE_FEATURESET_H_

View File

@ -28,6 +28,7 @@
#include "device/deviceapi.h"
#include "device/deviceset.h"
#include "device/deviceenumerator.h"
#include "feature/featureset.h"
#include "plugin/pluginmanager.h"
#include "loggerwithfile.h"
#include "webapi/webapirequestmapper.h"
@ -46,6 +47,8 @@ MESSAGE_CLASS_DEFINITION(MainCore::MsgSetDevice, Message)
MESSAGE_CLASS_DEFINITION(MainCore::MsgAddChannel, Message)
MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteChannel, Message)
MESSAGE_CLASS_DEFINITION(MainCore::MsgApplySettings, Message)
MESSAGE_CLASS_DEFINITION(MainCore::MsgAddFeature, Message)
MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteFeature, Message)
MainCore *MainCore::m_instance = 0;
@ -190,6 +193,19 @@ bool MainCore::handleMessage(const Message& cmd)
deleteChannel(notif.getDeviceSetIndex(), notif.getChannelIndex());
return true;
}
else if (MsgAddFeature::match(cmd))
{
MsgAddFeature& notif = (MsgAddFeature&) cmd;
addFeature(notif.getFeatureSetIndex(), notif.getFeatureRegistrationIndex());
return true;
}
else if (MsgDeleteFeature::match(cmd))
{
MsgDeleteFeature& notif = (MsgDeleteFeature&) cmd;
deleteFeature(notif.getFeatureSetIndex(), notif.getFeatureIndex());
return true;
}
else if (MsgApplySettings::match(cmd))
{
applySettings();
@ -645,6 +661,24 @@ void MainCore::deleteChannel(int deviceSetIndex, int channelIndex)
}
}
void MainCore::addFeature(int featureSetIndex, int featureIndex)
{
if (featureSetIndex >= 0)
{
FeatureSet *featureSet = m_featureSets[featureSetIndex];
featureSet->addFeature(featureSetIndex, m_pluginManager->getPluginAPI(), m_apiAdapter);
}
}
void MainCore::deleteFeature(int featureSetIndex, int featureIndex)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_featureSets.size()))
{
FeatureSet *featureSet = m_featureSets[featureSetIndex];
featureSet->deleteFeature(featureIndex);
}
}
void MainCore::loadPresetSettings(const Preset* preset, int tabIndex)
{
qDebug("MainCore::loadPresetSettings: preset [%s | %s]",

View File

@ -37,6 +37,7 @@ class PluginInterface;
class PluginManager;
class ChannelMarker;
class DeviceSet;
class FeatureSet;
class WebAPIRequestMapper;
class WebAPIServer;
class WebAPIAdapterSrv;
@ -67,6 +68,8 @@ public:
void changeSampleMIMO(int deviceSetIndex, int selectedDeviceIndex);
void addChannel(int deviceSetIndex, int selectedChannelIndex);
void deleteChannel(int deviceSetIndex, int channelIndex);
void addFeature(int featureSetIndex, int featureIndex);
void deleteFeature(int featureSetIndex, int featureIndex);
const QString& getAPIHost() const { return m_apiHost; }
int getAPIPort() const { return m_apiPort; }
@ -285,6 +288,51 @@ private:
{ }
};
class MsgAddFeature : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getFeatureSetIndex() const { return m_featureSetIndex; }
int getFeatureRegistrationIndex() const { return m_featureRegistrationIndex; }
static MsgAddFeature* create(int featureSetIndex, int featureRegistrationIndex)
{
return new MsgAddFeature(featureSetIndex, featureRegistrationIndex);
}
private:
int m_featureSetIndex;
int m_featureRegistrationIndex;
MsgAddFeature(int featureSetIndex, int featureRegistrationIndex) :
Message(),
m_featureSetIndex(featureSetIndex),
m_featureRegistrationIndex(featureRegistrationIndex)
{ }
};
class MsgDeleteFeature : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getFeatureSetIndex() const { return m_featureSetIndex; }
int getFeatureIndex() const { return m_featureIndex; }
static MsgDeleteFeature* create(int m_featureSetIndex, int m_featureIndex) {
return new MsgDeleteFeature(m_featureSetIndex, m_featureIndex);
}
private:
int m_featureSetIndex;
int m_featureIndex;
MsgDeleteFeature(int m_featureSetIndex, int m_featureIndex) :
Message(),
m_featureSetIndex(m_featureSetIndex),
m_featureIndex(m_featureIndex)
{ }
};
static MainCore *m_instance;
MainSettings m_settings;
int m_masterTabIndex;
@ -297,6 +345,7 @@ private:
MessageQueue m_inputMessageQueue;
QTimer m_masterTimer;
std::vector<DeviceSet*> m_deviceSets;
std::vector<FeatureSet*> m_featureSets;
PluginManager* m_pluginManager;
WebAPIRequestMapper *m_requestMapper;

View File

@ -48,6 +48,10 @@
#include "SWGLimeRFEDevices.h"
#include "SWGLimeRFESettings.h"
#include "SWGLimeRFEPower.h"
#include "SWGFeatureSetList.h"
#include "SWGFeatureSettings.h"
#include "SWGFeatureReport.h"
#include "SWGFeatureActions.h"
#include "maincore.h"
#include "loggerwithfile.h"
@ -62,6 +66,8 @@
#include "dsp/dspdevicemimoengine.h"
#include "dsp/dspengine.h"
#include "channel/channelapi.h"
#include "feature/featureset.h"
#include "feature/feature.h"
#include "plugin/pluginapi.h"
#include "plugin/pluginmanager.h"
#include "util/serialutil.h"
@ -1440,6 +1446,15 @@ int WebAPIAdapterSrv::instanceDeviceSetsGet(
return 200;
}
int WebAPIAdapterSrv::instanceFeatureSetsGet(
SWGSDRangel::SWGFeatureSetList& response,
SWGSDRangel::SWGErrorResponse& error)
{
(void) error;
getFeatureSetList(&response);
return 200;
}
int WebAPIAdapterSrv::instanceDeviceSetPost(
int direction,
SWGSDRangel::SWGSuccessResponse& response,
@ -2779,6 +2794,352 @@ int WebAPIAdapterSrv::devicesetChannelSettingsPutPatch(
}
}
int WebAPIAdapterSrv::featuresetFeaturePost(
int featureSetIndex,
SWGSDRangel::SWGFeatureSettings& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
PluginAPI::FeatureRegistrations *featureRegistrations = m_mainCore.m_pluginManager->getFeatureRegistrations();
int nbRegistrations = featureRegistrations->size();
int index = 0;
for (; index < nbRegistrations; index++)
{
if (featureRegistrations->at(index).m_featureId == *query.getFeatureType()) {
break;
}
}
if (index < nbRegistrations)
{
MainCore::MsgAddFeature *msg = MainCore::MsgAddFeature::create(featureSetIndex, index);
m_mainCore.m_inputMessageQueue.push(msg);
response.init();
*response.getMessage() = QString("Message to add a feature (MsgAddFeature) was submitted successfully");
return 202;
}
else
{
error.init();
*error.getMessage() = QString("There is no feature with id %1").arg(*query.getFeatureType());
return 404;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
MainCore::MsgDeleteFeature *msg = MainCore::MsgDeleteFeature::create(featureSetIndex, featureIndex);
m_mainCore.m_inputMessageQueue.push(msg);
response.init();
*response.getMessage() = QString("Message to delete a feature (MsgDeleteFeature) was submitted successfully");
return 202;
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no device set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureRunGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
response.init();
const Feature *feature = featureSet->getFeatureAt(featureIndex);
return feature->webapiRunGet(response, *error.getMessage());
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureRunPost(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
response.init();
Feature *feature = featureSet->getFeatureAt(featureIndex);
return feature->webapiRun(true, response, *error.getMessage());
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureRunDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
if (featureIndex < featureSet->getNumberOfFeatures())
{
response.init();
Feature *feature = featureSet->getFeatureAt(featureIndex);
return feature->webapiRun(false, response, *error.getMessage());
}
else
{
error.init();
*error.getMessage() = QString("There is no feature at index %1. %2 feature(s) left")
.arg(featureIndex)
.arg(featureSet->getNumberOfFeatures());
return 400;
}
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureSettingsGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
response.setFeatureType(new QString());
feature->getIdentifier(*response.getFeatureType());
return feature->webapiSettingsGet(response, *error.getMessage());
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureSettingsPutPatch(
int featureSetIndex,
int featureIndex,
bool force,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
QString featureType;
feature->getIdentifier(featureType);
if (featureType == *response.getFeatureType())
{
return feature->webapiSettingsPutPatch(force, featureSettingsKeys, response, *error.getMessage());
}
else
{
*error.getMessage() = QString("There is no feature type %1 at index %2. Found %3.")
.arg(*response.getFeatureType())
.arg(featureIndex)
.arg(featureType);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureReportGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureReport& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
response.setFeatureType(new QString());
feature->getIdentifier(*response.getFeatureType());
return feature->webapiReportGet(response, *error.getMessage());
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureIndex);
return 404;
}
}
int WebAPIAdapterSrv::featuresetFeatureActionsPost(
int featureSetIndex,
int featureIndex,
const QStringList& featureActionsKeys,
SWGSDRangel::SWGFeatureActions& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error)
{
error.init();
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (feature)
{
QString featureType;
feature->getIdentifier(featureType);
if (featureType == *query.getFeatureType())
{
int res = feature->webapiActionsPost(featureActionsKeys, query, *error.getMessage());
if (res/100 == 2)
{
response.init();
*response.getMessage() = QString("Message to post action was submitted successfully");
}
return res;
}
else
{
*error.getMessage() = QString("There is no feature type %1 at index %2. Found %3.")
.arg(*query.getFeatureType())
.arg(featureIndex)
.arg(featureType);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature with index %1").arg(featureIndex);
return 404;
}
}
else
{
*error.getMessage() = QString("There is no feature set with index %1").arg(featureIndex);
return 404;
}
}
void WebAPIAdapterSrv::getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSetList)
{
deviceSetList->init();
@ -3067,6 +3428,63 @@ void WebAPIAdapterSrv::getChannelsDetail(SWGSDRangel::SWGChannelsDetail *channel
}
}
int WebAPIAdapterSrv::featuresetGet(
int featureSetIndex,
SWGSDRangel::SWGFeatureSet& response,
SWGSDRangel::SWGErrorResponse& error)
{
if ((featureSetIndex >= 0) && (featureSetIndex < (int) m_mainCore.m_featureSets.size()))
{
const FeatureSet *featureSet = m_mainCore.m_featureSets[featureSetIndex];
getFeatureSet(&response, featureSet, featureSetIndex);
return 200;
}
else
{
error.init();
*error.getMessage() = QString("There is no feature set with index %1").arg(featureSetIndex);
return 404;
}
}
void WebAPIAdapterSrv::getFeatureSetList(SWGSDRangel::SWGFeatureSetList* featureSetList)
{
featureSetList->init();
featureSetList->setFeaturesetcount((int) m_mainCore.m_featureSets.size());
std::vector<FeatureSet*>::const_iterator it = m_mainCore.m_featureSets.begin();
for (int i = 0; it != m_mainCore.m_featureSets.end(); ++it, i++)
{
QList<SWGSDRangel::SWGFeatureSet*> *featureSets = featureSetList->getFeatureSets();
featureSets->append(new SWGSDRangel::SWGFeatureSet());
getFeatureSet(featureSets->back(), *it, i);
}
}
void WebAPIAdapterSrv::getFeatureSet(SWGSDRangel::SWGFeatureSet *swgFeatureSet, const FeatureSet* featureSet, int featureSetIndex)
{
swgFeatureSet->init();
swgFeatureSet->setFeaturecount(featureSet->getNumberOfFeatures());
QList<SWGSDRangel::SWGFeature*> *features = swgFeatureSet->getFeatures();
for (int i = 0; i < featureSet->getNumberOfFeatures(); i++)
{
const Feature *feature = featureSet->getFeatureAt(i);
features->append(new SWGSDRangel::SWGFeature);
features->back()->setIndex(i);
QString s;
feature->getTitle(s);
features->back()->setTitle(new QString(s));
feature->getIdentifier(s);
features->back()->setId(new QString(s));
features->back()->setUid(feature->getUID());
}
}
QtMsgType WebAPIAdapterSrv::getMsgTypeFromString(const QString& msgTypeString)
{
if (msgTypeString == "debug") {

View File

@ -26,6 +26,7 @@
class MainCore;
class DeviceSet;
class FeatureSet;
class WebAPIAdapterSrv: public WebAPIAdapterInterface
{
@ -203,6 +204,10 @@ public:
SWGSDRangel::SWGDeviceSetList& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int instanceFeatureSetsGet(
SWGSDRangel::SWGFeatureSetList& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int instanceDeviceSetPost(
int direction,
SWGSDRangel::SWGSuccessResponse& response,
@ -330,12 +335,77 @@ public:
SWGSDRangel::SWGChannelReport& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetGet(
int deviceSetIndex,
SWGSDRangel::SWGFeatureSet& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeaturePost(
int featureSetIndex,
SWGSDRangel::SWGFeatureSettings& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureRunGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureRunPost(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureRunDelete(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGDeviceState& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureSettingsGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureSettingsPutPatch(
int featureSetIndex,
int featureIndex,
bool force,
const QStringList& featureSettingsKeys,
SWGSDRangel::SWGFeatureSettings& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureReportGet(
int featureSetIndex,
int featureIndex,
SWGSDRangel::SWGFeatureReport& response,
SWGSDRangel::SWGErrorResponse& error);
virtual int featuresetFeatureActionsPost(
int featureSetIndex,
int featureIndex,
const QStringList& featureActionsKeys,
SWGSDRangel::SWGFeatureActions& query,
SWGSDRangel::SWGSuccessResponse& response,
SWGSDRangel::SWGErrorResponse& error);
private:
MainCore& m_mainCore;
void getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSetList);
void getDeviceSet(SWGSDRangel::SWGDeviceSet *swgDeviceSet, const DeviceSet* deviceSet, int deviceUISetIndex);
void getChannelsDetail(SWGSDRangel::SWGChannelsDetail *channelsDetail, const DeviceSet* deviceSet);
void getFeatureSetList(SWGSDRangel::SWGFeatureSetList* featureSetList);
void getFeatureSet(SWGSDRangel::SWGFeatureSet *swgFeatureSet, const FeatureSet* featureSet, int featureSetIndex);
static QtMsgType getMsgTypeFromString(const QString& msgTypeString);
static void getMsgTypeString(const QtMsgType& msgType, QString& level);
};

View File

@ -38907,7 +38907,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2020-09-28T13:19:26.040+02:00
Generated 2020-09-28T13:34:44.975+02:00
</div>
</div>
</div>