From 99fca7c09ef3b13c295a34a1ae8350cc466ad837 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Fri, 20 Jun 2025 15:43:01 +0100 Subject: [PATCH] Fix --remote-tcp. For #2470 --- app/main.cpp | 10 +- plugins/channelrx/demoddatv/leansdr/dvbs2.h | 6 +- sdrbase/channel/channelwebapiutils.cpp | 42 +++--- sdrbase/channel/channelwebapiutils.h | 14 +- sdrbase/remotetcpsinkstarter.cpp | 156 +++++--------------- sdrbase/remotetcpsinkstarter.h | 24 ++- sdrgui/mainwindow.cpp | 47 +++--- sdrgui/mainwindow.h | 5 +- 8 files changed, 129 insertions(+), 175 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index b79e7fe15..948a98e18 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -188,7 +188,9 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo logger = nullptr; } - MainWindow w(logger, parser); + MainWindow w(logger, parser); + + w.show(); if (parser.getListDevices()) { @@ -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(); } diff --git a/plugins/channelrx/demoddatv/leansdr/dvbs2.h b/plugins/channelrx/demoddatv/leansdr/dvbs2.h index ee4b59830..c4843b7ea 100644 --- a/plugins/channelrx/demoddatv/leansdr/dvbs2.h +++ b/plugins/channelrx/demoddatv/leansdr/dvbs2.h @@ -72,6 +72,8 @@ typedef SSIZE_T ssize_t; #include "ldpctool/algorithms.h" #include "ldpctool/ldpcworker.h" +#include + namespace leansdr { @@ -459,7 +461,7 @@ struct s2_frame_transmitter : runnable ) { (void)mcinfo; - + std::complex *pout0 = pout; // For sanity check // PLHEADER: SOF AND PLSCODE // EN 302 307-1 section 5.5.2 PL signalling @@ -2588,7 +2590,7 @@ struct s2_deinterleaver : runnable hard_sb accs[/*bps*/], int nacc) { (void)nacc; - + if (MSB_FIRST) { for (int b = 0; b < BPS; ++b) { diff --git a/sdrbase/channel/channelwebapiutils.cpp b/sdrbase/channel/channelwebapiutils.cpp index 73743a354..a5d49cee5 100644 --- a/sdrbase/channel/channelwebapiutils.cpp +++ b/sdrbase/channel/channelwebapiutils.cpp @@ -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(); - - QString errorMessage; - if (200 != m_device->getSampleSource()->webapiSettingsPutPatch(false, m_settingsKeys, *m_response, errorMessage)) { - qDebug() << "DeviceOpener::checkInitialised: webapiSettingsPutPatch failed: " << errorMessage; - } - - delete m_response; - delete this; + // 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; } diff --git a/sdrbase/channel/channelwebapiutils.h b/sdrbase/channel/channelwebapiutils.h index d22773aa5..c2dd35f2a 100644 --- a/sdrbase/channel/channelwebapiutils.h +++ b/sdrbase/channel/channelwebapiutils.h @@ -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); }; diff --git a/sdrbase/remotetcpsinkstarter.cpp b/sdrbase/remotetcpsinkstarter.cpp index df92c4965..71d3c0e8c 100644 --- a/sdrbase/remotetcpsinkstarter.cpp +++ b/sdrbase/remotetcpsinkstarter.cpp @@ -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); diff --git a/sdrbase/remotetcpsinkstarter.h b/sdrbase/remotetcpsinkstarter.h index cae1e73b2..dc30dd27a 100644 --- a/sdrbase/remotetcpsinkstarter.h +++ b/sdrbase/remotetcpsinkstarter.h @@ -24,12 +24,34 @@ #include "mainparser.h" #include "export.h" -class SDRBASE_API RemoteTCPSinkStarter { +#include + +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 */ diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index ec4c3b97b..fedeb303c 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -105,6 +105,7 @@ #include "util/android.h" #endif +#include "remotetcpsinkstarter.h" #include "mainwindow.h" #include