From 270fd955ae336009b7bccc31960c8398b7420c85 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 6 May 2020 09:50:43 +0200 Subject: [PATCH] Websocket spectrum: server implementation --- sdrbase/dsp/spectrumvis.cpp | 3 + sdrsrv/device/deviceset.cpp | 504 +++++ sdrsrv/device/deviceset.h | 104 + sdrsrv/maincore.cpp | 718 +++++++ sdrsrv/webapi/webapiadaptersrv.cpp | 3203 ++++++++++++++++++++++++++++ sdrsrv/webapi/webapiadaptersrv.h | 370 ++++ 6 files changed, 4902 insertions(+) create mode 100644 sdrsrv/device/deviceset.cpp create mode 100644 sdrsrv/device/deviceset.h create mode 100644 sdrsrv/maincore.cpp create mode 100644 sdrsrv/webapi/webapiadaptersrv.cpp create mode 100644 sdrsrv/webapi/webapiadaptersrv.h diff --git a/sdrbase/dsp/spectrumvis.cpp b/sdrbase/dsp/spectrumvis.cpp index f0bc08d13..8370d7fed 100644 --- a/sdrbase/dsp/spectrumvis.cpp +++ b/sdrbase/dsp/spectrumvis.cpp @@ -20,6 +20,7 @@ #include "SWGGLSpectrum.h" #include "SWGSpectrumServer.h" +#include "SWGSuccessResponse.h" #include "glspectruminterface.h" #include "dspcommands.h" @@ -850,6 +851,7 @@ int SpectrumVis::webapiSpectrumServerPost(SWGSDRangel::SWGSuccessResponse& respo getMessageQueueToGUI()->push(msgToGui); } + response.setMessage(new QString("Websocket spectrum server started")); return 200; } @@ -865,6 +867,7 @@ int SpectrumVis::webapiSpectrumServerDelete(SWGSDRangel::SWGSuccessResponse& res getMessageQueueToGUI()->push(msgToGui); } + response.setMessage(new QString("Websocket spectrum server stopped")); return 200; } diff --git a/sdrsrv/device/deviceset.cpp b/sdrsrv/device/deviceset.cpp new file mode 100644 index 000000000..bc6f86ce4 --- /dev/null +++ b/sdrsrv/device/deviceset.cpp @@ -0,0 +1,504 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "dsp/dspdevicesourceengine.h" +#include "dsp/dspdevicesinkengine.h" +#include "dsp/spectrumvis.h" +#include "plugin/pluginapi.h" +#include "plugin/plugininterface.h" +#include "settings/preset.h" +#include "channel/channelapi.h" +#include "channel/channelutils.h" +#include "settings/preset.h" + +#include "deviceset.h" + + +DeviceSet::ChannelInstanceRegistration::ChannelInstanceRegistration(const QString& channelName, ChannelAPI* channelAPI) : + m_channelName(channelName), + m_channelAPI(channelAPI) +{} + +DeviceSet::DeviceSet(int tabIndex, int deviceType) +{ + m_deviceAPI = nullptr; + m_deviceSourceEngine = nullptr; + m_deviceSinkEngine = nullptr; + m_deviceMIMOEngine = nullptr; + m_deviceTabIndex = tabIndex; + + if ((deviceType == 0) || (deviceType == 2)) { // Single Rx or MIMO + m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF); + } else if (deviceType == 1) { // Single Tx + m_spectrumVis = new SpectrumVis(SDR_TX_SCALEF); + } +} + +DeviceSet::~DeviceSet() +{ + delete m_spectrumVis; +} + +void DeviceSet::registerRxChannelInstance(const QString& channelName, ChannelAPI* channelAPI) +{ + m_channelInstanceRegistrations.append(ChannelInstanceRegistration(channelName, channelAPI)); + renameChannelInstances(); +} + +void DeviceSet::registerTxChannelInstance(const QString& channelName, ChannelAPI* channelAPI) +{ + m_channelInstanceRegistrations.append(ChannelInstanceRegistration(channelName, channelAPI)); + renameChannelInstances(); +} + +void DeviceSet::registerChannelInstance(const QString& channelName, ChannelAPI* channelAPI) +{ + m_channelInstanceRegistrations.append(ChannelInstanceRegistration(channelName, channelAPI)); + renameChannelInstances(); +} + +void DeviceSet::removeRxChannelInstance(ChannelAPI* channelAPI) +{ + for (ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it) + { + if (it->m_channelAPI == channelAPI) + { + m_channelInstanceRegistrations.erase(it); + break; + } + } + + renameChannelInstances(); +} + +void DeviceSet::removeTxChannelInstance(ChannelAPI* channelAPI) +{ + for(ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it) + { + if(it->m_channelAPI == channelAPI) + { + m_channelInstanceRegistrations.erase(it); + break; + } + } + + renameChannelInstances(); +} + +void DeviceSet::removeChannelInstance(ChannelAPI* channelAPI) +{ + for(ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it) + { + if(it->m_channelAPI == channelAPI) + { + m_channelInstanceRegistrations.erase(it); + break; + } + } + + renameChannelInstances(); +} + +void DeviceSet::freeChannels() +{ + for(int i = 0; i < m_channelInstanceRegistrations.count(); i++) + { + qDebug("DeviceSet::freeChannels: destroying channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelName)); + m_channelInstanceRegistrations[i].m_channelAPI->destroy(); + } +} + +void DeviceSet::deleteChannel(int channelIndex) +{ + if (channelIndex < m_channelInstanceRegistrations.count()) + { + m_channelInstanceRegistrations[channelIndex].m_channelAPI->destroy(); + m_channelInstanceRegistrations.removeAt(channelIndex); + renameChannelInstances(); + } +} + +void DeviceSet::addRxChannel(int selectedChannelIndex, PluginAPI *pluginAPI) +{ + PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getRxChannelRegistrations(); // Available channel plugins + ChannelAPI *rxChannel =(*channelRegistrations)[selectedChannelIndex].m_plugin->createRxChannelCS(m_deviceAPI); + ChannelInstanceRegistration reg = ChannelInstanceRegistration(rxChannel->getName(), rxChannel); + m_channelInstanceRegistrations.append(reg); + qDebug("DeviceSet::addRxChannel: %s", qPrintable(rxChannel->getName())); +} + +void DeviceSet::addTxChannel(int selectedChannelIndex, PluginAPI *pluginAPI) +{ + PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getTxChannelRegistrations(); // Available channel plugins + ChannelAPI *txChannel = (*channelRegistrations)[selectedChannelIndex].m_plugin->createTxChannelCS(m_deviceAPI); + ChannelInstanceRegistration reg = ChannelInstanceRegistration(txChannel->getName(), txChannel); + m_channelInstanceRegistrations.append(reg); + qDebug("DeviceSet::addTxChannel: %s", qPrintable(txChannel->getName())); +} + +void DeviceSet::addMIMOChannel(int selectedChannelIndex, PluginAPI *pluginAPI) +{ + PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getMIMOChannelRegistrations(); // Available channel plugins + ChannelAPI *mimoChannel = (*channelRegistrations)[selectedChannelIndex].m_plugin->createMIMOChannelCS(m_deviceAPI); + ChannelInstanceRegistration reg = ChannelInstanceRegistration(mimoChannel->getName(), mimoChannel); + m_channelInstanceRegistrations.append(reg); + qDebug("DeviceSet::addMIMOChannel: %s", qPrintable(mimoChannel->getName())); +} + +void DeviceSet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginAPI) +{ + if (preset->isSourcePreset()) + { + qDebug("DeviceSet::loadChannelSettings: Loading preset [%s | %s]", qPrintable(preset->getGroup()), qPrintable(preset->getDescription())); + + // Available channel plugins + PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getRxChannelRegistrations(); + + // copy currently open channels and clear list + ChannelInstanceRegistrations openChannels = m_channelInstanceRegistrations; + m_channelInstanceRegistrations.clear(); + + qDebug("DeviceSet::loadChannelSettings: %d channel(s) in preset", preset->getChannelCount()); + + for (int i = 0; i < preset->getChannelCount(); i++) + { + const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i); + ChannelInstanceRegistration reg; + + // if we have one instance available already, use it + + for (int i = 0; i < openChannels.count(); i++) + { + qDebug("DeviceSet::loadChannelSettings: channels compare [%s] vs [%s]", qPrintable(openChannels[i].m_channelName), qPrintable(channelConfig.m_channelIdURI)); + + //if(openChannels[i].m_channelName == channelConfig.m_channelIdURI) + if (ChannelUtils::compareChannelURIs(openChannels[i].m_channelName, channelConfig.m_channelIdURI)) + { + qDebug("DeviceSet::loadChannelSettings: channel [%s] found", qPrintable(openChannels[i].m_channelName)); + reg = openChannels.takeAt(i); + m_channelInstanceRegistrations.append(reg); + break; + } + } + + // if we haven't one already, create one + + if (reg.m_channelAPI == nullptr) + { + for (int i = 0; i < channelRegistrations->count(); i++) + { + //if((*channelRegistrations)[i].m_channelIdURI == channelConfig.m_channelIdURI) + if (ChannelUtils::compareChannelURIs((*channelRegistrations)[i].m_channelIdURI, channelConfig.m_channelIdURI)) + { + qDebug("DeviceSet::loadChannelSettings: creating new channel [%s] from config [%s]", + qPrintable((*channelRegistrations)[i].m_channelIdURI), + qPrintable(channelConfig.m_channelIdURI)); + ChannelAPI *rxChannel = (*channelRegistrations)[i].m_plugin->createRxChannelCS(m_deviceAPI); + reg = ChannelInstanceRegistration(channelConfig.m_channelIdURI, rxChannel); + m_channelInstanceRegistrations.append(reg); + break; + } + } + } + + if (reg.m_channelAPI != nullptr) + { + qDebug("DeviceSet::loadChannelSettings: deserializing channel [%s]", qPrintable(channelConfig.m_channelIdURI)); + reg.m_channelAPI->deserialize(channelConfig.m_config); + } + } + + // everything, that is still "available" is not needed anymore + for (int i = 0; i < openChannels.count(); i++) + { + qDebug("DeviceSet::loadChannelSettings: destroying spare channel [%s]", qPrintable(openChannels[i].m_channelName)); + openChannels[i].m_channelAPI->destroy(); + } + + renameChannelInstances(); + } + else + { + qDebug("DeviceSet::loadChannelSettings: Loading preset [%s | %s] not a source preset", qPrintable(preset->getGroup()), qPrintable(preset->getDescription())); + } +} + +void DeviceSet::saveRxChannelSettings(Preset *preset) +{ + if (preset->isSourcePreset()) + { + std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end()); // sort by increasing delta frequency and type + + for (int i = 0; i < m_channelInstanceRegistrations.count(); i++) + { + qDebug("DeviceSet::saveChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i].m_channelName)); + preset->addChannel(m_channelInstanceRegistrations[i].m_channelName, m_channelInstanceRegistrations[i].m_channelAPI->serialize()); + } + } + else + { + qDebug("DeviceSet::saveChannelSettings: not a source preset"); + } +} + +void DeviceSet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginAPI) +{ + if (preset->isSinkPreset()) + { + qDebug("DeviceSet::loadTxChannelSettings: Loading preset [%s | %s]", qPrintable(preset->getGroup()), qPrintable(preset->getDescription())); + + // Available channel plugins + PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getTxChannelRegistrations(); + + // copy currently open channels and clear list + ChannelInstanceRegistrations openChannels = m_channelInstanceRegistrations; + m_channelInstanceRegistrations.clear(); + + qDebug("DeviceSet::loadTxChannelSettings: %d channel(s) in preset", preset->getChannelCount()); + + for (int i = 0; i < preset->getChannelCount(); i++) + { + const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i); + ChannelInstanceRegistration reg; + + // if we have one instance available already, use it + + for (int i = 0; i < openChannels.count(); i++) + { + qDebug("DeviceSet::loadTxChannelSettings: channels compare [%s] vs [%s]", qPrintable(openChannels[i].m_channelName), qPrintable(channelConfig.m_channelIdURI)); + + if (openChannels[i].m_channelName == channelConfig.m_channelIdURI) + { + qDebug("DeviceSet::loadTxChannelSettings: channel [%s] found", qPrintable(openChannels[i].m_channelName)); + reg = openChannels.takeAt(i); + m_channelInstanceRegistrations.append(reg); + break; + } + } + + // if we haven't one already, create one + + if (reg.m_channelAPI == nullptr) + { + for (int i = 0; i < channelRegistrations->count(); i++) + { + if ((*channelRegistrations)[i].m_channelIdURI == channelConfig.m_channelIdURI) + { + qDebug("DeviceSet::loadTxChannelSettings: creating new channel [%s]", qPrintable(channelConfig.m_channelIdURI)); + ChannelAPI *txChannel = (*channelRegistrations)[i].m_plugin->createTxChannelCS(m_deviceAPI); + reg = ChannelInstanceRegistration(channelConfig.m_channelIdURI, txChannel); + m_channelInstanceRegistrations.append(reg); + break; + } + } + } + + if (reg.m_channelAPI != nullptr) + { + qDebug("DeviceSet::loadTxChannelSettings: deserializing channel [%s]", qPrintable(channelConfig.m_channelIdURI)); + reg.m_channelAPI->deserialize(channelConfig.m_config); + } + } + + // everything, that is still "available" is not needed anymore + for (int i = 0; i < openChannels.count(); i++) + { + qDebug("DeviceSet::loadTxChannelSettings: destroying spare channel [%s]", qPrintable(openChannels[i].m_channelName)); + openChannels[i].m_channelAPI->destroy(); + } + + renameChannelInstances(); + } + else + { + qDebug("DeviceSet::loadTxChannelSettings: Loading preset [%s | %s] not a sink preset", qPrintable(preset->getGroup()), qPrintable(preset->getDescription())); + } + +} + +void DeviceSet::saveTxChannelSettings(Preset *preset) +{ + if (preset->isSinkPreset()) + { + std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end()); // sort by increasing delta frequency and type + + for (int i = 0; i < m_channelInstanceRegistrations.count(); i++) + { + qDebug("DeviceSet::saveTxChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i].m_channelName)); + preset->addChannel(m_channelInstanceRegistrations[i].m_channelName, m_channelInstanceRegistrations[i].m_channelAPI->serialize()); + } + } + else + { + qDebug("DeviceSet::saveTxChannelSettings: not a sink preset"); + } +} + +void DeviceSet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *pluginAPI) +{ + if (preset->isMIMOPreset()) + { + qDebug("DeviceSet::loadMIMOChannelSettings: Loading preset [%s | %s]", qPrintable(preset->getGroup()), qPrintable(preset->getDescription())); + + // Available channel plugins + PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getMIMOChannelRegistrations(); + + // copy currently open channels and clear list + ChannelInstanceRegistrations openChannels = m_channelInstanceRegistrations; + m_channelInstanceRegistrations.clear(); + + qDebug("DeviceSet::loadMIMOChannelSettings: %d channel(s) in preset", preset->getChannelCount()); + + for (int i = 0; i < preset->getChannelCount(); i++) + { + const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i); + ChannelInstanceRegistration reg; + + // if we have one instance available already, use it + + for (int i = 0; i < openChannels.count(); i++) + { + qDebug("DeviceSet::loadMIMOChannelSettings: channels compare [%s] vs [%s]", qPrintable(openChannels[i].m_channelName), qPrintable(channelConfig.m_channelIdURI)); + + //if(openChannels[i].m_channelName == channelConfig.m_channelIdURI) + if (ChannelUtils::compareChannelURIs(openChannels[i].m_channelName, channelConfig.m_channelIdURI)) + { + qDebug("DeviceSet::loadMIMOChannelSettings: channel [%s] found", qPrintable(openChannels[i].m_channelName)); + reg = openChannels.takeAt(i); + m_channelInstanceRegistrations.append(reg); + break; + } + } + + // if we haven't one already, create one + + if (reg.m_channelAPI == nullptr) + { + for (int i = 0; i < channelRegistrations->count(); i++) + { + //if((*channelRegistrations)[i].m_channelIdURI == channelConfig.m_channelIdURI) + if (ChannelUtils::compareChannelURIs((*channelRegistrations)[i].m_channelIdURI, channelConfig.m_channelIdURI)) + { + qDebug("DeviceSet::loadMIMOChannelSettings: creating new channel [%s] from config [%s]", + qPrintable((*channelRegistrations)[i].m_channelIdURI), + qPrintable(channelConfig.m_channelIdURI)); + ChannelAPI *mimoChannel = (*channelRegistrations)[i].m_plugin->createMIMOChannelCS(m_deviceAPI); + reg = ChannelInstanceRegistration(channelConfig.m_channelIdURI, mimoChannel); + m_channelInstanceRegistrations.append(reg); + break; + } + } + } + + if (reg.m_channelAPI != nullptr) + { + qDebug("DeviceSet::loadMIMOChannelSettings: deserializing channel [%s]", qPrintable(channelConfig.m_channelIdURI)); + reg.m_channelAPI->deserialize(channelConfig.m_config); + } + } + + // everything, that is still "available" is not needed anymore + for (int i = 0; i < openChannels.count(); i++) + { + qDebug("DeviceSet::loadMIMOChannelSettings: destroying spare channel [%s]", qPrintable(openChannels[i].m_channelName)); + openChannels[i].m_channelAPI->destroy(); + } + + renameChannelInstances(); + } + else + { + qDebug("DeviceSet::loadChannelSettings: Loading preset [%s | %s] not a MIMO preset", qPrintable(preset->getGroup()), qPrintable(preset->getDescription())); + } +} + +void DeviceSet::saveMIMOChannelSettings(Preset *preset) +{ + if (preset->isMIMOPreset()) + { + std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end()); // sort by increasing delta frequency and type + + for (int i = 0; i < m_channelInstanceRegistrations.count(); i++) + { + qDebug("DeviceSet::saveMIMOChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i].m_channelName)); + preset->addChannel(m_channelInstanceRegistrations[i].m_channelName, m_channelInstanceRegistrations[i].m_channelAPI->serialize()); + } + } + else + { + qDebug("DeviceSet::saveMIMOChannelSettings: not a MIMO preset"); + } +} + +void DeviceSet::renameChannelInstances() +{ + for (int i = 0; i < m_channelInstanceRegistrations.count(); i++) + { + m_channelInstanceRegistrations[i].m_channelAPI->setName(QString("%1:%2").arg(m_channelInstanceRegistrations[i].m_channelName).arg(i)); + } +} + +// sort by increasing delta frequency and type (i.e. name) +bool DeviceSet::ChannelInstanceRegistration::operator<(const ChannelInstanceRegistration& other) const +{ + if (m_channelAPI && other.m_channelAPI) + { + if (m_channelAPI->getCenterFrequency() == other.m_channelAPI->getCenterFrequency()) + { + return m_channelAPI->getName() < other.m_channelAPI->getName(); + } + else + { + return m_channelAPI->getCenterFrequency() < other.m_channelAPI->getCenterFrequency(); + } + } + else + { + return false; + } +} + +int DeviceSet::webapiSpectrumSettingsGet(SWGSDRangel::SWGGLSpectrum& response, QString& errorMessage) const +{ + return m_spectrumVis->webapiSpectrumSettingsGet(response, errorMessage); +} + +int DeviceSet::webapiSpectrumSettingsPutPatch( + bool force, + const QStringList& spectrumSettingsKeys, + SWGSDRangel::SWGGLSpectrum& response, // query + response + QString& errorMessage) +{ + return m_spectrumVis->webapiSpectrumSettingsPutPatch(force, spectrumSettingsKeys, response, errorMessage); +} + +int DeviceSet::webapiSpectrumServerGet(SWGSDRangel::SWGSpectrumServer& response, QString& errorMessage) const +{ + return m_spectrumVis->webapiSpectrumServerGet(response, errorMessage); +} + +int DeviceSet::webapiSpectrumServerPost(SWGSDRangel::SWGSuccessResponse& response, QString& errorMessage) +{ + return m_spectrumVis->webapiSpectrumServerPost(response, errorMessage); +} + +int DeviceSet::webapiSpectrumServerDelete(SWGSDRangel::SWGSuccessResponse& response, QString& errorMessage) +{ + return m_spectrumVis->webapiSpectrumServerDelete(response, errorMessage); +} diff --git a/sdrsrv/device/deviceset.h b/sdrsrv/device/deviceset.h new file mode 100644 index 000000000..f80195593 --- /dev/null +++ b/sdrsrv/device/deviceset.h @@ -0,0 +1,104 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRSRV_DEVICE_DEVICESET_H_ +#define SDRSRV_DEVICE_DEVICESET_H_ + +#include + +class DeviceAPI; +class DSPDeviceSourceEngine; +class DSPDeviceSinkEngine; +class DSPDeviceMIMOEngine; +class PluginAPI; +class ChannelAPI; +class Preset; +class SpectrumVis; + +namespace SWGSDRangel { + class SWGGLSpectrum; + class SWGSpectrumServer; + class SWGSuccessResponse; +}; + +class DeviceSet +{ +public: + DeviceAPI *m_deviceAPI; + DSPDeviceSourceEngine *m_deviceSourceEngine; + DSPDeviceSinkEngine *m_deviceSinkEngine; + DSPDeviceMIMOEngine *m_deviceMIMOEngine; + SpectrumVis *m_spectrumVis; + + DeviceSet(int tabIndex, int deviceType); + ~DeviceSet(); + + int getNumberOfChannels() const { return m_channelInstanceRegistrations.size(); } + void addRxChannel(int selectedChannelIndex, PluginAPI *pluginAPI); + void addTxChannel(int selectedChannelIndex, PluginAPI *pluginAPI); + void addMIMOChannel(int selectedChannelIndex, PluginAPI *pluginAPI); + void deleteChannel(int channelIndex); + void registerRxChannelInstance(const QString& channelName, ChannelAPI* channelAPI); + void registerTxChannelInstance(const QString& channelName, ChannelAPI* channelAPI); + void registerChannelInstance(const QString& channelName, ChannelAPI* channelAPI); + void removeRxChannelInstance(ChannelAPI* channelAPI); + void removeTxChannelInstance(ChannelAPI* channelAPI); + void removeChannelInstance(ChannelAPI* channelAPI); + void freeChannels(); + void loadRxChannelSettings(const Preset* preset, PluginAPI *pluginAPI); + void saveRxChannelSettings(Preset* preset); + void loadTxChannelSettings(const Preset* preset, PluginAPI *pluginAPI); + void saveTxChannelSettings(Preset* preset); + void loadMIMOChannelSettings(const Preset* preset, PluginAPI *pluginAPI); + void saveMIMOChannelSettings(Preset* preset); + + // REST API + int webapiSpectrumSettingsGet(SWGSDRangel::SWGGLSpectrum& response, QString& errorMessage) const; + int webapiSpectrumSettingsPutPatch( + bool force, + const QStringList& spectrumSettingsKeys, + SWGSDRangel::SWGGLSpectrum& response, // query + response + QString& errorMessage); + int webapiSpectrumServerGet(SWGSDRangel::SWGSpectrumServer& response, QString& errorMessage) const; + int webapiSpectrumServerPost(SWGSDRangel::SWGSuccessResponse& response, QString& errorMessage); + int webapiSpectrumServerDelete(SWGSDRangel::SWGSuccessResponse& response, QString& errorMessage); + +private: + struct ChannelInstanceRegistration + { + QString m_channelName; + ChannelAPI *m_channelAPI; + + ChannelInstanceRegistration() : + m_channelName(), + m_channelAPI(nullptr) + { } + + ChannelInstanceRegistration(const QString& channelName, ChannelAPI* channelAPI); + + bool operator<(const ChannelInstanceRegistration& other) const; + }; + + typedef QList ChannelInstanceRegistrations; + + ChannelInstanceRegistrations m_channelInstanceRegistrations; + int m_deviceTabIndex; + + void renameChannelInstances(); +}; + +#endif /* SDRSRV_DEVICE_DEVICESET_H_ */ diff --git a/sdrsrv/maincore.cpp b/sdrsrv/maincore.cpp new file mode 100644 index 000000000..3d26681b9 --- /dev/null +++ b/sdrsrv/maincore.cpp @@ -0,0 +1,718 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +#include "dsp/dspengine.h" +#include "dsp/dspdevicesourceengine.h" +#include "dsp/dspdevicesinkengine.h" +#include "dsp/dspdevicemimoengine.h" +#include "dsp/spectrumvis.h" +#include "device/deviceapi.h" +#include "device/deviceset.h" +#include "device/deviceenumerator.h" +#include "plugin/pluginmanager.h" +#include "loggerwithfile.h" +#include "webapi/webapirequestmapper.h" +#include "webapi/webapiserver.h" +#include "webapi/webapiadaptersrv.h" + +#include "maincore.h" + +MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteInstance, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgLoadPreset, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgSavePreset, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgDeletePreset, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgAddDeviceSet, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgRemoveLastDeviceSet, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgSetDevice, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgAddChannel, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteChannel, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgApplySettings, Message) + +MainCore *MainCore::m_instance = 0; + +MainCore::MainCore(qtwebapp::LoggerWithFile *logger, const MainParser& parser, QObject *parent) : + QObject(parent), + m_settings(), + m_masterTabIndex(-1), + m_dspEngine(DSPEngine::instance()), + m_lastEngineState(DSPDeviceSourceEngine::StNotStarted), + m_logger(logger) +{ + qDebug() << "MainCore::MainCore: start"; + + m_instance = this; + m_settings.setAudioDeviceManager(m_dspEngine->getAudioDeviceManager()); + m_settings.setAMBEEngine(m_dspEngine->getAMBEEngine()); + + qDebug() << "MainCore::MainCore: create FFT factory..."; + m_dspEngine->createFFTFactory(parser.getFFTWFWisdomFileName()); + + qDebug() << "MainCore::MainCore: load plugins..."; + m_pluginManager = new PluginManager(this); + m_pluginManager->loadPlugins(QString("pluginssrv")); + + connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection); + m_masterTimer.start(50); + + qDebug() << "MainCore::MainCore: load setings..."; + loadSettings(); + + qDebug() << "MainCore::MainCore: finishing..."; + QString applicationDirPath = QCoreApplication::instance()->applicationDirPath(); + + m_apiAdapter = new WebAPIAdapterSrv(*this); + m_requestMapper = new WebAPIRequestMapper(this); + m_requestMapper->setAdapter(m_apiAdapter); + m_apiServer = new WebAPIServer(parser.getServerAddress(), parser.getServerPort(), m_requestMapper); + m_apiServer->start(); + + m_dspEngine->setMIMOSupport(parser.getMIMOSupport()); + + qDebug() << "MainCore::MainCore: end"; +} + +MainCore::~MainCore() +{ + while (m_deviceSets.size() > 0) { + removeLastDevice(); + } + + m_apiServer->stop(); + m_settings.save(); + delete m_apiServer; + delete m_requestMapper; + delete m_apiAdapter; + + delete m_pluginManager; + + qDebug() << "MainCore::~MainCore: end"; + delete m_logger; +} + +bool MainCore::handleMessage(const Message& cmd) +{ + if (MsgDeleteInstance::match(cmd)) + { + while (m_deviceSets.size() > 0) + { + removeLastDevice(); + } + + emit finished(); + return true; + } + else if (MsgLoadPreset::match(cmd)) + { + MsgLoadPreset& notif = (MsgLoadPreset&) cmd; + loadPresetSettings(notif.getPreset(), notif.getDeviceSetIndex()); + return true; + } + else if (MsgSavePreset::match(cmd)) + { + MsgSavePreset& notif = (MsgSavePreset&) cmd; + savePresetSettings(notif.getPreset(), notif.getDeviceSetIndex()); + m_settings.sortPresets(); + m_settings.save(); + return true; + } + else if (MsgDeletePreset::match(cmd)) + { + MsgDeletePreset& notif = (MsgDeletePreset&) cmd; + const Preset *presetToDelete = notif.getPreset(); + // remove preset from settings + m_settings.deletePreset(presetToDelete); + return true; + } + else if (MsgAddDeviceSet::match(cmd)) + { + MsgAddDeviceSet& notif = (MsgAddDeviceSet&) cmd; + int direction = notif.getDirection(); + + if (direction == 1) { // Single stream Tx + addSinkDevice(); + } else if (direction == 0) { // Single stream Rx + addSourceDevice(); + } else if (direction == 2) { // MIMO + addMIMODevice(); + } + + return true; + } + else if (MsgRemoveLastDeviceSet::match(cmd)) + { + if (m_deviceSets.size() > 0) { + removeLastDevice(); + } + + return true; + } + else if (MsgSetDevice::match(cmd)) + { + MsgSetDevice& notif = (MsgSetDevice&) cmd; + + if (notif.getDeviceType() == 1) { + changeSampleSink(notif.getDeviceSetIndex(), notif.getDeviceIndex()); + } else if (notif.getDeviceType() == 0) { + changeSampleSource(notif.getDeviceSetIndex(), notif.getDeviceIndex()); + } else if (notif.getDeviceType() == 2) { + changeSampleMIMO(notif.getDeviceSetIndex(), notif.getDeviceIndex()); + } + return true; + } + else if (MsgAddChannel::match(cmd)) + { + MsgAddChannel& notif = (MsgAddChannel&) cmd; + addChannel(notif.getDeviceSetIndex(), notif.getChannelRegistrationIndex()); + return true; + } + else if (MsgDeleteChannel::match(cmd)) + { + MsgDeleteChannel& notif = (MsgDeleteChannel&) cmd; + deleteChannel(notif.getDeviceSetIndex(), notif.getChannelIndex()); + return true; + } + else if (MsgApplySettings::match(cmd)) + { + applySettings(); + return true; + } + else + { + return false; + } +} + +void MainCore::handleMessages() +{ + Message* message; + + while ((message = m_inputMessageQueue.pop()) != 0) + { + qDebug("MainCore::handleMessages: message: %s", message->getIdentifier()); + handleMessage(*message); + delete message; + } +} + +void MainCore::loadSettings() +{ + qDebug() << "MainCore::loadSettings"; + + m_settings.load(); + m_settings.sortPresets(); + setLoggingOptions(); +} + +void MainCore::applySettings() +{ + m_settings.sortPresets(); + setLoggingOptions(); +} + +void MainCore::setLoggingOptions() +{ + m_logger->setConsoleMinMessageLevel(m_settings.getConsoleMinLogLevel()); + + if (m_settings.getUseLogFile()) + { + qtwebapp::FileLoggerSettings fileLoggerSettings; // default values + + if (m_logger->hasFileLogger()) { + fileLoggerSettings = m_logger->getFileLoggerSettings(); // values from file logger if it exists + } + + fileLoggerSettings.fileName = m_settings.getLogFileName(); // put new values + m_logger->createOrSetFileLogger(fileLoggerSettings, 2000); // create file logger if it does not exist and apply settings in any case + } + + if (m_logger->hasFileLogger()) { + m_logger->setFileMinMessageLevel(m_settings.getFileMinLogLevel()); + } + + m_logger->setUseFileLogger(m_settings.getUseLogFile()); + + if (m_settings.getUseLogFile()) + { +#if QT_VERSION >= 0x050400 + QString appInfoStr(tr("%1 %2 Qt %3 %4b %5 %6 DSP Rx:%7b Tx:%8b PID %9") + .arg(QCoreApplication::applicationName()) + .arg(QCoreApplication::applicationVersion()) + .arg(QT_VERSION_STR) + .arg(QT_POINTER_SIZE*8) + .arg(QSysInfo::currentCpuArchitecture()) + .arg(QSysInfo::prettyProductName()) + .arg(SDR_RX_SAMP_SZ) + .arg(SDR_TX_SAMP_SZ) + .arg(QCoreApplication::applicationPid())); +#else + QString appInfoStr(tr("%1 %2 Qt %3 %4b DSP Rx:%5b Tx:%6b PID %7") + .arg(QCoreApplication::applicationName()) + .arg(QCoreApplication::applicationVersion()) + .arg(QT_VERSION_STR) + .arg(QT_POINTER_SIZE*8) + .arg(SDR_RX_SAMP_SZ) + .arg(SDR_RX_SAMP_SZ) + .arg(QCoreApplication::applicationPid()); + #endif + m_logger->logToFile(QtInfoMsg, appInfoStr); + } +} + +void MainCore::addSinkDevice() +{ + DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine(); + dspDeviceSinkEngine->start(); + + uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID(); + char uidCStr[16]; + sprintf(uidCStr, "UID:%d", dspDeviceSinkEngineUID); + + int deviceTabIndex = m_deviceSets.size(); + m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 1)); + m_deviceSets.back()->m_deviceSourceEngine = nullptr; + m_deviceSets.back()->m_deviceSinkEngine = dspDeviceSinkEngine; + m_deviceSets.back()->m_deviceMIMOEngine = nullptr; + dspDeviceSinkEngine->addSpectrumSink(m_deviceSets.back()->m_spectrumVis); + + char tabNameCStr[16]; + sprintf(tabNameCStr, "T%d", deviceTabIndex); + + DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleTx, deviceTabIndex, nullptr, dspDeviceSinkEngine, nullptr); + + m_deviceSets.back()->m_deviceAPI = deviceAPI; + QList channelNames; + + // create a file sink by default + int fileSinkDeviceIndex = DeviceEnumerator::instance()->getFileSinkDeviceIndex(); + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(fileSinkDeviceIndex); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + m_deviceSets.back()->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + m_deviceSets.back()->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + m_deviceSets.back()->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + m_deviceSets.back()->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getTxPluginInterface(fileSinkDeviceIndex)); + + QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence); + + if (userArgs.size() > 0) { + m_deviceSets.back()->m_deviceAPI->setHardwareUserArguments(userArgs); + } + + DeviceSampleSink *sink = m_deviceSets.back()->m_deviceAPI->getPluginInterface()->createSampleSinkPluginInstance( + m_deviceSets.back()->m_deviceAPI->getSamplingDeviceId(), m_deviceSets.back()->m_deviceAPI); + m_deviceSets.back()->m_deviceAPI->setSampleSink(sink); +} + +void MainCore::addSourceDevice() +{ + DSPDeviceSourceEngine *dspDeviceSourceEngine = m_dspEngine->addDeviceSourceEngine(); + dspDeviceSourceEngine->start(); + + uint dspDeviceSourceEngineUID = dspDeviceSourceEngine->getUID(); + char uidCStr[16]; + sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID); + + int deviceTabIndex = m_deviceSets.size(); + m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 0)); + m_deviceSets.back()->m_deviceSourceEngine = dspDeviceSourceEngine; + m_deviceSets.back()->m_deviceSinkEngine = nullptr; + m_deviceSets.back()->m_deviceMIMOEngine = nullptr; + dspDeviceSourceEngine->addSink(m_deviceSets.back()->m_spectrumVis); + + char tabNameCStr[16]; + sprintf(tabNameCStr, "R%d", deviceTabIndex); + + DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleRx, deviceTabIndex, dspDeviceSourceEngine, nullptr, nullptr); + + m_deviceSets.back()->m_deviceAPI = deviceAPI; + + // Create a file source instance by default + int fileSourceDeviceIndex = DeviceEnumerator::instance()->getFileInputDeviceIndex(); + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(fileSourceDeviceIndex); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + m_deviceSets.back()->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + m_deviceSets.back()->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + m_deviceSets.back()->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + m_deviceSets.back()->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getRxPluginInterface(fileSourceDeviceIndex)); + + QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence); + + if (userArgs.size() > 0) { + m_deviceSets.back()->m_deviceAPI->setHardwareUserArguments(userArgs); + } + + DeviceSampleSource *source = m_deviceSets.back()->m_deviceAPI->getPluginInterface()->createSampleSourcePluginInstance( + m_deviceSets.back()->m_deviceAPI->getSamplingDeviceId(), m_deviceSets.back()->m_deviceAPI); + m_deviceSets.back()->m_deviceAPI->setSampleSource(source); +} + +void MainCore::addMIMODevice() +{ + DSPDeviceMIMOEngine *dspDeviceMIMOEngine = m_dspEngine->addDeviceMIMOEngine(); + dspDeviceMIMOEngine->start(); + + uint dspDeviceMIMOEngineUID = dspDeviceMIMOEngine->getUID(); + char uidCStr[16]; + sprintf(uidCStr, "UID:%d", dspDeviceMIMOEngineUID); + + int deviceTabIndex = m_deviceSets.size(); + m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 2)); + m_deviceSets.back()->m_deviceSourceEngine = nullptr; + m_deviceSets.back()->m_deviceSinkEngine = nullptr; + m_deviceSets.back()->m_deviceMIMOEngine = dspDeviceMIMOEngine; + dspDeviceMIMOEngine->addSpectrumSink(m_deviceSets.back()->m_spectrumVis); + + char tabNameCStr[16]; + sprintf(tabNameCStr, "M%d", deviceTabIndex); + + DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamMIMO, deviceTabIndex, nullptr, nullptr, dspDeviceMIMOEngine); + + // create a test MIMO by default + int testMIMODeviceIndex = DeviceEnumerator::instance()->getTestMIMODeviceIndex(); + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(testMIMODeviceIndex); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + m_deviceSets.back()->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + m_deviceSets.back()->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + m_deviceSets.back()->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + m_deviceSets.back()->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + m_deviceSets.back()->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getMIMOPluginInterface(testMIMODeviceIndex)); + + QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence); + + if (userArgs.size() > 0) { + m_deviceSets.back()->m_deviceAPI->setHardwareUserArguments(userArgs); + } + + DeviceSampleMIMO *mimo = m_deviceSets.back()->m_deviceAPI->getPluginInterface()->createSampleMIMOPluginInstance( + m_deviceSets.back()->m_deviceAPI->getSamplingDeviceId(), m_deviceSets.back()->m_deviceAPI); + m_deviceSets.back()->m_deviceAPI->setSampleMIMO(mimo); +} + +void MainCore::removeLastDevice() +{ + if (m_deviceSets.back()->m_deviceSourceEngine) // source set + { + DSPDeviceSourceEngine *lastDeviceEngine = m_deviceSets.back()->m_deviceSourceEngine; + lastDeviceEngine->stopAcquistion(); + + // deletes old UI and input object + m_deviceSets.back()->freeChannels(); // destroys the channel instances + m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId(); + m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput( + m_deviceSets.back()->m_deviceAPI->getSampleSource()); + m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists + + DeviceAPI *sourceAPI = m_deviceSets.back()->m_deviceAPI; + delete m_deviceSets.back(); + + lastDeviceEngine->stop(); + m_dspEngine->removeLastDeviceSourceEngine(); + + delete sourceAPI; + } + else if (m_deviceSets.back()->m_deviceSinkEngine) // sink set + { + DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSets.back()->m_deviceSinkEngine; + lastDeviceEngine->stopGeneration(); + + // deletes old UI and output object + m_deviceSets.back()->freeChannels(); + m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId(); + m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( + m_deviceSets.back()->m_deviceAPI->getSampleSink()); + m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists + + DeviceAPI *sinkAPI = m_deviceSets.back()->m_deviceAPI; + delete m_deviceSets.back(); + + lastDeviceEngine->stop(); + m_dspEngine->removeLastDeviceSinkEngine(); + + delete sinkAPI; + } + + m_deviceSets.pop_back(); +} + +void MainCore::changeSampleSource(int deviceSetIndex, int selectedDeviceIndex) +{ + if (deviceSetIndex >= 0) + { + qDebug("MainCore::changeSampleSource: deviceSet at %d", deviceSetIndex); + DeviceSet *deviceSet = m_deviceSets[deviceSetIndex]; + deviceSet->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings + deviceSet->m_deviceAPI->stopDeviceEngine(); + + // deletes old UI and input object + deviceSet->m_deviceAPI->resetSamplingDeviceId(); + deviceSet->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput( + deviceSet->m_deviceAPI->getSampleSource()); + deviceSet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists + + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(selectedDeviceIndex); + deviceSet->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + deviceSet->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + deviceSet->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + deviceSet->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + deviceSet->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + deviceSet->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + deviceSet->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + deviceSet->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getRxPluginInterface(selectedDeviceIndex)); + + // add to buddies list + std::vector::iterator it = m_deviceSets.begin(); + int nbOfBuddies = 0; + + for (; it != m_deviceSets.end(); ++it) + { + if (*it != deviceSet) // do not add to itself + { + if ((*it)->m_deviceSourceEngine) // it is a source device + { + if ((deviceSet->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceSet->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSourceBuddy(deviceSet->m_deviceAPI); + nbOfBuddies++; + } + } + + if ((*it)->m_deviceSinkEngine) // it is a sink device + { + if ((deviceSet->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceSet->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSourceBuddy(deviceSet->m_deviceAPI); + nbOfBuddies++; + } + } + } + } + + if (nbOfBuddies == 0) { + deviceSet->m_deviceAPI->setBuddyLeader(true); + } + + // constructs new GUI and input object + DeviceSampleSource *source = deviceSet->m_deviceAPI->getPluginInterface()->createSampleSourcePluginInstance( + deviceSet->m_deviceAPI->getSamplingDeviceId(), deviceSet->m_deviceAPI); + deviceSet->m_deviceAPI->setSampleSource(source); + + deviceSet->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings + } +} + +void MainCore::changeSampleSink(int deviceSetIndex, int selectedDeviceIndex) +{ + if (deviceSetIndex >= 0) + { + qDebug("MainCore::changeSampleSink: device set at %d", deviceSetIndex); + DeviceSet *deviceSet = m_deviceSets[deviceSetIndex]; + deviceSet->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings + deviceSet->m_deviceAPI->stopDeviceEngine(); + + // deletes old UI and output object + deviceSet->m_deviceAPI->resetSamplingDeviceId(); + deviceSet->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( + deviceSet->m_deviceAPI->getSampleSink()); + deviceSet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists + + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(selectedDeviceIndex); + deviceSet->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + deviceSet->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + deviceSet->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + deviceSet->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + deviceSet->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + deviceSet->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + deviceSet->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + deviceSet->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getTxPluginInterface(selectedDeviceIndex)); + + // add to buddies list + std::vector::iterator it = m_deviceSets.begin(); + int nbOfBuddies = 0; + + for (; it != m_deviceSets.end(); ++it) + { + if (*it != deviceSet) // do not add to itself + { + if ((*it)->m_deviceSourceEngine) // it is a source device + { + if ((deviceSet->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceSet->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSinkBuddy(deviceSet->m_deviceAPI); + nbOfBuddies++; + } + } + + if ((*it)->m_deviceSinkEngine) // it is a sink device + { + if ((deviceSet->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceSet->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSinkBuddy(deviceSet->m_deviceAPI); + nbOfBuddies++; + } + } + } + } + + if (nbOfBuddies == 0) { + deviceSet->m_deviceAPI->setBuddyLeader(true); + } + + // constructs new GUI and output object + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getPluginInterface()->createSampleSinkPluginInstance( + deviceSet->m_deviceAPI->getSamplingDeviceId(), deviceSet->m_deviceAPI); + deviceSet->m_deviceAPI->setSampleSink(sink); + + deviceSet->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings + } +} + +void MainCore::changeSampleMIMO(int deviceSetIndex, int selectedDeviceIndex) +{ + if (deviceSetIndex >= 0) + { + qDebug("MainCore::changeSampleMIMO: device set at %d", deviceSetIndex); + DeviceSet *deviceSet = m_deviceSets[deviceSetIndex]; + deviceSet->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings + deviceSet->m_deviceAPI->stopDeviceEngine(); + + // deletes old UI and output object + deviceSet->m_deviceAPI->resetSamplingDeviceId(); + deviceSet->m_deviceAPI->getPluginInterface()->deleteSampleMIMOPluginInstanceMIMO( + deviceSet->m_deviceAPI->getSampleMIMO()); + + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(selectedDeviceIndex); + deviceSet->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + deviceSet->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + deviceSet->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + deviceSet->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + deviceSet->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + deviceSet->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + deviceSet->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + deviceSet->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getMIMOPluginInterface(selectedDeviceIndex)); + + QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence); + + if (userArgs.size() > 0) { + deviceSet->m_deviceAPI->setHardwareUserArguments(userArgs); + } + + // constructs new GUI and MIMO object + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getPluginInterface()->createSampleMIMOPluginInstance( + deviceSet->m_deviceAPI->getSamplingDeviceId(), deviceSet->m_deviceAPI); + deviceSet->m_deviceAPI->setSampleMIMO(mimo); + + deviceSet->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings + } +} + +void MainCore::addChannel(int deviceSetIndex, int selectedChannelIndex) +{ + if (deviceSetIndex >= 0) + { + DeviceSet *deviceSet = m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // source device => Rx channels + { + deviceSet->addRxChannel(selectedChannelIndex, m_pluginManager->getPluginAPI()); + } + else if (deviceSet->m_deviceSinkEngine) // sink device => Tx channels + { + deviceSet->addTxChannel(selectedChannelIndex, m_pluginManager->getPluginAPI()); + } + } +} + +void MainCore::deleteChannel(int deviceSetIndex, int channelIndex) +{ + if (deviceSetIndex >= 0) + { + DeviceSet *deviceSet = m_deviceSets[deviceSetIndex]; + deviceSet->deleteChannel(channelIndex); + } +} + +void MainCore::loadPresetSettings(const Preset* preset, int tabIndex) +{ + qDebug("MainCore::loadPresetSettings: preset [%s | %s]", + qPrintable(preset->getGroup()), + qPrintable(preset->getDescription())); + + if (tabIndex >= 0) + { + DeviceSet *deviceSet = m_deviceSets[tabIndex]; + deviceSet->m_deviceAPI->loadSamplingDeviceSettings(preset); + + if (deviceSet->m_deviceSourceEngine) { // source device + deviceSet->loadRxChannelSettings(preset, m_pluginManager->getPluginAPI()); + } else if (deviceSet->m_deviceSinkEngine) { // sink device + deviceSet->loadTxChannelSettings(preset, m_pluginManager->getPluginAPI()); + } else if (deviceSet->m_deviceMIMOEngine) { // MIMO device + deviceSet->loadMIMOChannelSettings(preset, m_pluginManager->getPluginAPI()); + } + } +} + +void MainCore::savePresetSettings(Preset* preset, int tabIndex) +{ + qDebug("MainCore::savePresetSettings: preset [%s | %s]", + qPrintable(preset->getGroup()), + qPrintable(preset->getDescription())); + + // Save from currently selected source tab + //int currentSourceTabIndex = ui->tabInputsView->currentIndex(); + DeviceSet *deviceSet = m_deviceSets[tabIndex]; + + if (deviceSet->m_deviceSourceEngine) // source device + { + preset->clearChannels(); + preset->setSourcePreset(); + deviceSet->saveRxChannelSettings(preset); + deviceSet->m_deviceAPI->saveSamplingDeviceSettings(preset); + } + else if (deviceSet->m_deviceSinkEngine) // sink device + { + preset->clearChannels(); + preset->setSinkPreset(); + deviceSet->saveTxChannelSettings(preset); + deviceSet->m_deviceAPI->saveSamplingDeviceSettings(preset); + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO device + { + preset->clearChannels(); + preset->setMIMOPreset(); + deviceSet->saveMIMOChannelSettings(preset); + deviceSet->m_deviceAPI->saveSamplingDeviceSettings(preset); + } +} + diff --git a/sdrsrv/webapi/webapiadaptersrv.cpp b/sdrsrv/webapi/webapiadaptersrv.cpp new file mode 100644 index 000000000..987c5e69d --- /dev/null +++ b/sdrsrv/webapi/webapiadaptersrv.cpp @@ -0,0 +1,3203 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#include "SWGInstanceSummaryResponse.h" +#include "SWGInstanceConfigResponse.h" +#include "SWGInstanceDevicesResponse.h" +#include "SWGInstanceChannelsResponse.h" +#include "SWGLoggingInfo.h" +#include "SWGAudioDevices.h" +#include "SWGLocationInformation.h" +#include "SWGDVSerialDevices.h" +#include "SWGAMBEDevices.h" +#include "SWGPresetImport.h" +#include "SWGPresetExport.h" +#include "SWGPresets.h" +#include "SWGPresetTransfer.h" +#include "SWGDeviceSettings.h" +#include "SWGDeviceActions.h" +#include "SWGChannelsDetail.h" +#include "SWGChannelSettings.h" +#include "SWGChannelReport.h" +#include "SWGChannelActions.h" +#include "SWGSuccessResponse.h" +#include "SWGErrorResponse.h" +#include "SWGDeviceState.h" +#include "SWGDeviceReport.h" +#include "SWGLimeRFEDevices.h" +#include "SWGLimeRFESettings.h" +#include "SWGLimeRFEPower.h" + +#include "maincore.h" +#include "loggerwithfile.h" +#include "device/deviceset.h" +#include "device/deviceapi.h" +#include "device/deviceenumerator.h" +#include "dsp/devicesamplesink.h" +#include "dsp/devicesamplesource.h" +#include "dsp/devicesamplemimo.h" +#include "dsp/dspdevicesourceengine.h" +#include "dsp/dspdevicesinkengine.h" +#include "dsp/dspdevicemimoengine.h" +#include "dsp/dspengine.h" +#include "channel/channelapi.h" +#include "plugin/pluginapi.h" +#include "plugin/pluginmanager.h" +#include "util/serialutil.h" +#include "webapi/webapiadapterbase.h" +#include "webapiadaptersrv.h" + +#ifdef HAS_LIMERFEUSB +#include "limerfe/limerfecontroller.h" +#endif + +WebAPIAdapterSrv::WebAPIAdapterSrv(MainCore& mainCore) : + m_mainCore(mainCore) +{ +} + +WebAPIAdapterSrv::~WebAPIAdapterSrv() +{ +} + +int WebAPIAdapterSrv::instanceSummary( + SWGSDRangel::SWGInstanceSummaryResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + response.init(); + *response.getAppname() = QCoreApplication::applicationName(); + *response.getVersion() = QCoreApplication::applicationVersion(); + *response.getQtVersion() = QString(QT_VERSION_STR); + response.setDspRxBits(SDR_RX_SAMP_SZ); + response.setDspTxBits(SDR_TX_SAMP_SZ); + response.setPid(QCoreApplication::applicationPid()); +#if QT_VERSION >= 0x050400 + *response.getArchitecture() = QString(QSysInfo::currentCpuArchitecture()); + *response.getOs() = QString(QSysInfo::prettyProductName()); +#endif + + SWGSDRangel::SWGLoggingInfo *logging = response.getLogging(); + logging->init(); + logging->setDumpToFile(m_mainCore.m_logger->getUseFileLogger() ? 1 : 0); + + if (logging->getDumpToFile()) { + m_mainCore.m_logger->getLogFileName(*logging->getFileName()); + m_mainCore.m_logger->getFileMinMessageLevelStr(*logging->getFileLevel()); + } + + m_mainCore.m_logger->getConsoleMinMessageLevelStr(*logging->getConsoleLevel()); + + SWGSDRangel::SWGDeviceSetList *deviceSetList = response.getDevicesetlist(); + getDeviceSetList(deviceSetList); + + return 200; +} + +int WebAPIAdapterSrv::instanceDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + MainCore::MsgDeleteInstance *msg = MainCore::MsgDeleteInstance::create(); + m_mainCore.getInputMessageQueue()->push(msg); + + response.init(); + *response.getMessage() = QString("Message to stop the SDRangel instance (MsgDeleteInstance) was submitted successfully"); + + return 202; +} + +int WebAPIAdapterSrv::instanceConfigGet( + SWGSDRangel::SWGInstanceConfigResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + response.init(); + WebAPIAdapterBase webAPIAdapterBase; + webAPIAdapterBase.setPluginManager(m_mainCore.getPluginManager()); + SWGSDRangel::SWGPreferences *preferences = response.getPreferences(); + WebAPIAdapterBase::webapiFormatPreferences(preferences, m_mainCore.getMainSettings().getPreferences()); + SWGSDRangel::SWGPreset *workingPreset = response.getWorkingPreset(); + webAPIAdapterBase.webapiFormatPreset(workingPreset, m_mainCore.getMainSettings().getWorkingPresetConst()); + + int nbPresets = m_mainCore.m_settings.getPresetCount(); + QList *swgPresets = response.getPresets(); + + for (int i = 0; i < nbPresets; i++) + { + const Preset *preset = m_mainCore.m_settings.getPreset(i); + swgPresets->append(new SWGSDRangel::SWGPreset); + webAPIAdapterBase.webapiFormatPreset(swgPresets->back(), *preset); + } + + int nbCommands = m_mainCore.m_settings.getCommandCount(); + QList *swgCommands = response.getCommands(); + + for (int i = 0; i < nbCommands; i++) + { + const Command *command = m_mainCore.m_settings.getCommand(i); + swgCommands->append(new SWGSDRangel::SWGCommand); + WebAPIAdapterBase::webapiFormatCommand(swgCommands->back(), *command); + } + + return 200; +} + +int WebAPIAdapterSrv::instanceConfigPutPatch( + bool force, // PUT else PATCH + SWGSDRangel::SWGInstanceConfigResponse& query, + const ConfigKeys& configKeys, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + WebAPIAdapterBase webAPIAdapterBase; + webAPIAdapterBase.setPluginManager(m_mainCore.getPluginManager()); + + if (force) { + webAPIAdapterBase.webapiInitConfig(m_mainCore.m_settings); + } + + Preferences newPreferences = m_mainCore.m_settings.getPreferences(); + webAPIAdapterBase.webapiUpdatePreferences(query.getPreferences(), configKeys.m_preferencesKeys, newPreferences); + m_mainCore.m_settings.setPreferences(newPreferences); + + Preset *workingPreset = m_mainCore.m_settings.getWorkingPreset(); + webAPIAdapterBase.webapiUpdatePreset(force, query.getWorkingPreset(), configKeys.m_workingPresetKeys, workingPreset); + + QList::const_iterator presetKeysIt = configKeys.m_presetKeys.begin(); + int i = 0; + for (; presetKeysIt != configKeys.m_presetKeys.end(); ++presetKeysIt, i++) + { + Preset *newPreset = new Preset(); // created with default values + SWGSDRangel::SWGPreset *swgPreset = query.getPresets()->at(i); + webAPIAdapterBase.webapiUpdatePreset(force, swgPreset, *presetKeysIt, newPreset); + m_mainCore.m_settings.addPreset(newPreset); + } + + QList::const_iterator commandKeysIt = configKeys.m_commandKeys.begin(); + i = 0; + for (; commandKeysIt != configKeys.m_commandKeys.end(); ++commandKeysIt, i++) + { + Command *newCommand = new Command(); // created with default values + SWGSDRangel::SWGCommand *swgCommand = query.getCommands()->at(i); + webAPIAdapterBase.webapiUpdateCommand(swgCommand, *commandKeysIt, *newCommand); + m_mainCore.m_settings.addCommand(newCommand); + } + + MainCore::MsgApplySettings *msg = MainCore::MsgApplySettings::create(); + m_mainCore.m_inputMessageQueue.push(msg); + + return 200; +} + +int WebAPIAdapterSrv::instanceDevices( + int direction, + SWGSDRangel::SWGInstanceDevicesResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + response.init(); + + int nbSamplingDevices; + + if (direction == 0) { // Single Rx stream device + nbSamplingDevices = DeviceEnumerator::instance()->getNbRxSamplingDevices(); + } else if (direction == 1) { // Single Tx stream device + nbSamplingDevices = DeviceEnumerator::instance()->getNbTxSamplingDevices(); + } else if (direction == 2) { // MIMO device + nbSamplingDevices = DeviceEnumerator::instance()->getNbMIMOSamplingDevices(); + } else { // not supported + nbSamplingDevices = 0; + } + + + response.setDevicecount(nbSamplingDevices); + QList *devices = response.getDevices(); + + for (int i = 0; i < nbSamplingDevices; i++) + { + const PluginInterface::SamplingDevice *samplingDevice = nullptr; + + if (direction == 0) { + samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(i); + } else if (direction == 1) { + samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(i); + } else if (direction == 2) { + samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(i); + } else { + continue; + } + + devices->append(new SWGSDRangel::SWGDeviceListItem); + devices->back()->init(); + *devices->back()->getDisplayedName() = samplingDevice->displayedName; + *devices->back()->getHwType() = samplingDevice->hardwareId; + *devices->back()->getSerial() = samplingDevice->serial; + devices->back()->setSequence(samplingDevice->sequence); + devices->back()->setDirection((int) samplingDevice->streamType); + devices->back()->setDeviceNbStreams(samplingDevice->deviceNbItems); + devices->back()->setDeviceSetIndex(samplingDevice->claimed); + devices->back()->setIndex(i); + } + + return 200; +} + +int WebAPIAdapterSrv::instanceChannels( + int direction, + SWGSDRangel::SWGInstanceChannelsResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + response.init(); + PluginAPI::ChannelRegistrations *channelRegistrations; + int nbChannelDevices; + + if (direction == 0) // Single sink (Rx) channel + { + channelRegistrations = m_mainCore.m_pluginManager->getRxChannelRegistrations(); + nbChannelDevices = channelRegistrations->size(); + } + else if (direction == 1) // Single source (Tx) channel + { + channelRegistrations = m_mainCore.m_pluginManager->getTxChannelRegistrations(); + nbChannelDevices = channelRegistrations->size(); + } + else if (direction == 2) // MIMO channel + { + channelRegistrations = m_mainCore.m_pluginManager->getMIMOChannelRegistrations(); + nbChannelDevices = channelRegistrations->size(); + } + else // not supported + { + channelRegistrations = nullptr; + nbChannelDevices = 0; + } + + response.setChannelcount(nbChannelDevices); + QList *channels = response.getChannels(); + + for (int i = 0; i < nbChannelDevices; i++) + { + channels->append(new SWGSDRangel::SWGChannelListItem); + channels->back()->init(); + PluginInterface *channelInterface = channelRegistrations->at(i).m_plugin; + const PluginDescriptor& pluginDescriptor = channelInterface->getPluginDescriptor(); + *channels->back()->getVersion() = pluginDescriptor.version; + *channels->back()->getName() = pluginDescriptor.displayedName; + channels->back()->setDirection(direction); + *channels->back()->getIdUri() = channelRegistrations->at(i).m_channelIdURI; + *channels->back()->getId() = channelRegistrations->at(i).m_channelId; + channels->back()->setIndex(i); + } + + return 200; +} + +int WebAPIAdapterSrv::instanceLoggingGet( + SWGSDRangel::SWGLoggingInfo& response, + SWGSDRangel::SWGErrorResponse& error) +{ + response.init(); + response.setDumpToFile(m_mainCore.m_logger->getUseFileLogger() ? 1 : 0); + + if (response.getDumpToFile()) { + m_mainCore.m_logger->getLogFileName(*response.getFileName()); + m_mainCore.m_logger->getFileMinMessageLevelStr(*response.getFileLevel()); + } + + m_mainCore.m_logger->getConsoleMinMessageLevelStr(*response.getConsoleLevel()); + + return 200; +} + +int WebAPIAdapterSrv::instanceLoggingPut( + SWGSDRangel::SWGLoggingInfo& query, + SWGSDRangel::SWGLoggingInfo& response, + SWGSDRangel::SWGErrorResponse& error) +{ + // response input is the query actually + bool dumpToFile = (query.getDumpToFile() != 0); + QString* consoleLevel = query.getConsoleLevel(); + QString* fileLevel = query.getFileLevel(); + QString* fileName = query.getFileName(); + + // perform actions + if (consoleLevel) { + m_mainCore.m_settings.setConsoleMinLogLevel(getMsgTypeFromString(*consoleLevel)); + } + + if (fileLevel) { + m_mainCore.m_settings.setFileMinLogLevel(getMsgTypeFromString(*fileLevel)); + } + + m_mainCore.m_settings.setUseLogFile(dumpToFile); + + if (fileName) { + m_mainCore.m_settings.setLogFileName(*fileName); + } + + m_mainCore.setLoggingOptions(); + + // build response + response.init(); + getMsgTypeString(m_mainCore.m_settings.getConsoleMinLogLevel(), *response.getConsoleLevel()); + response.setDumpToFile(m_mainCore.m_settings.getUseLogFile() ? 1 : 0); + getMsgTypeString(m_mainCore.m_settings.getFileMinLogLevel(), *response.getFileLevel()); + *response.getFileName() = m_mainCore.m_settings.getLogFileName(); + + return 200; +} + +int WebAPIAdapterSrv::instanceAudioGet( + SWGSDRangel::SWGAudioDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + const QList& audioInputDevices = m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDevices(); + const QList& audioOutputDevices = m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDevices(); + int nbInputDevices = audioInputDevices.size(); + int nbOutputDevices = audioOutputDevices.size(); + + response.init(); + response.setNbInputDevices(nbInputDevices); + response.setNbOutputDevices(nbOutputDevices); + QList *inputDevices = response.getInputDevices(); + QList *outputDevices = response.getOutputDevices(); + AudioDeviceManager::InputDeviceInfo inputDeviceInfo; + AudioDeviceManager::OutputDeviceInfo outputDeviceInfo; + + // system default input device + inputDevices->append(new SWGSDRangel::SWGAudioInputDevice); + inputDevices->back()->init(); + bool found = m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceInfo(AudioDeviceManager::m_defaultDeviceName, inputDeviceInfo); + *inputDevices->back()->getName() = AudioDeviceManager::m_defaultDeviceName; + inputDevices->back()->setIndex(-1); + inputDevices->back()->setSampleRate(inputDeviceInfo.sampleRate); + inputDevices->back()->setIsSystemDefault(0); + inputDevices->back()->setDefaultUnregistered(found ? 0 : 1); + inputDevices->back()->setVolume(inputDeviceInfo.volume); + + // real input devices + for (int i = 0; i < nbInputDevices; i++) + { + inputDevices->append(new SWGSDRangel::SWGAudioInputDevice); + inputDevices->back()->init(); + inputDeviceInfo.resetToDefaults(); + found = m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceInfo(audioInputDevices.at(i).deviceName(), inputDeviceInfo); + *inputDevices->back()->getName() = audioInputDevices.at(i).deviceName(); + inputDevices->back()->setIndex(i); + inputDevices->back()->setSampleRate(inputDeviceInfo.sampleRate); + inputDevices->back()->setIsSystemDefault(audioInputDevices.at(i).deviceName() == QAudioDeviceInfo::defaultInputDevice().deviceName() ? 1 : 0); + inputDevices->back()->setDefaultUnregistered(found ? 0 : 1); + inputDevices->back()->setVolume(inputDeviceInfo.volume); + } + + // system default output device + outputDevices->append(new SWGSDRangel::SWGAudioOutputDevice); + outputDevices->back()->init(); + found = m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDeviceInfo(AudioDeviceManager::m_defaultDeviceName, outputDeviceInfo); + *outputDevices->back()->getName() = AudioDeviceManager::m_defaultDeviceName; + outputDevices->back()->setIndex(-1); + outputDevices->back()->setSampleRate(outputDeviceInfo.sampleRate); + inputDevices->back()->setIsSystemDefault(0); + outputDevices->back()->setDefaultUnregistered(found ? 0 : 1); + outputDevices->back()->setCopyToUdp(outputDeviceInfo.copyToUDP ? 1 : 0); + outputDevices->back()->setUdpUsesRtp(outputDeviceInfo.udpUseRTP ? 1 : 0); + outputDevices->back()->setUdpChannelMode((int) outputDeviceInfo.udpChannelMode); + outputDevices->back()->setUdpChannelCodec((int) outputDeviceInfo.udpChannelCodec); + outputDevices->back()->setUdpDecimationFactor(outputDeviceInfo.udpDecimationFactor); + *outputDevices->back()->getUdpAddress() = outputDeviceInfo.udpAddress; + outputDevices->back()->setUdpPort(outputDeviceInfo.udpPort); + + // real output devices + for (int i = 0; i < nbOutputDevices; i++) + { + outputDevices->append(new SWGSDRangel::SWGAudioOutputDevice); + outputDevices->back()->init(); + outputDeviceInfo.resetToDefaults(); + found = m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDeviceInfo(audioOutputDevices.at(i).deviceName(), outputDeviceInfo); + *outputDevices->back()->getName() = audioOutputDevices.at(i).deviceName(); + outputDevices->back()->setIndex(i); + outputDevices->back()->setSampleRate(outputDeviceInfo.sampleRate); + outputDevices->back()->setIsSystemDefault(audioOutputDevices.at(i).deviceName() == QAudioDeviceInfo::defaultOutputDevice().deviceName() ? 1 : 0); + outputDevices->back()->setDefaultUnregistered(found ? 0 : 1); + outputDevices->back()->setCopyToUdp(outputDeviceInfo.copyToUDP ? 1 : 0); + outputDevices->back()->setUdpUsesRtp(outputDeviceInfo.udpUseRTP ? 1 : 0); + outputDevices->back()->setUdpChannelMode((int) outputDeviceInfo.udpChannelMode); + outputDevices->back()->setUdpChannelCodec((int) outputDeviceInfo.udpChannelCodec); + outputDevices->back()->setUdpDecimationFactor(outputDeviceInfo.udpDecimationFactor); + *outputDevices->back()->getUdpAddress() = outputDeviceInfo.udpAddress; + outputDevices->back()->setUdpPort(outputDeviceInfo.udpPort); + } + + return 200; +} + +int WebAPIAdapterSrv::instanceAudioInputPatch( + SWGSDRangel::SWGAudioInputDevice& response, + const QStringList& audioInputKeys, + SWGSDRangel::SWGErrorResponse& error) +{ + // TODO + AudioDeviceManager::InputDeviceInfo inputDeviceInfo; + QString deviceName; + int deviceIndex = response.getIndex(); + + if (!m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceName(deviceIndex, deviceName)) + { + error.init(); + *error.getMessage() = QString("There is no input audio device at index %1").arg(deviceIndex); + return 404; + } + + m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceInfo(deviceName, inputDeviceInfo); + + if (audioInputKeys.contains("sampleRate")) { + inputDeviceInfo.sampleRate = response.getSampleRate(); + } + if (audioInputKeys.contains("volume")) { + inputDeviceInfo.volume = response.getVolume(); + } + + m_mainCore.m_dspEngine->getAudioDeviceManager()->setInputDeviceInfo(deviceIndex, inputDeviceInfo); + m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceInfo(deviceName, inputDeviceInfo); + + response.setSampleRate(inputDeviceInfo.sampleRate); + response.setVolume(inputDeviceInfo.volume); + + return 200; +} + +int WebAPIAdapterSrv::instanceAudioOutputPatch( + SWGSDRangel::SWGAudioOutputDevice& response, + const QStringList& audioOutputKeys, + SWGSDRangel::SWGErrorResponse& error) +{ + AudioDeviceManager::OutputDeviceInfo outputDeviceInfo; + QString deviceName; + int deviceIndex = response.getIndex(); + + if (!m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDeviceName(deviceIndex, deviceName)) + { + error.init(); + *error.getMessage() = QString("There is no output audio device at index %1").arg(deviceIndex); + return 404; + } + + m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDeviceInfo(deviceName, outputDeviceInfo); + + if (audioOutputKeys.contains("sampleRate")) { + outputDeviceInfo.sampleRate = response.getSampleRate(); + } + if (audioOutputKeys.contains("copyToUDP")) { + outputDeviceInfo.copyToUDP = response.getCopyToUdp() == 0 ? 0 : 1; + } + if (audioOutputKeys.contains("udpUsesRTP")) { + outputDeviceInfo.udpUseRTP = response.getUdpUsesRtp() == 0 ? 0 : 1; + } + if (audioOutputKeys.contains("udpChannelMode")) { + outputDeviceInfo.udpChannelMode = static_cast(response.getUdpChannelMode() % 4); + } + if (audioOutputKeys.contains("udpAddress")) { + outputDeviceInfo.udpAddress = *response.getUdpAddress(); + } + if (audioOutputKeys.contains("udpPort")) { + outputDeviceInfo.udpPort = response.getUdpPort() % (1<<16); + } + + m_mainCore.m_dspEngine->getAudioDeviceManager()->setOutputDeviceInfo(deviceIndex, outputDeviceInfo); + m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDeviceInfo(deviceName, outputDeviceInfo); + + response.setSampleRate(outputDeviceInfo.sampleRate); + response.setCopyToUdp(outputDeviceInfo.copyToUDP == 0 ? 0 : 1); + response.setUdpUsesRtp(outputDeviceInfo.udpUseRTP == 0 ? 0 : 1); + response.setUdpChannelMode(outputDeviceInfo.udpChannelMode); + response.setUdpChannelCodec(outputDeviceInfo.udpChannelCodec); + response.setUdpDecimationFactor(outputDeviceInfo.udpDecimationFactor); + + if (response.getUdpAddress()) { + *response.getUdpAddress() = outputDeviceInfo.udpAddress; + } else { + response.setUdpAddress(new QString(outputDeviceInfo.udpAddress)); + } + + response.setUdpPort(outputDeviceInfo.udpPort % (1<<16)); + + return 200; +} + +int WebAPIAdapterSrv::instanceAudioInputDelete( + SWGSDRangel::SWGAudioInputDevice& response, + SWGSDRangel::SWGErrorResponse& error) +{ + AudioDeviceManager::InputDeviceInfo inputDeviceInfo; + QString deviceName; + int deviceIndex = response.getIndex(); + + if (!m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceName(deviceIndex, deviceName)) + { + error.init(); + *error.getMessage() = QString("There is no audio input device at index %1").arg(deviceIndex); + return 404; + } + + m_mainCore.m_dspEngine->getAudioDeviceManager()->unsetInputDeviceInfo(deviceIndex); + m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceInfo(deviceName, inputDeviceInfo); + + response.setSampleRate(inputDeviceInfo.sampleRate); + response.setVolume(inputDeviceInfo.volume); + + return 200; +} + +int WebAPIAdapterSrv::instanceAudioOutputDelete( + SWGSDRangel::SWGAudioOutputDevice& response, + SWGSDRangel::SWGErrorResponse& error) +{ + AudioDeviceManager::OutputDeviceInfo outputDeviceInfo; + QString deviceName; + int deviceIndex = response.getIndex(); + + if (!m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDeviceName(deviceIndex, deviceName)) + { + error.init(); + *error.getMessage() = QString("There is no audio output device at index %1").arg(deviceIndex); + return 404; + } + + m_mainCore.m_dspEngine->getAudioDeviceManager()->unsetInputDeviceInfo(deviceIndex); + m_mainCore.m_dspEngine->getAudioDeviceManager()->getOutputDeviceInfo(deviceName, outputDeviceInfo); + + response.setSampleRate(outputDeviceInfo.sampleRate); + response.setCopyToUdp(outputDeviceInfo.copyToUDP == 0 ? 0 : 1); + response.setUdpUsesRtp(outputDeviceInfo.udpUseRTP == 0 ? 0 : 1); + response.setUdpChannelMode(outputDeviceInfo.udpChannelMode); + response.setUdpChannelCodec(outputDeviceInfo.udpChannelCodec); + response.setUdpDecimationFactor(outputDeviceInfo.udpDecimationFactor); + + if (response.getUdpAddress()) { + *response.getUdpAddress() = outputDeviceInfo.udpAddress; + } else { + response.setUdpAddress(new QString(outputDeviceInfo.udpAddress)); + } + + response.setUdpPort(outputDeviceInfo.udpPort % (1<<16)); + + return 200; +} + +int WebAPIAdapterSrv::instanceAudioInputCleanupPatch( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + m_mainCore.m_dspEngine->getAudioDeviceManager()->inputInfosCleanup(); + + response.init(); + *response.getMessage() = QString("Unregistered parameters for devices not in list of available input devices for this instance"); + + return 200; +} + +int WebAPIAdapterSrv::instanceAudioOutputCleanupPatch( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + m_mainCore.m_dspEngine->getAudioDeviceManager()->outputInfosCleanup(); + + response.init(); + *response.getMessage() = QString("Unregistered parameters for devices not in list of available output devices for this instance"); + + return 200; +} + +int WebAPIAdapterSrv::instanceLocationGet( + SWGSDRangel::SWGLocationInformation& response, + SWGSDRangel::SWGErrorResponse& error) +{ + response.init(); + response.setLatitude(m_mainCore.m_settings.getLatitude()); + response.setLongitude(m_mainCore.m_settings.getLongitude()); + + return 200; +} + +int WebAPIAdapterSrv::instanceLocationPut( + SWGSDRangel::SWGLocationInformation& response, + SWGSDRangel::SWGErrorResponse& error) +{ + float latitude = response.getLatitude(); + float longitude = response.getLongitude(); + + latitude = latitude < -90.0 ? -90.0 : latitude > 90.0 ? 90.0 : latitude; + longitude = longitude < -180.0 ? -180.0 : longitude > 180.0 ? 180.0 : longitude; + + m_mainCore.m_settings.setLatitude(latitude); + m_mainCore.m_settings.setLongitude(longitude); + + response.setLatitude(m_mainCore.m_settings.getLatitude()); + response.setLongitude(m_mainCore.m_settings.getLongitude()); + + return 200; +} + +int WebAPIAdapterSrv::instanceDVSerialGet( + SWGSDRangel::SWGDVSerialDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + response.init(); + + std::vector deviceNames; + m_mainCore.m_dspEngine->getDVSerialNames(deviceNames); + response.setNbDevices((int) deviceNames.size()); + QList *deviceNamesList = response.getDvSerialDevices(); + + std::vector::iterator it = deviceNames.begin(); + + while (it != deviceNames.end()) + { + deviceNamesList->append(new SWGSDRangel::SWGDVSerialDevice); + deviceNamesList->back()->init(); + *deviceNamesList->back()->getDeviceName() = QString::fromStdString(*it); + ++it; + } + + return 200; +} + +int WebAPIAdapterSrv::instanceDVSerialPatch( + bool dvserial, + SWGSDRangel::SWGDVSerialDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + m_mainCore.m_dspEngine->setDVSerialSupport(dvserial); + response.init(); + + if (dvserial) + { + std::vector deviceNames; + m_mainCore.m_dspEngine->getDVSerialNames(deviceNames); + response.setNbDevices((int) deviceNames.size()); + QList *deviceNamesList = response.getDvSerialDevices(); + + std::vector::iterator it = deviceNames.begin(); + std::string deviceNamesStr = "DV Serial devices found: "; + + while (it != deviceNames.end()) + { + deviceNamesList->append(new SWGSDRangel::SWGDVSerialDevice); + deviceNamesList->back()->init(); + *deviceNamesList->back()->getDeviceName() = QString::fromStdString(*it); + ++it; + } + } + else + { + response.setNbDevices(0); + } + + return 200; +} + +int WebAPIAdapterSrv::instanceAMBESerialGet( + SWGSDRangel::SWGDVSerialDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + (void) error; + response.init(); + + std::vector deviceNames; + std::vector qDeviceNames; + m_mainCore.m_dspEngine->getAMBEEngine()->scan(qDeviceNames); + + for (std::vector::const_iterator it = qDeviceNames.begin(); it != qDeviceNames.end(); ++it) { + deviceNames.push_back(it->toStdString()); + } + + response.setNbDevices((int) deviceNames.size()); + QList *deviceNamesList = response.getDvSerialDevices(); + + std::vector::iterator it = deviceNames.begin(); + + while (it != deviceNames.end()) + { + deviceNamesList->append(new SWGSDRangel::SWGDVSerialDevice); + deviceNamesList->back()->init(); + *deviceNamesList->back()->getDeviceName() = QString::fromStdString(*it); + ++it; + } + + return 200; +} + +int WebAPIAdapterSrv::instanceAMBEDevicesGet( + SWGSDRangel::SWGAMBEDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + (void) error; + response.init(); + + std::vector deviceNames; + m_mainCore.m_dspEngine->getDVSerialNames(deviceNames); + response.setNbDevices((int) deviceNames.size()); + QList *deviceNamesList = response.getAmbeDevices(); + + std::vector::iterator it = deviceNames.begin(); + + while (it != deviceNames.end()) + { + deviceNamesList->append(new SWGSDRangel::SWGAMBEDevice); + deviceNamesList->back()->init(); + *deviceNamesList->back()->getDeviceRef() = QString::fromStdString(*it); + deviceNamesList->back()->setDelete(0); + ++it; + } + + return 200; +} + +int WebAPIAdapterSrv::instanceAMBEDevicesDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + (void) error; + m_mainCore.m_dspEngine->getAMBEEngine()->releaseAll(); + + response.init(); + *response.getMessage() = QString("All AMBE devices released"); + + return 200; +} + +int WebAPIAdapterSrv::instanceAMBEDevicesPut( + SWGSDRangel::SWGAMBEDevices& query, + SWGSDRangel::SWGAMBEDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + m_mainCore.m_dspEngine->getAMBEEngine()->releaseAll(); + + QList *ambeList = query.getAmbeDevices(); + + for (QList::const_iterator it = ambeList->begin(); it != ambeList->end(); ++it) { + m_mainCore.m_dspEngine->getAMBEEngine()->registerController((*it)->getDeviceRef()->toStdString()); + } + + instanceAMBEDevicesGet(response, error); + return 200; +} + +int WebAPIAdapterSrv::instanceAMBEDevicesPatch( + SWGSDRangel::SWGAMBEDevices& query, + SWGSDRangel::SWGAMBEDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + QList *ambeList = query.getAmbeDevices(); + + for (QList::const_iterator it = ambeList->begin(); it != ambeList->end(); ++it) + { + if ((*it)->getDelete()) { + m_mainCore.m_dspEngine->getAMBEEngine()->releaseController((*it)->getDeviceRef()->toStdString()); + } else { + m_mainCore.m_dspEngine->getAMBEEngine()->registerController((*it)->getDeviceRef()->toStdString()); + } + } + + instanceAMBEDevicesGet(response, error); + return 200; +} + +#ifdef HAS_LIMERFEUSB +int WebAPIAdapterSrv::instanceLimeRFESerialGet( + SWGSDRangel::SWGLimeRFEDevices& response, + SWGSDRangel::SWGErrorResponse& error) +{ + (void) error; + std::vector comPorts; + SerialUtil::getComPorts(comPorts, "ttyUSB[0-9]+"); // regex is for Linux only + response.setNbDevices((int) comPorts.size()); + QList *deviceNamesList = response.getLimeRfeDevices(); + std::vector::iterator it = comPorts.begin(); + + while (it != comPorts.end()) + { + deviceNamesList->append(new SWGSDRangel::SWGLimeRFEDevice); + deviceNamesList->back()->init(); + *deviceNamesList->back()->getDeviceRef() = QString::fromStdString(*it); + ++it; + } + + return 200; +} + +int WebAPIAdapterSrv::instanceLimeRFEConfigGet( + const QString& serial, + SWGSDRangel::SWGLimeRFESettings& response, + SWGSDRangel::SWGErrorResponse& error) +{ + LimeRFEController controller; + int rc = controller.openDevice(serial.toStdString()); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error opening LimeRFE device %1: %2") + .arg(serial).arg(controller.getError(rc).c_str()); + return 400; + } + + rc = controller.getState(); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error getting config from LimeRFE device %1: %2") + .arg(serial).arg(controller.getError(rc).c_str()); + return 500; + } + + controller.closeDevice(); + + LimeRFEController::LimeRFESettings settings; + controller.stateToSettings(settings); + response.init(); + response.setDevicePath(new QString(serial)); + response.setRxChannels((int) settings.m_rxChannels); + response.setRxWidebandChannel((int) settings.m_rxWidebandChannel); + response.setRxHamChannel((int) settings.m_rxHAMChannel); + response.setRxCellularChannel((int) settings.m_rxCellularChannel); + response.setRxPort((int) settings.m_rxPort); + response.setRxOn(settings.m_rxOn ? 1 : 0); + response.setAmfmNotch(settings.m_amfmNotch ? 1 : 0); + response.setAttenuationFactor(settings.m_attenuationFactor); + response.setTxChannels((int) settings.m_txChannels); + response.setTxWidebandChannel((int) settings.m_txWidebandChannel); + response.setTxHamChannel((int) settings.m_txHAMChannel); + response.setTxCellularChannel((int) settings.m_txCellularChannel); + response.setTxPort((int) settings.m_txPort); + response.setTxOn(settings.m_txOn ? 1 : 0); + response.setSwrEnable(settings.m_swrEnable ? 1 : 0); + response.setSwrSource((int) settings.m_swrSource); + + return 200; +} + +int WebAPIAdapterSrv::instanceLimeRFEConfigPut( + SWGSDRangel::SWGLimeRFESettings& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + LimeRFEController controller; + int rc = controller.openDevice(query.getDevicePath()->toStdString()); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error opening LimeRFE device %1: %2") + .arg(*query.getDevicePath()).arg(controller.getError(rc).c_str()); + return 400; + } + + LimeRFEController::LimeRFESettings settings; + settings.m_rxChannels = (LimeRFEController::ChannelGroups) query.getRxChannels(); + settings.m_rxWidebandChannel = (LimeRFEController::WidebandChannel) query.getRxWidebandChannel(); + settings.m_rxHAMChannel = (LimeRFEController::HAMChannel) query.getRxHamChannel(); + settings.m_rxCellularChannel = (LimeRFEController::CellularChannel) query.getRxCellularChannel(); + settings.m_rxPort = (LimeRFEController::RxPort) query.getRxPort(); + settings.m_rxOn = query.getRxOn() != 0; + settings.m_amfmNotch = query.getAmfmNotch() != 0; + settings.m_attenuationFactor = query.getAttenuationFactor(); + settings.m_txChannels = (LimeRFEController::ChannelGroups) query.getTxChannels(); + settings.m_txWidebandChannel = (LimeRFEController::WidebandChannel) query.getTxWidebandChannel(); + settings.m_txHAMChannel = (LimeRFEController::HAMChannel) query.getTxHamChannel(); + settings.m_txCellularChannel = (LimeRFEController::CellularChannel) query.getTxCellularChannel(); + settings.m_txPort = (LimeRFEController::TxPort) query.getTxPort(); + settings.m_txOn = query.getTxOn() != 0; + settings.m_swrEnable = query.getSwrEnable() != 0; + settings.m_swrSource = (LimeRFEController::SWRSource) query.getSwrSource(); + + controller.settingsToState(settings); + + rc = controller.configure(); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error configuring LimeRFE device %1: %2") + .arg(*query.getDevicePath()).arg(controller.getError(rc).c_str()); + return 500; + } + + response.init(); + *response.getMessage() = QString("LimeRFE device at %1 configuration updated successfully").arg(*query.getDevicePath()); + return 200; +} + +int WebAPIAdapterSrv::instanceLimeRFERunPut( + SWGSDRangel::SWGLimeRFESettings& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + LimeRFEController controller; + int rc = controller.openDevice(query.getDevicePath()->toStdString()); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error opening LimeRFE device %1: %2") + .arg(*query.getDevicePath()).arg(controller.getError(rc).c_str()); + return 400; + } + + LimeRFEController::LimeRFESettings settings; + settings.m_rxOn = query.getRxOn() != 0; + settings.m_txOn = query.getTxOn() != 0; + + rc = controller.setRx(settings, settings.m_rxOn); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error setting Rx/Tx LimeRFE device %1: %2") + .arg(*query.getDevicePath()).arg(controller.getError(rc).c_str()); + return 400; + } + + response.init(); + *response.getMessage() = QString("LimeRFE device at %1 mode updated successfully").arg(*query.getDevicePath()); + return 200; +} + +int WebAPIAdapterSrv::instanceLimeRFEPowerGet( + const QString& serial, + SWGSDRangel::SWGLimeRFEPower& response, + SWGSDRangel::SWGErrorResponse& error) +{ + LimeRFEController controller; + int rc = controller.openDevice(serial.toStdString()); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error opening LimeRFE device %1: %2") + .arg(serial).arg(controller.getError(rc).c_str()); + return 400; + } + + int fwdPower; + rc = controller.getFwdPower(fwdPower); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error getting forward power from LimeRFE device %1: %2") + .arg(serial).arg(controller.getError(rc).c_str()); + return 500; + } + + int refPower; + rc = controller.getRefPower(refPower); + + if (rc != 0) + { + error.init(); + *error.getMessage() = QString("Error getting reflected power from LimeRFE device %1: %2") + .arg(serial).arg(controller.getError(rc).c_str()); + return 500; + } + + controller.closeDevice(); + + response.init(); + response.setForward(fwdPower); + response.setReflected(refPower); + return 200; +} +#endif + +int WebAPIAdapterSrv::instancePresetFilePut( + SWGSDRangel::SWGPresetImport& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error) +{ + const QString& fileName = *query.getFilePath(); + + if (fileName != "") + { + QFile exportFile(fileName); + + if (exportFile.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QByteArray base64Str; + QTextStream instream(&exportFile); + instream >> base64Str; + exportFile.close(); + + Preset* preset = m_mainCore.m_settings.newPreset("", ""); + preset->deserialize(QByteArray::fromBase64(base64Str)); + + if (query.getGroupName() && (query.getGroupName()->size() > 0)) { + preset->setGroup(*query.getGroupName()); + } + + if (query.getDescription() && (query.getDescription()->size() > 0)) { + preset->setDescription(*query.getDescription()); + } + + response.init(); + response.setCenterFrequency(preset->getCenterFrequency()); + *response.getGroupName() = preset->getGroup(); + *response.getType() = preset->isSourcePreset() ? "R" : preset->isSinkPreset() ? "T" : preset->isMIMOPreset() ? "M" : "X"; + *response.getName() = preset->getDescription(); + + return 200; + } + else + { + error.init(); + *error.getMessage() = QString("File %1 not found or not readable").arg(fileName); + return 404; + } + } + else + { + error.init(); + *error.getMessage() = QString("Empty file path"); + return 404; + } +} + +int WebAPIAdapterSrv::instancePresetFilePost( + SWGSDRangel::SWGPresetExport& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error) +{ + QString filePath = *query.getFilePath(); + SWGSDRangel::SWGPresetIdentifier *presetIdentifier = query.getPreset(); + + const Preset *selectedPreset = m_mainCore.m_settings.getPreset(*presetIdentifier->getGroupName(), + presetIdentifier->getCenterFrequency(), + *presetIdentifier->getName(), + *presetIdentifier->getType()); + + if (selectedPreset == 0) + { + error.init(); + *error.getMessage() = QString("There is no preset [%1, %2, %3, %4]") + .arg(*presetIdentifier->getGroupName()) + .arg(presetIdentifier->getCenterFrequency()) + .arg(*presetIdentifier->getName()) + .arg(*presetIdentifier->getType()); + return 404; + } + + QString base64Str = selectedPreset->serialize().toBase64(); + + if (filePath != "") + { + QFileInfo fileInfo(filePath); + + if (fileInfo.suffix() != "prex") { + filePath += ".prex"; + } + + QFile exportFile(filePath); + + if (exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QTextStream outstream(&exportFile); + outstream << base64Str; + exportFile.close(); + + response.init(); + response.setCenterFrequency(selectedPreset->getCenterFrequency()); + *response.getGroupName() = selectedPreset->getGroup(); + *response.getType() = selectedPreset->isSourcePreset() ? "R" : selectedPreset->isSinkPreset() ? "T" : selectedPreset->isMIMOPreset() ? "M" : "X"; + *response.getName() = selectedPreset->getDescription(); + + return 200; + } + else + { + error.init(); + *error.getMessage() = QString("File %1 cannot be written").arg(filePath); + return 404; + } + } + else + { + error.init(); + *error.getMessage() = QString("Empty file path"); + return 404; + } +} + +int WebAPIAdapterSrv::instancePresetsGet( + SWGSDRangel::SWGPresets& response, + SWGSDRangel::SWGErrorResponse& error) +{ + int nbPresets = m_mainCore.m_settings.getPresetCount(); + int nbGroups = 0; + int nbPresetsThisGroup = 0; + QString groupName; + response.init(); + QList *groups = response.getGroups(); + QList *swgPresets = 0; + int i = 0; + + // Presets are sorted by group first + + for (; i < nbPresets; i++) + { + const Preset *preset = m_mainCore.m_settings.getPreset(i); + + if ((i == 0) || (groupName != preset->getGroup())) // new group + { + if (i > 0) { groups->back()->setNbPresets(nbPresetsThisGroup); } + groups->append(new SWGSDRangel::SWGPresetGroup); + groups->back()->init(); + groupName = preset->getGroup(); + *groups->back()->getGroupName() = groupName; + swgPresets = groups->back()->getPresets(); + nbGroups++; + nbPresetsThisGroup = 0; + } + + swgPresets->append(new SWGSDRangel::SWGPresetItem); + swgPresets->back()->init(); + swgPresets->back()->setCenterFrequency(preset->getCenterFrequency()); + *swgPresets->back()->getType() = preset->isSourcePreset() ? "R" : preset->isSinkPreset() ? "T" : preset->isMIMOPreset() ? "M" : "X"; + *swgPresets->back()->getName() = preset->getDescription(); + nbPresetsThisGroup++; + } + + if (i > 0) { groups->back()->setNbPresets(nbPresetsThisGroup); } + response.setNbGroups(nbGroups); + + return 200; +} + +int WebAPIAdapterSrv::instancePresetPatch( + SWGSDRangel::SWGPresetTransfer& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error) +{ + int deviceSetIndex = query.getDeviceSetIndex(); + SWGSDRangel::SWGPresetIdentifier *presetIdentifier = query.getPreset(); + int nbDeviceSets = m_mainCore.m_deviceSets.size(); + + if (deviceSetIndex >= nbDeviceSets) + { + error.init(); + *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); + return 404; + } + + const Preset *selectedPreset = m_mainCore.m_settings.getPreset(*presetIdentifier->getGroupName(), + presetIdentifier->getCenterFrequency(), + *presetIdentifier->getName(), + *presetIdentifier->getType()); + + if (selectedPreset == 0) + { + error.init(); + *error.getMessage() = QString("There is no preset [%1, %2, %3 %4]") + .arg(*presetIdentifier->getGroupName()) + .arg(presetIdentifier->getCenterFrequency()) + .arg(*presetIdentifier->getName()) + .arg(*presetIdentifier->getType()); + return 404; + } + + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine && !selectedPreset->isSourcePreset()) + { + error.init(); + *error.getMessage() = QString("Preset type and device set type (Rx) mismatch"); + return 404; + } + + if (deviceSet->m_deviceSinkEngine && !selectedPreset->isSinkPreset()) + { + error.init(); + *error.getMessage() = QString("Preset type and device set type (Tx) mismatch"); + return 404; + } + + if (deviceSet->m_deviceMIMOEngine && !selectedPreset->isMIMOPreset()) + { + error.init(); + *error.getMessage() = QString("Preset type and device set type (MIMO) mismatch"); + return 404; + } + + MainCore::MsgLoadPreset *msg = MainCore::MsgLoadPreset::create(selectedPreset, deviceSetIndex); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + response.setCenterFrequency(selectedPreset->getCenterFrequency()); + *response.getGroupName() = selectedPreset->getGroup(); + *response.getType() = selectedPreset->isSourcePreset() ? "R" : selectedPreset->isSinkPreset() ? "T" : selectedPreset->isMIMOPreset() ? "M" : "X"; + *response.getName() = selectedPreset->getDescription(); + + return 202; +} + +int WebAPIAdapterSrv::instancePresetPut( + SWGSDRangel::SWGPresetTransfer& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error) +{ + int deviceSetIndex = query.getDeviceSetIndex(); + SWGSDRangel::SWGPresetIdentifier *presetIdentifier = query.getPreset(); + int nbDeviceSets = m_mainCore.m_deviceSets.size(); + + if (deviceSetIndex >= nbDeviceSets) + { + error.init(); + *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); + return 404; + } + + const Preset *selectedPreset = m_mainCore.m_settings.getPreset(*presetIdentifier->getGroupName(), + presetIdentifier->getCenterFrequency(), + *presetIdentifier->getName(), + *presetIdentifier->getType()); + + if (selectedPreset == 0) + { + error.init(); + *error.getMessage() = QString("There is no preset [%1, %2, %3 %4]") + .arg(*presetIdentifier->getGroupName()) + .arg(presetIdentifier->getCenterFrequency()) + .arg(*presetIdentifier->getName()) + .arg(*presetIdentifier->getType()); + return 404; + } + else // update existing preset + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine && !selectedPreset->isSourcePreset()) + { + error.init(); + *error.getMessage() = QString("Preset type and device set type (Rx) mismatch"); + return 404; + } + + if (deviceSet->m_deviceSinkEngine && !selectedPreset->isSinkPreset()) + { + error.init(); + *error.getMessage() = QString("Preset type and device set type (Tx) mismatch"); + return 404; + } + + if (deviceSet->m_deviceSinkEngine && !selectedPreset->isMIMOPreset()) + { + error.init(); + *error.getMessage() = QString("Preset type and device set type (MIMO) mismatch"); + return 404; + } + } + + MainCore::MsgSavePreset *msg = MainCore::MsgSavePreset::create(const_cast(selectedPreset), deviceSetIndex, false); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + response.setCenterFrequency(selectedPreset->getCenterFrequency()); + *response.getGroupName() = selectedPreset->getGroup(); + *response.getType() = selectedPreset->isSourcePreset() ? "R" : selectedPreset->isSinkPreset() ? "T": selectedPreset->isMIMOPreset() ? "M" : "X"; + *response.getName() = selectedPreset->getDescription(); + + return 202; +} + +int WebAPIAdapterSrv::instancePresetPost( + SWGSDRangel::SWGPresetTransfer& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error) +{ + int deviceSetIndex = query.getDeviceSetIndex(); + SWGSDRangel::SWGPresetIdentifier *presetIdentifier = query.getPreset(); + int nbDeviceSets = m_mainCore.m_deviceSets.size(); + + if (deviceSetIndex >= nbDeviceSets) + { + error.init(); + *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); + return 404; + } + + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + int deviceCenterFrequency = 0; + int presetTypeCode; + + if (deviceSet->m_deviceSourceEngine) { // Rx + deviceCenterFrequency = deviceSet->m_deviceSourceEngine->getSource()->getCenterFrequency(); + presetTypeCode = 0; + } else if (deviceSet->m_deviceSinkEngine) { // Tx + deviceCenterFrequency = deviceSet->m_deviceSinkEngine->getSink()->getCenterFrequency(); + presetTypeCode = 1; + } else if (deviceSet->m_deviceMIMOEngine) { // MIMO + deviceCenterFrequency = deviceSet->m_deviceMIMOEngine->getMIMO()->getMIMOCenterFrequency(); + presetTypeCode = 2; + } else { + error.init(); + *error.getMessage() = QString("Device set error"); + return 500; + } + + const Preset *selectedPreset = m_mainCore.m_settings.getPreset(*presetIdentifier->getGroupName(), + deviceCenterFrequency, + *presetIdentifier->getName(), + *presetIdentifier->getType()); + + if (selectedPreset == 0) // save on a new preset + { + selectedPreset = m_mainCore.m_settings.newPreset(*presetIdentifier->getGroupName(), *presetIdentifier->getName()); + } + else + { + error.init(); + *error.getMessage() = QString("Preset already exists [%1, %2, %3 %4]") + .arg(*presetIdentifier->getGroupName()) + .arg(deviceCenterFrequency) + .arg(*presetIdentifier->getName()) + .arg(*presetIdentifier->getType()); + return 409; + } + + MainCore::MsgSavePreset *msg = MainCore::MsgSavePreset::create(const_cast(selectedPreset), deviceSetIndex, true); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + response.setCenterFrequency(deviceCenterFrequency); + *response.getGroupName() = selectedPreset->getGroup(); + *response.getType() = presetTypeCode == 0 ? "R" : presetTypeCode == 1 ? "T" : presetTypeCode == 2 ? "M" : "X"; + *response.getName() = selectedPreset->getDescription(); + + return 202; +} + +int WebAPIAdapterSrv::instancePresetDelete( + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error) +{ + const Preset *selectedPreset = m_mainCore.m_settings.getPreset(*response.getGroupName(), + response.getCenterFrequency(), + *response.getName(), + *response.getType()); + + if (selectedPreset == 0) + { + error.init(); + *error.getMessage() = QString("There is no preset [%1, %2, %3 %4]") + .arg(*response.getGroupName()) + .arg(response.getCenterFrequency()) + .arg(*response.getName()) + .arg(*response.getType()); + return 404; + } + + response.setCenterFrequency(selectedPreset->getCenterFrequency()); + *response.getGroupName() = selectedPreset->getGroup(); + *response.getType() = selectedPreset->isSourcePreset() ? "R" : selectedPreset->isSinkPreset() ? "T" : selectedPreset->isMIMOPreset() ? "M" : "X"; + *response.getName() = selectedPreset->getDescription(); + + MainCore::MsgDeletePreset *msg = MainCore::MsgDeletePreset::create(const_cast(selectedPreset)); + m_mainCore.m_inputMessageQueue.push(msg); + + return 202; +} + +int WebAPIAdapterSrv::instanceDeviceSetsGet( + SWGSDRangel::SWGDeviceSetList& response, + SWGSDRangel::SWGErrorResponse& error) +{ + getDeviceSetList(&response); + return 200; +} + +int WebAPIAdapterSrv::instanceDeviceSetPost( + int direction, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + MainCore::MsgAddDeviceSet *msg = MainCore::MsgAddDeviceSet::create(direction); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + *response.getMessage() = QString("Message to add a new device set (MsgAddDeviceSet) was submitted successfully"); + + return 202; +} + +int WebAPIAdapterSrv::instanceDeviceSetDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if (m_mainCore.m_deviceSets.size() > 0) + { + MainCore::MsgRemoveLastDeviceSet *msg = MainCore::MsgRemoveLastDeviceSet::create(); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + *response.getMessage() = QString("Message to remove last device set (MsgRemoveLastDeviceSet) was submitted successfully"); + + return 202; + } + else + { + error.init(); + *error.getMessage() = "No more device sets to be removed"; + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceSet& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + const DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + getDeviceSet(&response, deviceSet, deviceSetIndex); + + return 200; + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetFocusPatch( + int deviceSetIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + *error.getMessage() = QString("Not supported in server instance"); + return 400; +} + +int WebAPIAdapterSrv::devicesetDevicePut( + int deviceSetIndex, + SWGSDRangel::SWGDeviceListItem& query, + SWGSDRangel::SWGDeviceListItem& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if ((query.getDirection() != 1) && (deviceSet->m_deviceSinkEngine)) + { + error.init(); + *error.getMessage() = QString("Device type and device set type (Tx) mismatch"); + return 404; + } + + if ((query.getDirection() != 0) && (deviceSet->m_deviceSourceEngine)) + { + error.init(); + *error.getMessage() = QString("Device type and device set type (Rx) mismatch"); + return 404; + } + + if ((query.getDirection() != 2) && (deviceSet->m_deviceMIMOEngine)) + { + error.init(); + *error.getMessage() = QString("Device type and device set type (MIMO) mismatch"); + return 404; + } + + int nbSamplingDevices; + + if (query.getDirection() == 0) { + nbSamplingDevices = DeviceEnumerator::instance()->getNbRxSamplingDevices(); + } else if (query.getDirection() == 1) { + nbSamplingDevices = DeviceEnumerator::instance()->getNbTxSamplingDevices(); + } else if (query.getDirection() == 2) { + nbSamplingDevices = DeviceEnumerator::instance()->getNbMIMOSamplingDevices(); + } else { + nbSamplingDevices = 0; // TODO: not implemented yet + } + + for (int i = 0; i < nbSamplingDevices; i++) + { + int direction; + const PluginInterface::SamplingDevice *samplingDevice; + + if (query.getDirection() == 0) + { + direction = 0; + samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(i); + } + else if (query.getDirection() == 1) + { + direction = 1; + samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(i); + } + else if (query.getDirection() == 2) + { + direction = 2; + samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(i); + } + else + { + continue; // device not supported + } + + if (query.getDisplayedName() && (*query.getDisplayedName() != samplingDevice->displayedName)) { + continue; + } + + if (query.getHwType() && (*query.getHwType() != samplingDevice->hardwareId)) { + continue; + } + + if ((query.getSequence() >= 0) && (query.getSequence() != samplingDevice->sequence)) { + continue; + } + + if (query.getSerial() && (*query.getSerial() != samplingDevice->serial)) { + continue; + } + + if ((query.getDeviceStreamIndex() >= 0) && (query.getDeviceStreamIndex() != samplingDevice->deviceItemIndex)) { + continue; + } + + MainCore::MsgSetDevice *msg = MainCore::MsgSetDevice::create(deviceSetIndex, i, query.getDirection()); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + *response.getDisplayedName() = samplingDevice->displayedName; + *response.getHwType() = samplingDevice->hardwareId; + *response.getSerial() = samplingDevice->serial; + response.setSequence(samplingDevice->sequence); + response.setDirection(direction); + response.setDeviceNbStreams(samplingDevice->deviceNbItems); + response.setDeviceStreamIndex(samplingDevice->deviceItemIndex); + response.setDeviceSetIndex(deviceSetIndex); + response.setIndex(i); + + return 202; + } + + error.init(); + *error.getMessage() = QString("Device not found"); + return 404; + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetSpectrumSettingsGet( + int deviceSetIndex, + SWGSDRangel::SWGGLSpectrum& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + const DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + return deviceSet->webapiSpectrumSettingsGet(response, *error.getMessage()); + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetSpectrumSettingsPutPatch( + int deviceSetIndex, + bool force, //!< true to force settings = put else patch + const QStringList& spectrumSettingsKeys, + SWGSDRangel::SWGGLSpectrum& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + return deviceSet->webapiSpectrumSettingsPutPatch(force, spectrumSettingsKeys, response, *error.getMessage()); + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetSpectrumServerGet( + int deviceSetIndex, + SWGSDRangel::SWGSpectrumServer& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + const DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + deviceSet->webapiSpectrumServerGet(response, *error.getMessage()); + + return 200; + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetSpectrumServerPost( + int deviceSetIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + deviceSet->webapiSpectrumServerPost(response, *error.getMessage()); + + return 200; + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetSpectrumServerDelete( + int deviceSetIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + deviceSet->webapiSpectrumServerDelete(response, *error.getMessage()); + + return 200; + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceSettingsGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceSettings& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + response.setDeviceHwType(new QString(deviceSet->m_deviceAPI->getHardwareId())); + response.setDirection(0); + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + return source->webapiSettingsGet(response, *error.getMessage()); + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + response.setDeviceHwType(new QString(deviceSet->m_deviceAPI->getHardwareId())); + response.setDirection(1); + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + return sink->webapiSettingsGet(response, *error.getMessage()); + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + response.setDeviceHwType(new QString(deviceSet->m_deviceAPI->getHardwareId())); + response.setDirection(2); + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + return mimo->webapiSettingsGet(response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceActionsPost( + int deviceSetIndex, + const QStringList& deviceActionsKeys, + SWGSDRangel::SWGDeviceActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + if (query.getDirection() != 0) + { + *error.getMessage() = QString("Single Rx device found but other type of device requested"); + return 400; + } + if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 input").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + int res = source->webapiActionsPost(deviceActionsKeys, query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + if (query.getDirection() != 1) + { + *error.getMessage() = QString("Single Tx device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + int res = sink->webapiActionsPost(deviceActionsKeys, query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + if (query.getDirection() != 2) + { + *error.getMessage() = QString("MIMO device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + int res = mimo->webapiActionsPost(deviceActionsKeys, 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("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceSettingsPutPatch( + int deviceSetIndex, + bool force, + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + if (response.getDirection() != 0) + { + *error.getMessage() = QString("Single Rx device found but other type of device requested"); + return 400; + } + if (deviceSet->m_deviceAPI->getHardwareId() != *response.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 input").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + return source->webapiSettingsPutPatch(force, deviceSettingsKeys, response, *error.getMessage()); + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + if (response.getDirection() != 1) + { + *error.getMessage() = QString("Single Tx device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *response.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + return sink->webapiSettingsPutPatch(force, deviceSettingsKeys, response, *error.getMessage()); + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + if (response.getDirection() != 2) + { + *error.getMessage() = QString("MIMO device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *response.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + return mimo->webapiSettingsPutPatch(force, deviceSettingsKeys, response, *error.getMessage()); + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceRunGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Rx + { + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + response.init(); + return source->webapiRunGet(response, *error.getMessage()); + } + else if (deviceSet->m_deviceSinkEngine) // Tx + { + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + response.init(); + return sink->webapiRunGet(response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceSubsystemRunGet( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceMIMOEngine) // MIMO + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + response.init(); + return mimo->webapiRunGet(subsystemIndex, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceRunPost( + int deviceSetIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Rx + { + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + response.init(); + return source->webapiRun(true, response, *error.getMessage()); + } + else if (deviceSet->m_deviceSinkEngine) // Tx + { + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + response.init(); + return sink->webapiRun(true, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceSubsystemRunPost( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceMIMOEngine) // MIMO + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + response.init(); + return mimo->webapiRun(true, subsystemIndex, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceRunDelete( + int deviceSetIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Rx + { + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + response.init(); + return source->webapiRun(false, response, *error.getMessage()); + } + else if (deviceSet->m_deviceSinkEngine) // Tx + { + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + response.init(); + return sink->webapiRun(false, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceSubsystemRunDelete( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceMIMOEngine) // MIMO + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + response.init(); + return mimo->webapiRun(false, subsystemIndex, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetDeviceReportGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceReport& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + response.setDeviceHwType(new QString(deviceSet->m_deviceAPI->getHardwareId())); + response.setDirection(0); + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + return source->webapiReportGet(response, *error.getMessage()); + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + response.setDeviceHwType(new QString(deviceSet->m_deviceAPI->getHardwareId())); + response.setDirection(1); + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + return sink->webapiReportGet(response, *error.getMessage()); + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + response.setDeviceHwType(new QString(deviceSet->m_deviceAPI->getHardwareId())); + response.setDirection(2); + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + return mimo->webapiReportGet(response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetChannelsReportGet( + int deviceSetIndex, + SWGSDRangel::SWGChannelsDetail& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + const DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + getChannelsDetail(&response, deviceSet); + + return 200; + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + +int WebAPIAdapterSrv::devicesetChannelPost( + int deviceSetIndex, + SWGSDRangel::SWGChannelSettings& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (query.getDirection() == 0) // Single Rx + { + if (!deviceSet->m_deviceSourceEngine && !deviceSet->m_deviceMIMOEngine) + { + error.init(); + *error.getMessage() = QString("Device set at %1 is not a receive capable device set").arg(deviceSetIndex); + return 400; + } + + PluginAPI::ChannelRegistrations *channelRegistrations = m_mainCore.m_pluginManager->getRxChannelRegistrations(); + int nbRegistrations = channelRegistrations->size(); + int index = 0; + for (; index < nbRegistrations; index++) + { + if (channelRegistrations->at(index).m_channelId == *query.getChannelType()) { + break; + } + } + + if (index < nbRegistrations) + { + MainCore::MsgAddChannel *msg = MainCore::MsgAddChannel::create(deviceSetIndex, index, false); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + *response.getMessage() = QString("Message to add a channel (MsgAddChannel) was submitted successfully"); + + return 202; + } + else + { + error.init(); + *error.getMessage() = QString("There is no receive channel with id %1").arg(*query.getChannelType()); + return 404; + } + } + else if (query.getDirection() == 1) // single Tx + { + if (!deviceSet->m_deviceSinkEngine && !deviceSet->m_deviceMIMOEngine) + { + error.init(); + *error.getMessage() = QString("Device set at %1 is not a transmit capable device set").arg(deviceSetIndex); + return 400; + } + + PluginAPI::ChannelRegistrations *channelRegistrations = m_mainCore.m_pluginManager->getTxChannelRegistrations(); + int nbRegistrations = channelRegistrations->size(); + int index = 0; + for (; index < nbRegistrations; index++) + { + if (channelRegistrations->at(index).m_channelId == *query.getChannelType()) { + break; + } + } + + if (index < nbRegistrations) + { + MainCore::MsgAddChannel *msg = MainCore::MsgAddChannel::create(deviceSetIndex, index, true); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + *response.getMessage() = QString("Message to add a channel (MsgAddChannel) was submitted successfully"); + + return 202; + } + else + { + error.init(); + *error.getMessage() = QString("There is no transmit channel with id %1").arg(*query.getChannelType()); + return 404; + } + } + else if (query.getDirection() == 2) // MIMO + { + if (!deviceSet->m_deviceMIMOEngine) + { + error.init(); + *error.getMessage() = QString("Device set at %1 is not a MIMO capable device set").arg(deviceSetIndex); + return 400; + } + + PluginAPI::ChannelRegistrations *channelRegistrations = m_mainCore.m_pluginManager->getMIMOChannelRegistrations(); + int nbRegistrations = channelRegistrations->size(); + int index = 0; + for (; index < nbRegistrations; index++) + { + if (channelRegistrations->at(index).m_channelId == *query.getChannelType()) { + break; + } + } + + if (index < nbRegistrations) + { + MainCore::MsgAddChannel *msg = MainCore::MsgAddChannel::create(deviceSetIndex, index, true); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + *response.getMessage() = QString("Message to add a channel (MsgAddChannel) was submitted successfully"); + + return 202; + } + else + { + error.init(); + *error.getMessage() = QString("There is no MIMO channel with id %1").arg(*query.getChannelType()); + return 404; + } + } + else + { + error.init(); + *error.getMessage() = QString("This type of device is not implemented yet"); + return 400; + } + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetChannelDelete( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (channelIndex < deviceSet->getNumberOfChannels()) + { + MainCore::MsgDeleteChannel *msg = MainCore::MsgDeleteChannel::create(deviceSetIndex, channelIndex); + m_mainCore.m_inputMessageQueue.push(msg); + + response.init(); + *response.getMessage() = QString("Message to delete a channel (MsgDeleteChannel) was submitted successfully"); + + return 202; + } + else + { + error.init(); + *error.getMessage() = QString("There is no channel at index %1. There are %2 channels") + .arg(channelIndex) + .arg(channelIndex < deviceSet->getNumberOfChannels()); + return 400; + } + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetChannelSettingsGet( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + response.setChannelType(new QString()); + channelAPI->getIdentifier(*response.getChannelType()); + response.setDirection(0); + return channelAPI->webapiSettingsGet(response, *error.getMessage()); + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + response.setChannelType(new QString()); + channelAPI->getIdentifier(*response.getChannelType()); + response.setDirection(1); + return channelAPI->webapiSettingsGet(response, *error.getMessage()); + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + ChannelAPI *channelAPI = nullptr; + + if (channelIndex < nbSinkChannels) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + response.setDirection(0); + } + else if (channelIndex < nbSinkChannels + nbSourceChannels) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex - nbSinkChannels); + response.setDirection(1); + } + else if (channelIndex < nbSinkChannels + nbSourceChannels + nbMIMOChannels) + { + channelAPI = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(channelIndex - nbSinkChannels - nbSourceChannels); + response.setDirection(2); + } + else + { + *error.getMessage() = QString("Ther is no channel with index %1").arg(channelIndex); + return 404; + } + + if (channelAPI) + { + response.setChannelType(new QString()); + channelAPI->getIdentifier(*response.getChannelType()); + return channelAPI->webapiSettingsGet(response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("Ther is no channel with index %1").arg(channelIndex); + return 404; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetChannelReportGet( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelReport& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + response.setChannelType(new QString()); + channelAPI->getIdentifier(*response.getChannelType()); + response.setDirection(0); + return channelAPI->webapiReportGet(response, *error.getMessage()); + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + response.setChannelType(new QString()); + channelAPI->getIdentifier(*response.getChannelType()); + response.setDirection(1); + return channelAPI->webapiReportGet(response, *error.getMessage()); + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + ChannelAPI *channelAPI = nullptr; + + if (channelIndex < nbSinkChannels) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + response.setDirection(0); + } + else if (channelIndex < nbSinkChannels + nbSourceChannels) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex - nbSinkChannels); + response.setDirection(1); + } + else if (channelIndex < nbSinkChannels + nbSourceChannels + nbMIMOChannels) + { + channelAPI = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(channelIndex - nbSinkChannels - nbSourceChannels); + response.setDirection(2); + } + else + { + *error.getMessage() = QString("Ther is no channel with index %1").arg(channelIndex); + return 404; + } + + if (channelAPI) + { + response.setChannelType(new QString()); + channelAPI->getIdentifier(*response.getChannelType()); + return channelAPI->webapiReportGet(response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("Ther is no channel with index %1").arg(channelIndex); + return 404; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetChannelActionsPost( + int deviceSetIndex, + int channelIndex, + const QStringList& channelActionsKeys, + SWGSDRangel::SWGChannelActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(channelActionsKeys, 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 channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(channelActionsKeys, 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 channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + ChannelAPI *channelAPI = nullptr; + + if ((query.getDirection() == 0) && (channelIndex < nbSinkChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + } + else if ((query.getDirection() == 1) && (channelIndex < nbSinkChannels + nbSourceChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex - nbSinkChannels); + } + else if ((query.getDirection() == 2) && (channelIndex < nbSinkChannels + nbSourceChannels + nbMIMOChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(channelIndex - nbSinkChannels - nbSourceChannels); + } + else + { + *error.getMessage() = QString("here is no channel with index %1").arg(channelIndex); + return 404; + } + + if (channelAPI) + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(channelActionsKeys, 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 channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + else + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +int WebAPIAdapterSrv::devicesetChannelSettingsPutPatch( + int deviceSetIndex, + int channelIndex, + bool force, + const QStringList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Rx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *response.getChannelType()) + { + return channelAPI->webapiSettingsPutPatch(force, channelSettingsKeys, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*response.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceSinkEngine) // Tx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *response.getChannelType()) + { + return channelAPI->webapiSettingsPutPatch(force, channelSettingsKeys, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*response.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + ChannelAPI *channelAPI = nullptr; + + if (channelIndex < nbSinkChannels) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + response.setDirection(0); + } + else if (channelIndex < nbSinkChannels + nbSourceChannels) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex - nbSinkChannels); + response.setDirection(1); + } + else if (channelIndex < nbSinkChannels + nbSourceChannels + nbMIMOChannels) + { + channelAPI = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(channelIndex - nbSinkChannels - nbSourceChannels); + response.setDirection(2); + } + else + { + *error.getMessage() = QString("here is no channel with index %1").arg(channelIndex); + return 404; + } + + if (channelAPI) + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *response.getChannelType()) + { + return channelAPI->webapiSettingsPutPatch(force, channelSettingsKeys, response, *error.getMessage()); + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*response.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + else + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + +void WebAPIAdapterSrv::getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSetList) +{ + deviceSetList->init(); + deviceSetList->setDevicesetcount((int) m_mainCore.m_deviceSets.size()); + + std::vector::const_iterator it = m_mainCore.m_deviceSets.begin(); + + for (int i = 0; it != m_mainCore.m_deviceSets.end(); ++it, i++) + { + QList *deviceSets = deviceSetList->getDeviceSets(); + deviceSets->append(new SWGSDRangel::SWGDeviceSet()); + + getDeviceSet(deviceSets->back(), *it, i); + } +} + +void WebAPIAdapterSrv::getDeviceSet(SWGSDRangel::SWGDeviceSet *swgDeviceSet, const DeviceSet* deviceSet, int deviceUISetIndex) +{ + swgDeviceSet->init(); + SWGSDRangel::SWGSamplingDevice *samplingDevice = swgDeviceSet->getSamplingDevice(); + samplingDevice->init(); + samplingDevice->setIndex(deviceUISetIndex); + + if (deviceSet->m_deviceSinkEngine) // Single Tx data + { + samplingDevice->setDirection(1); + *samplingDevice->getHwType() = deviceSet->m_deviceAPI->getHardwareId(); + *samplingDevice->getSerial() = deviceSet->m_deviceAPI->getSamplingDeviceSerial(); + samplingDevice->setSequence(deviceSet->m_deviceAPI->getSamplingDeviceSequence()); + samplingDevice->setDeviceNbStreams(deviceSet->m_deviceAPI->getDeviceNbItems()); + samplingDevice->setDeviceStreamIndex(deviceSet->m_deviceAPI->getDeviceItemIndex()); + deviceSet->m_deviceAPI->getDeviceEngineStateStr(*samplingDevice->getState()); + DeviceSampleSink *sampleSink = deviceSet->m_deviceSinkEngine->getSink(); + + if (sampleSink) { + samplingDevice->setCenterFrequency(sampleSink->getCenterFrequency()); + samplingDevice->setBandwidth(sampleSink->getSampleRate()); + } + + swgDeviceSet->setChannelcount(deviceSet->m_deviceAPI->getNbSourceChannels()); + QList *channels = swgDeviceSet->getChannels(); + + for (int i = 0; i < swgDeviceSet->getChannelcount(); i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSourceAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(1); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + } + } + + if (deviceSet->m_deviceSourceEngine) // Single Rx data + { + samplingDevice->setDirection(0); + *samplingDevice->getHwType() = deviceSet->m_deviceAPI->getHardwareId(); + *samplingDevice->getSerial() = deviceSet->m_deviceAPI->getSamplingDeviceSerial(); + samplingDevice->setSequence(deviceSet->m_deviceAPI->getSamplingDeviceSequence()); + samplingDevice->setDeviceNbStreams(deviceSet->m_deviceAPI->getDeviceNbItems()); + samplingDevice->setDeviceStreamIndex(deviceSet->m_deviceAPI->getDeviceItemIndex()); + deviceSet->m_deviceAPI->getDeviceEngineStateStr(*samplingDevice->getState()); + DeviceSampleSource *sampleSource = deviceSet->m_deviceSourceEngine->getSource(); + + if (sampleSource) { + samplingDevice->setCenterFrequency(sampleSource->getCenterFrequency()); + samplingDevice->setBandwidth(sampleSource->getSampleRate()); + } + + swgDeviceSet->setChannelcount(deviceSet->m_deviceAPI->getNbSinkChannels()); + QList *channels = swgDeviceSet->getChannels(); + + for (int i = 0; i < swgDeviceSet->getChannelcount(); i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSinkAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(0); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + } + } + + if (deviceSet->m_deviceMIMOEngine) // MIMO data + { + samplingDevice->setDirection(2); + *samplingDevice->getHwType() = deviceSet->m_deviceAPI->getHardwareId(); + *samplingDevice->getSerial() = deviceSet->m_deviceAPI->getSamplingDeviceSerial(); + samplingDevice->setSequence(deviceSet->m_deviceAPI->getSamplingDeviceSequence()); + samplingDevice->setDeviceNbStreams(deviceSet->m_deviceAPI->getDeviceNbItems()); + samplingDevice->setDeviceStreamIndex(deviceSet->m_deviceAPI->getDeviceItemIndex()); + samplingDevice->setState(new QString("notStarted")); + deviceSet->m_deviceAPI->getDeviceEngineStateStr(*samplingDevice->getStateRx(), 0); + deviceSet->m_deviceAPI->getDeviceEngineStateStr(*samplingDevice->getStateTx(), 1); + DeviceSampleMIMO *sampleMIMO = deviceSet->m_deviceMIMOEngine->getMIMO(); + + if (sampleMIMO) + { + samplingDevice->setCenterFrequency(sampleMIMO->getMIMOCenterFrequency()); + samplingDevice->setBandwidth(sampleMIMO->getMIMOSampleRate()); + } + + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + swgDeviceSet->setChannelcount(nbSinkChannels + nbSourceChannels + nbMIMOChannels); + QList *channels = swgDeviceSet->getChannels(); + + for (int i = 0; i < nbSinkChannels; i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSinkAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(0); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + } + + for (int i = 0; i < nbSourceChannels; i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSourceAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(1); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + } + + for (int i = 0; i < nbMIMOChannels; i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(2); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + } + } +} + +void WebAPIAdapterSrv::getChannelsDetail(SWGSDRangel::SWGChannelsDetail *channelsDetail, const DeviceSet* deviceSet) +{ + channelsDetail->init(); + SWGSDRangel::SWGChannelReport *channelReport; + QString channelReportError; + + if (deviceSet->m_deviceSinkEngine) // Tx data + { + channelsDetail->setChannelcount(deviceSet->m_deviceAPI->getNbSourceChannels()); + QList *channels = channelsDetail->getChannels(); + + for (int i = 0; i < channelsDetail->getChannelcount(); i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSourceAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(1); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + + channelReport = new SWGSDRangel::SWGChannelReport(); + + if (channel->webapiReportGet(*channelReport, channelReportError) != 501) { + channels->back()->setReport(channelReport); + } else { + delete channelReport; + } + } + } + + if (deviceSet->m_deviceSourceEngine) // Rx data + { + channelsDetail->setChannelcount(deviceSet->m_deviceAPI->getNbSinkChannels()); + QList *channels = channelsDetail->getChannels(); + + for (int i = 0; i < channelsDetail->getChannelcount(); i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSinkAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(0); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + + channelReport = new SWGSDRangel::SWGChannelReport(); + + if (channel->webapiReportGet(*channelReport, channelReportError) != 501) { + channels->back()->setReport(channelReport); + } else { + delete channelReport; + } + } + } + + if (deviceSet->m_deviceMIMOEngine) // MIMO data + { + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + QList *channels = channelsDetail->getChannels(); + channelsDetail->setChannelcount(nbSinkChannels + nbSourceChannels + nbMIMOChannels); + + for (int i = 0; i < nbSinkChannels; i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSinkAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(0); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + + channelReport = new SWGSDRangel::SWGChannelReport(); + + if (channel->webapiReportGet(*channelReport, channelReportError) != 501) { + channels->back()->setReport(channelReport); + } else { + delete channelReport; + } + } + + for (int i = 0; i < nbSourceChannels; i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getChanelSourceAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(1); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + + channelReport = new SWGSDRangel::SWGChannelReport(); + + if (channel->webapiReportGet(*channelReport, channelReportError) != 501) { + channels->back()->setReport(channelReport); + } else { + delete channelReport; + } + } + + for (int i = 0; i < nbMIMOChannels; i++) + { + channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); + ChannelAPI *channel = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(i); + channels->back()->setDeltaFrequency(channel->getCenterFrequency()); + channels->back()->setDirection(2); + channels->back()->setIndex(channel->getIndexInDeviceSet()); + channels->back()->setUid(channel->getUID()); + channel->getIdentifier(*channels->back()->getId()); + channel->getTitle(*channels->back()->getTitle()); + + channelReport = new SWGSDRangel::SWGChannelReport(); + + if (channel->webapiReportGet(*channelReport, channelReportError) != 501) { + channels->back()->setReport(channelReport); + } else { + delete channelReport; + } + } + } +} + +QtMsgType WebAPIAdapterSrv::getMsgTypeFromString(const QString& msgTypeString) +{ + if (msgTypeString == "debug") { + return QtDebugMsg; + } else if (msgTypeString == "info") { + return QtInfoMsg; + } else if (msgTypeString == "warning") { + return QtWarningMsg; + } else if (msgTypeString == "error") { + return QtCriticalMsg; + } else { + return QtDebugMsg; + } +} + +void WebAPIAdapterSrv::getMsgTypeString(const QtMsgType& msgType, QString& levelStr) +{ + switch (msgType) + { + case QtDebugMsg: + levelStr = "debug"; + break; + case QtInfoMsg: + levelStr = "info"; + break; + case QtWarningMsg: + levelStr = "warning"; + break; + case QtCriticalMsg: + case QtFatalMsg: + levelStr = "error"; + break; + default: + levelStr = "debug"; + break; + } +} diff --git a/sdrsrv/webapi/webapiadaptersrv.h b/sdrsrv/webapi/webapiadaptersrv.h new file mode 100644 index 000000000..d7fe1175e --- /dev/null +++ b/sdrsrv/webapi/webapiadaptersrv.h @@ -0,0 +1,370 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRSRV_WEBAPI_WEBAPIADAPTERSRV_H_ +#define SDRSRV_WEBAPI_WEBAPIADAPTERSRV_H_ + +#include + +#include "webapi/webapiadapterinterface.h" + +class MainCore; +class DeviceSet; + +class WebAPIAdapterSrv: public WebAPIAdapterInterface +{ +public: + WebAPIAdapterSrv(MainCore& mainCore); + virtual ~WebAPIAdapterSrv(); + + virtual int instanceSummary( + SWGSDRangel::SWGInstanceSummaryResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceConfigGet( + SWGSDRangel::SWGInstanceConfigResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceConfigPutPatch( + bool force, // PUT else PATCH + SWGSDRangel::SWGInstanceConfigResponse& query, + const ConfigKeys& configKeys, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceDevices( + int direction, + SWGSDRangel::SWGInstanceDevicesResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceChannels( + int direction, + SWGSDRangel::SWGInstanceChannelsResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLoggingGet( + SWGSDRangel::SWGLoggingInfo& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLoggingPut( + SWGSDRangel::SWGLoggingInfo& query, + SWGSDRangel::SWGLoggingInfo& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAudioGet( + SWGSDRangel::SWGAudioDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAudioInputPatch( + SWGSDRangel::SWGAudioInputDevice& response, + const QStringList& audioInputKeys, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAudioOutputPatch( + SWGSDRangel::SWGAudioOutputDevice& response, + const QStringList& audioOutputKeys, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAudioInputDelete( + SWGSDRangel::SWGAudioInputDevice& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAudioOutputDelete( + SWGSDRangel::SWGAudioOutputDevice& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAudioInputCleanupPatch( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAudioOutputCleanupPatch( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLocationGet( + SWGSDRangel::SWGLocationInformation& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLocationPut( + SWGSDRangel::SWGLocationInformation& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceDVSerialGet( + SWGSDRangel::SWGDVSerialDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceDVSerialPatch( + bool dvserial, + SWGSDRangel::SWGDVSerialDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAMBESerialGet( + SWGSDRangel::SWGDVSerialDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAMBEDevicesGet( + SWGSDRangel::SWGAMBEDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAMBEDevicesPut( + SWGSDRangel::SWGAMBEDevices& query, + SWGSDRangel::SWGAMBEDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAMBEDevicesPatch( + SWGSDRangel::SWGAMBEDevices& query, + SWGSDRangel::SWGAMBEDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceAMBEDevicesDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + +#ifdef HAS_LIMERFEUSB + virtual int instanceLimeRFESerialGet( + SWGSDRangel::SWGLimeRFEDevices& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLimeRFEConfigGet( + const QString& serial, + SWGSDRangel::SWGLimeRFESettings& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLimeRFEConfigPut( + SWGSDRangel::SWGLimeRFESettings& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLimeRFERunPut( + SWGSDRangel::SWGLimeRFESettings& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceLimeRFEPowerGet( + const QString& serial, + SWGSDRangel::SWGLimeRFEPower& response, + SWGSDRangel::SWGErrorResponse& error); +#endif + + virtual int instancePresetFilePut( + SWGSDRangel::SWGPresetImport& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instancePresetFilePost( + SWGSDRangel::SWGPresetExport& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instancePresetsGet( + SWGSDRangel::SWGPresets& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instancePresetPatch( + SWGSDRangel::SWGPresetTransfer& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instancePresetPut( + SWGSDRangel::SWGPresetTransfer& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instancePresetPost( + SWGSDRangel::SWGPresetTransfer& query, + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instancePresetDelete( + SWGSDRangel::SWGPresetIdentifier& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceDeviceSetsGet( + SWGSDRangel::SWGDeviceSetList& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceDeviceSetPost( + int direction, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceDeviceSetDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceSet& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetFocusPatch( + int deviceSetIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDevicePut( + int deviceSetIndex, + SWGSDRangel::SWGDeviceListItem& query, + SWGSDRangel::SWGDeviceListItem& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetSpectrumSettingsGet( + int deviceSetIndex, + SWGSDRangel::SWGGLSpectrum& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetSpectrumSettingsPutPatch( + int deviceSetIndex, + bool force, //!< true to force settings = put else patch + const QStringList& spectrumSettingsKeys, + SWGSDRangel::SWGGLSpectrum& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetSpectrumServerGet( + int deviceSetIndex, + SWGSDRangel::SWGSpectrumServer& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetSpectrumServerPost( + int deviceSetIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetSpectrumServerDelete( + int deviceSetIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSettingsGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceSettings& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceActionsPost( + int deviceSetIndex, + const QStringList& deviceActionsKeys, + SWGSDRangel::SWGDeviceActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSettingsPutPatch( + int deviceSetIndex, + bool force, + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceRunGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceRunPost( + int deviceSetIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceRunDelete( + int deviceSetIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSubsystemRunGet( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSubsystemRunPost( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSubsystemRunDelete( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceReportGet( + int deviceSetIndex, + SWGSDRangel::SWGDeviceReport& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetChannelsReportGet( + int deviceSetIndex, + SWGSDRangel::SWGChannelsDetail& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetChannelPost( + int deviceSetIndex, + SWGSDRangel::SWGChannelSettings& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetChannelDelete( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetChannelSettingsGet( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetChannelActionsPost( + int deviceSetIndex, + int channelIndex, + const QStringList& channelActionsKeys, + SWGSDRangel::SWGChannelActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetChannelSettingsPutPatch( + int deviceSetIndex, + int channelIndex, + bool force, + const QStringList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetChannelReportGet( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelReport& 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); + static QtMsgType getMsgTypeFromString(const QString& msgTypeString); + static void getMsgTypeString(const QtMsgType& msgType, QString& level); +}; + +#endif /* SDRSRV_WEBAPI_WEBAPIADAPTERSRV_H_ */