mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-06-25 05:25:27 -04:00
commit
ca5898bc57
@ -190,6 +190,8 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
||||
|
||||
MainWindow w(logger, parser);
|
||||
|
||||
w.show();
|
||||
|
||||
if (parser.getListDevices())
|
||||
{
|
||||
// List available physical devices and exit
|
||||
@ -197,12 +199,6 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (parser.getRemoteTCPSink()) {
|
||||
RemoteTCPSinkStarter::start(parser);
|
||||
}
|
||||
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,8 @@ typedef SSIZE_T ssize_t;
|
||||
#include "ldpctool/algorithms.h"
|
||||
#include "ldpctool/ldpcworker.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace leansdr
|
||||
{
|
||||
|
||||
|
@ -2019,18 +2019,21 @@ bool ChannelWebAPIUtils::addChannel(unsigned int deviceSetIndex, const QString&
|
||||
}
|
||||
|
||||
// response will be deleted after device is opened.
|
||||
bool ChannelWebAPIUtils::addDevice(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response)
|
||||
bool ChannelWebAPIUtils::addDevice(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response, QObject *receiver, const char *slot)
|
||||
{
|
||||
return DeviceOpener::open(hwType, direction, settingsKeys, response);
|
||||
return DeviceOpener::open(hwType, direction, settingsKeys, response, receiver, slot);
|
||||
}
|
||||
|
||||
DeviceOpener::DeviceOpener(int deviceIndex, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response) :
|
||||
DeviceOpener::DeviceOpener(int deviceIndex, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response, QObject *receiver, const char *slot) :
|
||||
m_deviceIndex(deviceIndex),
|
||||
m_direction(direction),
|
||||
m_settingsKeys(settingsKeys),
|
||||
m_response(response),
|
||||
m_device(nullptr)
|
||||
{
|
||||
if (receiver) {
|
||||
connect(this, SIGNAL(deviceOpened(int)), receiver, slot);
|
||||
}
|
||||
connect(MainCore::instance(), &MainCore::deviceSetAdded, this, &DeviceOpener::deviceSetAdded);
|
||||
// Create DeviceSet
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
@ -2046,33 +2049,30 @@ void DeviceOpener::deviceSetAdded(int index, DeviceAPI *device)
|
||||
disconnect(MainCore::instance(), &MainCore::deviceSetAdded, this, &DeviceOpener::deviceSetAdded);
|
||||
|
||||
m_device = device;
|
||||
|
||||
connect(MainCore::instance(), &MainCore::deviceChanged, this, &DeviceOpener::deviceChanged);
|
||||
// Set the correct device type
|
||||
MainCore::MsgSetDevice *msg = MainCore::MsgSetDevice::create(m_deviceSetIndex, m_deviceIndex, m_direction);
|
||||
MainCore::instance()->getMainMessageQueue()->push(msg);
|
||||
// Wait until device has initialised - FIXME: Better way to do this other than polling?
|
||||
m_timer.setInterval(250);
|
||||
connect(&m_timer, &QTimer::timeout, this, &DeviceOpener::checkInitialised);
|
||||
m_timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceOpener::checkInitialised()
|
||||
void DeviceOpener::deviceChanged(int index)
|
||||
{
|
||||
if (m_device && m_device->getSampleSource() && (m_device->state() >= DeviceAPI::EngineState::StIdle))
|
||||
{
|
||||
m_timer.stop();
|
||||
|
||||
// Apply device settings
|
||||
QString errorMessage;
|
||||
if (200 != m_device->getSampleSource()->webapiSettingsPutPatch(false, m_settingsKeys, *m_response, errorMessage)) {
|
||||
qDebug() << "DeviceOpener::checkInitialised: webapiSettingsPutPatch failed: " << errorMessage;
|
||||
}
|
||||
|
||||
// Signal device has been opened
|
||||
emit deviceOpened(m_deviceSetIndex);
|
||||
|
||||
delete m_response;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceOpener::open(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response)
|
||||
bool DeviceOpener::open(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response, QObject *receiver, const char *slot)
|
||||
{
|
||||
if (direction) {
|
||||
return false; // FIXME: Only RX support for now
|
||||
@ -2090,7 +2090,7 @@ bool DeviceOpener::open(const QString hwType, int direction, const QStringList&
|
||||
continue;
|
||||
}
|
||||
|
||||
new DeviceOpener(i, direction, settingsKeys, response);
|
||||
new DeviceOpener(i, direction, settingsKeys, response, receiver, slot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class DeviceAPI;
|
||||
class DeviceOpener : public QObject {
|
||||
Q_OBJECT
|
||||
protected:
|
||||
DeviceOpener(int deviceIndex, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response);
|
||||
DeviceOpener(int deviceIndex, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response, QObject *receiver, const char *slot);
|
||||
private:
|
||||
int m_deviceIndex;
|
||||
int m_direction;
|
||||
@ -51,13 +51,17 @@ private:
|
||||
QStringList m_settingsKeys;
|
||||
SWGSDRangel::SWGDeviceSettings *m_response;
|
||||
DeviceAPI *m_device;
|
||||
QTimer m_timer;
|
||||
|
||||
void createDeviceSet();
|
||||
private slots:
|
||||
void deviceSetAdded(int index, DeviceAPI *device);
|
||||
void checkInitialised();
|
||||
void deviceChanged(int index);
|
||||
public:
|
||||
static bool open(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response);
|
||||
bool open(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response);
|
||||
|
||||
static bool open(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response, QObject *receiver, const char *slot);
|
||||
signals:
|
||||
void deviceOpened(int deviceSetIndex);
|
||||
};
|
||||
|
||||
class SDRBASE_API ChannelWebAPIUtils
|
||||
@ -127,7 +131,7 @@ public:
|
||||
static bool getChannelSettings(ChannelAPI *channel, SWGSDRangel::SWGChannelSettings &channelSettingsResponse);
|
||||
static bool getChannelReport(unsigned int deviceIndex, unsigned int channelIndex, SWGSDRangel::SWGChannelReport &channelReport);
|
||||
static bool addChannel(unsigned int deviceSetIndex, const QString& uri, int direction);
|
||||
static bool addDevice(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response);
|
||||
static bool addDevice(const QString hwType, int direction, const QStringList& settingsKeys, SWGSDRangel::SWGDeviceSettings *response, QObject *receiver = nullptr, const char *slot = nullptr);
|
||||
protected:
|
||||
static QString getDeviceHardwareId(unsigned int deviceIndex);
|
||||
};
|
||||
|
@ -27,9 +27,11 @@
|
||||
#include "device/deviceenumerator.h"
|
||||
#include "dsp/devicesamplesource.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "channel/channelwebapiutils.h"
|
||||
#include "SWGChannelSettings.h"
|
||||
#include "SWGRemoteTCPSinkSettings.h"
|
||||
#include "SWGDeviceState.h"
|
||||
#include "SWGDeviceSettings.h"
|
||||
|
||||
// Lists available physical devices to stdout
|
||||
void RemoteTCPSinkStarter::listAvailableDevices()
|
||||
@ -53,133 +55,46 @@ void RemoteTCPSinkStarter::listAvailableDevices()
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate specified sampling source device and create a RemoteTCPSink channel
|
||||
// on the specified address and port and start the device
|
||||
static void startRemoteTCPSink(const QString& address, int port, const QString& hwType, const QString& serial)
|
||||
RemoteTCPSinkStarter::RemoteTCPSinkStarter(const QString& address, int port, const QString& hwType, const QString& serial) :
|
||||
m_dataAddress(address),
|
||||
m_dataPort(port),
|
||||
m_deviceSet(nullptr)
|
||||
{
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
|
||||
// Delete any existing device sets, in case requested device is already in use
|
||||
int initialDeviceSets = mainCore->getDeviceSets().size();
|
||||
for (int i = 0; i < initialDeviceSets; i++)
|
||||
{
|
||||
MainCore::MsgRemoveLastDeviceSet *msg = MainCore::MsgRemoveLastDeviceSet::create();
|
||||
mainCore->getMainMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
// Wait until they've been deleted
|
||||
if (initialDeviceSets > 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
QTime dieTime = QTime::currentTime().addMSecs(100);
|
||||
while (QTime::currentTime() < dieTime) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
}
|
||||
}
|
||||
while (mainCore->getDeviceSets().size() > 0);
|
||||
}
|
||||
|
||||
// Create DeviceSet
|
||||
unsigned int deviceSetIndex = mainCore->getDeviceSets().size();
|
||||
MainCore::MsgAddDeviceSet *msg = MainCore::MsgAddDeviceSet::create(0);
|
||||
mainCore->getMainMessageQueue()->push(msg);
|
||||
|
||||
// Switch to requested device type
|
||||
int nbSamplingDevices = DeviceEnumerator::instance()->getNbRxSamplingDevices();
|
||||
bool found = false;
|
||||
for (int i = 0; i < nbSamplingDevices; i++)
|
||||
{
|
||||
const PluginInterface::SamplingDevice *samplingDevice;
|
||||
|
||||
samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(i);
|
||||
|
||||
if (!hwType.isEmpty() && (hwType != samplingDevice->hardwareId)) {
|
||||
continue;
|
||||
}
|
||||
if (!serial.isEmpty() && (serial != samplingDevice->serial)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int direction = 0;
|
||||
MainCore::MsgSetDevice *msg = MainCore::MsgSetDevice::create(deviceSetIndex, i, direction);
|
||||
mainCore->getMainMessageQueue()->push(msg);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
qCritical() << "startRemoteTCPSink: Failed to find device";
|
||||
return;
|
||||
}
|
||||
// Add device of requested type
|
||||
SWGSDRangel::SWGDeviceSettings *response = new SWGSDRangel::SWGDeviceSettings();
|
||||
response->init();
|
||||
ChannelWebAPIUtils::addDevice(hwType, 0, QStringList(), response, this, SLOT(deviceOpened(int)));
|
||||
}
|
||||
|
||||
void RemoteTCPSinkStarter::deviceOpened(int deviceSetIndex)
|
||||
{
|
||||
m_deviceSet = MainCore::instance()->getDeviceSets()[deviceSetIndex];
|
||||
// Add RemoteTCPSink channel
|
||||
PluginAPI::ChannelRegistrations *channelRegistrations = mainCore->getPluginManager()->getRxChannelRegistrations();
|
||||
int nbRegistrations = channelRegistrations->size();
|
||||
int index = 0;
|
||||
for (; index < nbRegistrations; index++)
|
||||
{
|
||||
if (channelRegistrations->at(index).m_channelId == "RemoteTCPSink") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
connect(MainCore::instance(), &MainCore::channelAdded, this, &RemoteTCPSinkStarter::channelAdded);
|
||||
ChannelWebAPIUtils::addChannel(deviceSetIndex, "sdrangel.channel.remotetcpsink", 0);
|
||||
}
|
||||
|
||||
if (index < nbRegistrations)
|
||||
{
|
||||
MainCore::MsgAddChannel *msg = MainCore::MsgAddChannel::create(deviceSetIndex, index, 0);
|
||||
mainCore->getMainMessageQueue()->push(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical() << "startRemoteTCPSink: RemoteTCPSink is not available";
|
||||
return;
|
||||
}
|
||||
int channelIndex = 0;
|
||||
void RemoteTCPSinkStarter::channelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
(void) deviceSetIndex;
|
||||
|
||||
// Wait until device & channel are created - is there a better way?
|
||||
DeviceSet *deviceSet = nullptr;
|
||||
ChannelAPI *channelAPI = nullptr;
|
||||
do
|
||||
{
|
||||
QTime dieTime = QTime::currentTime().addMSecs(100);
|
||||
while (QTime::currentTime() < dieTime) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
}
|
||||
// Set RemoteTCPSink settings
|
||||
ChannelWebAPIUtils::patchChannelSetting(channel, "dataAddress", m_dataAddress);
|
||||
ChannelWebAPIUtils::patchChannelSetting(channel, "dataPort", m_dataPort);
|
||||
|
||||
if (mainCore->getDeviceSets().size() > deviceSetIndex)
|
||||
{
|
||||
deviceSet = mainCore->getDeviceSets()[deviceSetIndex];
|
||||
if (deviceSet) {
|
||||
channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (channelAPI == nullptr);
|
||||
// Wait for settings to be applied, then start the device
|
||||
QTimer::singleShot(250, [=] {
|
||||
startDevice();
|
||||
});
|
||||
}
|
||||
|
||||
// Set TCP settings
|
||||
QStringList channelSettingsKeys = {"dataAddress", "dataPort"};
|
||||
SWGSDRangel::SWGChannelSettings response;
|
||||
response.init();
|
||||
SWGSDRangel::SWGRemoteTCPSinkSettings *sinkSettings = response.getRemoteTcpSinkSettings();
|
||||
sinkSettings->setDataAddress(new QString(address));
|
||||
sinkSettings->setDataPort(port);
|
||||
QString errorMessage;
|
||||
channelAPI->webapiSettingsPutPatch(false, channelSettingsKeys, response, errorMessage);
|
||||
void RemoteTCPSinkStarter::startDevice()
|
||||
{
|
||||
// Start the device
|
||||
ChannelWebAPIUtils::run(m_deviceSet->getIndex());
|
||||
|
||||
// Wait some time for settings to be applied
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
|
||||
// Start the device (use WebAPI so GUI is updated)
|
||||
DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource();
|
||||
QStringList deviceActionsKeys;
|
||||
SWGSDRangel::SWGDeviceState state;
|
||||
state.init();
|
||||
int res = source->webapiRun(true, state, errorMessage);
|
||||
if (res != 200) {
|
||||
qCritical() << "startRemoteTCPSink: Failed to start device: " << res;
|
||||
} else {
|
||||
qInfo().nospace().noquote() << "Remote TCP Sink started on " << address << ":" << port;
|
||||
}
|
||||
// Delete object as we have finished
|
||||
delete this;
|
||||
}
|
||||
|
||||
// Start Remote TCP Sink on specified device, with specified address and port
|
||||
@ -191,8 +106,7 @@ void RemoteTCPSinkStarter::start(const MainParser& parser)
|
||||
QString remoteTCPSinkSerial = parser.getRemoteTCPSinkSerial();
|
||||
|
||||
QTimer::singleShot(250, [=] {
|
||||
startRemoteTCPSink(
|
||||
remoteTCPSinkAddress,
|
||||
new RemoteTCPSinkStarter(remoteTCPSinkAddress,
|
||||
remoteTCPSinkPort,
|
||||
remoteTCPSinkHWType,
|
||||
remoteTCPSinkSerial);
|
||||
|
@ -24,12 +24,34 @@
|
||||
#include "mainparser.h"
|
||||
#include "export.h"
|
||||
|
||||
class SDRBASE_API RemoteTCPSinkStarter {
|
||||
#include <QObject>
|
||||
|
||||
class DeviceSet;
|
||||
class DeviceAPI;
|
||||
class ChannelAPI;
|
||||
|
||||
class SDRBASE_API RemoteTCPSinkStarter : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
QString m_dataAddress;
|
||||
int m_dataPort;
|
||||
|
||||
DeviceSet *m_deviceSet;
|
||||
|
||||
public:
|
||||
static void listAvailableDevices();
|
||||
static void start(const MainParser& parser);
|
||||
|
||||
|
||||
private:
|
||||
RemoteTCPSinkStarter(const QString& address, int port, const QString& hwType, const QString& serial);
|
||||
void startDevice();
|
||||
|
||||
private slots:
|
||||
void deviceOpened(int deviceSetIndex);
|
||||
void channelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
|
||||
};
|
||||
|
||||
#endif /* REMOTETCPSINKSTARTER_H */
|
||||
|
@ -105,6 +105,7 @@
|
||||
#include "util/android.h"
|
||||
#endif
|
||||
|
||||
#include "remotetcpsinkstarter.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <audio/audiodevicemanager.h>
|
||||
@ -136,7 +137,8 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse
|
||||
#if QT_CONFIG(process)
|
||||
m_fftWisdomProcess(nullptr),
|
||||
#endif
|
||||
m_settingsSaved(false)
|
||||
m_settingsSaved(false),
|
||||
m_parser(parser)
|
||||
{
|
||||
QAccessible::installFactory(AccessibleValueDial::factory);
|
||||
QAccessible::installFactory(AccessibleValueDialZ::factory);
|
||||
@ -273,10 +275,12 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse
|
||||
restoreState(qUncompress(QByteArray::fromBase64(s.value("mainWindowState").toByteArray())));
|
||||
|
||||
// Load initial configuration
|
||||
InitFSM *fsm = new InitFSM(this, splash, !parser.getScratch());
|
||||
InitFSM *fsm = new InitFSM(this, splash, !parser.getScratch() && !parser.getRemoteTCPSink(), !parser.getRemoteTCPSink());
|
||||
connect(fsm, &InitFSM::finished, fsm, &InitFSM::deleteLater);
|
||||
connect(fsm, &InitFSM::finished, splash, &SDRangelSplash::deleteLater);
|
||||
if (parser.getStart()) {
|
||||
if (parser.getRemoteTCPSink()) {
|
||||
connect(fsm, &InitFSM::finished, this, &MainWindow::startRemoteTCPSink);
|
||||
} else if (parser.getStart()) {
|
||||
connect(fsm, &InitFSM::finished, this, &MainWindow::startAllAfterDelay);
|
||||
}
|
||||
fsm->start();
|
||||
@ -1183,9 +1187,10 @@ void LoadConfigurationFSM::restoreGeometry()
|
||||
}
|
||||
}
|
||||
|
||||
InitFSM::InitFSM(MainWindow *mainWindow, SDRangelSplash *splash, bool loadDefault, QObject *parent) :
|
||||
InitFSM::InitFSM(MainWindow *mainWindow, SDRangelSplash *splash, bool loadDefault, bool showConfigs, QObject *parent) :
|
||||
MainWindowFSM(mainWindow, parent),
|
||||
m_splash(splash)
|
||||
m_splash(splash),
|
||||
m_showConfigs(showConfigs)
|
||||
{
|
||||
// Create FSM
|
||||
createStates(2);
|
||||
@ -1222,6 +1227,8 @@ void InitFSM::showDefaultConfigurations()
|
||||
qDebug() << "MainWindow::MainWindow: no or empty current configuration, creating empty workspace...";
|
||||
m_mainWindow->addWorkspace();
|
||||
|
||||
if (m_showConfigs)
|
||||
{
|
||||
// If no configurations, load some basic examples
|
||||
if (m_mainWindow->m_mainCore->getMutableSettings().getConfigurations()->size() == 0) {
|
||||
m_mainWindow->loadDefaultConfigurations();
|
||||
@ -1232,7 +1239,8 @@ void InitFSM::showDefaultConfigurations()
|
||||
#endif
|
||||
// Show configurations
|
||||
m_mainWindow->openConfigurationDialog(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseFSM::CloseFSM(MainWindow *mainWindow, QObject *parent) :
|
||||
@ -3391,6 +3399,11 @@ void MainWindow::showAllChannels(int deviceSetIndex)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::startRemoteTCPSink()
|
||||
{
|
||||
RemoteTCPSinkStarter::start(m_parser);
|
||||
}
|
||||
|
||||
void MainWindow::startAllAfterDelay()
|
||||
{
|
||||
// Wait a little bit before starting all devices and features,
|
||||
|
@ -258,10 +258,11 @@ class InitFSM : public MainWindowFSM {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InitFSM(MainWindow *mainWindow, SDRangelSplash *splash, bool loadDefault, QObject *parent=nullptr);
|
||||
InitFSM(MainWindow *mainWindow, SDRangelSplash *splash, bool loadDefault, bool showConfigs, QObject *parent=nullptr);
|
||||
|
||||
private:
|
||||
SDRangelSplash *m_splash;
|
||||
bool m_showConfigs;
|
||||
LoadConfigurationFSM *m_loadConfigurationFSM;
|
||||
|
||||
void loadDefaultConfiguration();
|
||||
@ -345,6 +346,7 @@ private:
|
||||
#endif
|
||||
|
||||
bool m_settingsSaved; // Records if settings have already been saved in response to a QCloseEvent
|
||||
const MainParser& m_parser;
|
||||
|
||||
void loadSettings();
|
||||
void loadDeviceSetPresetSettings(const Preset* preset, int deviceSetIndex);
|
||||
@ -458,6 +460,7 @@ private slots:
|
||||
void featureMove(FeatureGUI *gui, int wsIndexDestnation);
|
||||
void deviceStateChanged(DeviceAPI *deviceAPI);
|
||||
void openFeaturePresetsDialog(QPoint p, Workspace *workspace);
|
||||
void startRemoteTCPSink();
|
||||
void startAllAfterDelay();
|
||||
void startAll();
|
||||
void startAllDevices(const Workspace *workspace) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user